一维搜索算法之黄金分割法

  • 1、概述
  • 2、黄金分割法
  • 3、修改后的黄金分割算法
  • 4、编程实现修改后的黄金分割算法

1、概述

  黄金分割法是一种区间收缩方法。

  所谓区间收缩方法,指的是将含有最优解的区间逐步缩小,直至区间长度为零的方法。比如,为求函数f(x)在区间[a,b]上的最小值点,可在该区间中任取两点x1、x2x_1、x_2x1​、x2​,通过比较函数f(x)在这两点的函数值或者导数值等,来决定去掉一部分区间[a,x1x_1x1​]或者[x2x_2x2​,b],从而使搜索区间长度变小,如此迭代,直至区间收缩为一点为止,或区间长度小于某给定的精度为止。

  对于区间[a,b]上的单峰函数f(x),可以在其中任意选取两点x1、x2x_1、x_2x1​、x2​,通过比较这两点的函数值,就可以将搜索区间缩小。比如说,如果f(x1x_1x1​)<f(x2x_2x2​),则选取[a1,b1a_1,b_1a1​,b1​]=[a,x2x_2x2​],如果f(x1x_1x1​)> f(x2x_2x2​),则选取[a1,b1a_1,b_1a1​,b1​]=[x1x_1x1​,b],如果f(x1x_1x1​)=f(x2x_2x2​ ),则选取[a1,b1a_1,b_1a1​,b1​]=[x1,x2x_1,x_2x1​,x2​],这样就得到f(x)的更小的搜索区间[a1,b1a_1,b_1a1​,b1​],然后根据这一方法再进行划分,得到一系列搜索区间满足

  于是对事先给定的某个精度ε\varepsilonε,当bk−ak<εb_k-a_k<\varepsilonbk​−ak​<ε时,可以将f(x)的最小值点近似地取为x∗=ak+bk2x^*=\frac{a_k+b_k}{2}x∗=2ak​+bk​​

  单峰函数与搜索区间的定义如下:


如何选取x1和x2才能使得算法的效率更高?
这里推导过程不在详细讨论,直接给出满足对称取点、等比收缩和单点计算三个原则的分点。
{x1=a+0.382(b−a)x2=a+0.618(b−a)\left\{\begin{matrix} x_1=a+0.382(b-a) \\ x_2=a+0.618(b-a) \end{matrix}\right.{x1​=a+0.382(b−a)x2​=a+0.618(b−a)​
或者
{x1=a+0.382(b−a)x2=a+b−x1\left\{\begin{matrix} x_1=a+0.382(b-a) \\ x_2=a+b-x_1 \end{matrix}\right.{x1​=a+0.382(b−a)x2​=a+b−x1​​

2、黄金分割法

  算法描述如下:

  这个算法非常理想,整个迭代过程中。除最初计算分点时使用过一次乘法外,后边的分点全部都由加减法完成,并且每次迭代只需计算一个分点的函数值。但是,在实际应用中,该方法存在一定的缺陷。这种缺陷主要来源于无理数−1+52\frac{-1+\sqrt{5}}{2}2−1+5​​的取值。这里我们只取了小数点后三位数。因而有一定误差,所以在迭代过程中,经过多次累计,误差就会很大,从而导致最终选取的两点并不一定是我们所期望的那两点,事实上,常常发生x2小于x1的情形。
  为避免这种情况的出现,我们也可以通过将无理数−1+52\frac{-1+\sqrt{5}}{2}2−1+5​​小数点后面的位数提高来避免算法的这一缺陷。不过这样做的效果未必很好。因为我们不知道在算法中到底要经过多少次迭代,当迭代次数很大时,这种做法依然是不能奏效的。因此,我们在程序中每次计算分点时不得不根据算法原理,使用一次乘法,即第二个分点不用加减法产生,而直接用乘法计算得出。由此即可避免累计误差所带来的缺陷。我们仍假设f(x)是区间[a,b]上的单峰函数。修改后的黄金分割法的计算框图如下图所示。

3、修改后的黄金分割算法

修改后的黄金分割算法如下:

4、编程实现修改后的黄金分割算法

用黄金分割法求函数f(x)=x3−12x−11f(x)=x^3-12x-11f(x)=x3−12x−11在区间[0,10][0,10][0,10]上的最小值点,取ε=0.01\varepsilon=0.01ε=0.01。

import java.math.BigDecimal;/*** 黄金分割法测试*/
public class GoldenCut {public static final BigDecimal C=new BigDecimal("0.01");public static  BigDecimal end=null;/***x^3-12x-11* @param x 输入参数x* @return x^3-12x-11*/public static BigDecimal ComputeFx(BigDecimal x){return x.pow(3).subtract(new BigDecimal("12").multiply(x)).subtract(new BigDecimal("11")).setScale(10,BigDecimal.ROUND_HALF_EVEN);}/*** a+0.382*(b-a)* @param a* @param b* @return a+0.382*(b-a)*/public static BigDecimal Compute382(BigDecimal a,BigDecimal b){return a.add(new BigDecimal("0.382").multiply(b.subtract(a))).setScale(10,BigDecimal.ROUND_HALF_EVEN);}/*** a+0.618(b-a)* @param a* @param b* @return*/public static BigDecimal Compute618(BigDecimal a,BigDecimal b){return a.add(new BigDecimal("0.618").multiply(b.subtract(a))).setScale(10,BigDecimal.ROUND_HALF_EVEN);}/*** a+b-x1* @param a* @param b* @param x1* @return*/public static BigDecimal Subtractabx1(BigDecimal a,BigDecimal b,BigDecimal x1){return a.add(b).subtract(x1).setScale(10,BigDecimal.ROUND_HALF_EVEN);}//判断是否满足精度 b-a<C?public static boolean OK(BigDecimal a,BigDecimal b){return b.subtract(a).compareTo(C) < 0;}//输出最优解public static BigDecimal Success(BigDecimal a, BigDecimal b){return (a.add(b)).divide(new BigDecimal("2")).setScale(10,BigDecimal.ROUND_HALF_EVEN);}//修改后的黄金分割法public static void goldenTest1(BigDecimal a,BigDecimal b){System.out.println("初始化");BigDecimal x1=Compute382(a,b);BigDecimal x2=Subtractabx1(a,b,x1);BigDecimal f1=ComputeFx(x1);BigDecimal f2=ComputeFx(x2);System.out.println("x1="+x1);System.out.println("x2="+x2);System.out.println("f1="+f1);System.out.println("f2="+f2);System.out.println("迭代区间如下:");int count=0;    //迭代次数while(!OK(a,b)){//只要不满足精度就一直迭代System.out.println("["+a+"\t,\t"+b+"]");count++;    //迭代次数+1if(f1.compareTo(f2)==1){//f1>f2a=x1;if(OK(a,b)){     //精度判断end = Success(a, b);break;}else{f1=f2;x1=x2;x2=Compute618(a,b);f2=ComputeFx(x2);}}else{b=x2;if(OK(a,b)){end = Success(a, b);break;}else{f2=f1;x2=x1;x1=Compute382(a,b);f1=ComputeFx(x1);}}}System.out.println("迭代结束,迭代次数"+count);}public static void main(String[] args) {BigDecimal a=new BigDecimal("0");BigDecimal b=new BigDecimal("10");goldenTest1(a,b);System.out.println("最优解为x*="+end);System.out.println("f(x*)="+ComputeFx(end));}
}

由运行结果可以看到,迭代次数15次,最优解为x∗=2.0009942948,f(x∗)=−26.9999940673x^*=2.0009942948,f(x^*)=-26.9999940673x∗=2.0009942948,f(x∗)=−26.9999940673。迭代区间如下:

可以证明,黄金分割法是线性收敛的。

黄金分割法(一维搜索算法)相关推荐

  1. 一维搜索算法介绍及其实现

    一维搜索算法介绍及其实现 当进行优化算法实现时.一般都要进行一系列如下格式的迭代运算 x(k+1) = x(k) + a(k) *s(k),其中s(k)是变量变化的方向,而a(k)可以确定变量变化的大 ...

  2. 利用matlab实现一维搜索算法

    通过五种方法实现全局极小值点的求解.其中,"成功-失败法"是试探法:区间收缩法,包括二分法.0.618法:函数逼近法,包括Newton法.二次插值法. 1."成功-失败& ...

  3. matlab一维搜索方法程序,matlab一维搜索法

    工程优化设计中的数学方法硕士研究生课程 理学院数学系:穆学文 Tel:88207669 E-mail:mxw1334@ 第三章 常用的一维搜索方法一元函数求极小及线性搜索均为一维搜索.常用于求: mi ...

  4. 基于OMPAL138+FPGA的三相电能质量分析仪设计

    随着我国经济的快速发展,电力资源已经成为人民生活.社会生产的重要能源.由于各种各样的用电设备日益增多,使得实际电网中存在很多不平衡和非线性的冲击性负载,导致电网出现供电电压偏差.频率偏差.谐波.间谐波 ...

  5. matlab优化工具箱介绍

    在生活和工作中,人们对于同一个问题往往会提出多个解决方案,并通过各方面的论证从中提取最佳方案.最优化方法就是专门研究如何从多个方案中科学合理地提取出最佳方案的科学.由于优化问题无所不在,目前最优化方法 ...

  6. 最优化方法matlab实现

    优化问题测试函数: http://www-optima.amp.i.kyoto-u.ac.jp/member/student/hedar/Hedar_files/TestGO.htm 9.1  概   ...

  7. 规划问题—最优化方法的Matlab实现

    优化问题测试函数: http://www-optima.amp.i.kyoto-u.ac.jp/member/student/hedar/Hedar_files/TestGO.htm 9.1  概   ...

  8. 最优化方法的Matlab实现

    转自:http://blog.csdn.net/luckydongbin/article/details/1497391 现在看一段 摄像机标定的程序里面涉及到最优化求解方程的函数,从网上找到了下面的 ...

  9. 数学知识-- 信赖域(Trust Region)算法是怎么一回事

    信赖域(Trust Region)算法是怎么一回事 转载自: https://www.codelast.com/原创信赖域trust-region算法是怎么一回事/ 如果你关心最优化(Optimiza ...

  10. Matlab优化函数中options选项的修改

    关于非线性优化fminbnd函数的说明(仅供新手参考) 初学matlab优化,迭代中止后,经常一头雾水.参看帮助后仍似懂非懂.下面关于fminbnd函数的说明(也可作为fmincon函数的参考)对于新 ...

最新文章

  1. ListView style
  2. 即将开源 | 2亿用户背后的Flutter应用框架Fish Redux
  3. Makefile中打印变量
  4. mysql5.6配置semi_sync
  5. Open ID Connect(OIDC)在 ASP.NET Core中的应用
  6. 2.3 快速搭建你的第一个系统,并进行迭代-深度学习第三课《结构化机器学习项目》-Stanford吴恩达教授
  7. LEMP构建高性能WEB服务器(第三版)
  8. python bosonnlp_BosonNLP分词技术解密
  9. 阿里巴巴与清华大学成立联合实验室,探索下一代人机自然交互
  10. C语言程序读写文件(文件内存一个十进制数,每读一次数值加一)
  11. Linux系统日志及日志分析
  12. Flink 最佳学习实践 | 从 0 到 1 学会 Apache Flink
  13. VS2013 异常处理
  14. css - 给图片添加蒙版
  15. CUDA2.1-原理之索引与warp
  16. 深度剖析“GCC编译器编译过程”
  17. json_encode
  18. day01_启动程序装载器 IPL
  19. Qt公有槽和私有槽的区别
  20. 【离散数学】陪集精讲

热门文章

  1. java 全双工串口,Java实现全双工串口通信
  2. 第一章,用行列式解线性方程组,02-二阶与三阶行列式
  3. nRF52283开发板 基于ble_peripheral\ble_app_blinky demo添加新的私有服务
  4. 什么是tomcat?tomcat是干什么用的?
  5. 全球及中国紧急警报系统EAS行业竞争格局及市场前景预测分析报告2022-2028年
  6. mysql myd文件过大_Mysql数据文件大小超过4G了如何缩小优化
  7. AUTOCAD——成组命令
  8. 计算机绘画社团活动教案,电脑绘画社团教案
  9. Hibernate类的继承使用joined-class实现
  10. Java 11中文版 API参考文档(收藏)