最优化第二讲——一维搜索法(斐波那契法和java实现)

来源:互联网 发布:sql server 下载地址 编辑:程序博客网 时间:2024/06/04 18:01

先看一下斐波那契数列

这个很容易理解,就是当前的值等于前两个值的和

斐波那契法的递归结构如下


步骤一:我们首先要知道需要精确到的区间长度,例如要在[1, 10]之间搜索极小值点,希望精确到0.5之间,那么也就是我最后要求得的Ln的长度要小于等于0.5。所以这个时候就能知道经过几轮计算可以达到这个精度,斐波那契数列指的是:Fn=F(n-1)+F(n-2)。上图可知Ln与Fn是有关系的,所以可以求得满足Ln小于等于0.5的Fn,也就知道了可以迭代几轮。

步骤二:求出L2,L2=L1*F(n-1)/F(n),这个式子可以由上图得到,就是要确定最开始的t1、t2点,然后比较t1、t2点对应的函数值得大小,缩小区间,缩小区间的方法跟通用方法一致,如果t1的函数值f1大于t2的函数值f2,那么区间缩小为[t1, 10],否则区间缩小为[1, t2]

步骤三:如果区间缩小为[t1, 10],这个时候t1=t2,而t2的值等于t1在这个区间内的对称值。其实我们可以看到只有第一步需要计算两个点的函数值,其他步都只要计算一个点的函数值就行,因为另外一个点的函数值由上一步遗留下来

代码实现如下

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. private static void fibonacci(float start, float end, float eps) {  
  2.           
  3.         float Fn_1, Fn;  
  4.         int n;  
  5.         float L1 = end - start;  
  6.         float Ln = eps;  
  7.         n = 2;  
  8.         Fn = F(n);  
  9.         //求要经过几轮区间长度才可以小于eps  
  10.         while(Fn <= L1 / Ln) {  
  11.             n ++;  
  12.             Fn = F(n);  
  13.         }  
  14.         Fn_1 = F(n - 1);  
  15.           
  16.         float t1, t2, f1, f2;  
  17.         float a = Math.min(start, end);  
  18.         float b = Math.max(start, end);  
  19.           
  20.         t1 = b - (b - a) * Fn_1 / Fn;  
  21.         t2 = a + b - t1;  
  22.         f1 = fun(t1);  
  23.         f2 = fun(t2);  
  24.           
  25.         while(b - a >= Ln) {  
  26.             if(f2 < f1) {  
  27.                 a = t1;  
  28.                 t1 = t2;  
  29.                 t2 = a + b - t1;  
  30.                 f1 = f2;  
  31.                 f2 = fun(t2);  
  32.             } else {  
  33.                 b = t2;  
  34.                 t2 = t1;  
  35.                 t1 = a + b - t2;  
  36.                 f2 = f1;  
  37.                 f1 = fun(t1);  
  38.             }  
  39.         }  
  40.           
  41.         System.out.println((b + a) / 2);  
  42.     }  
  43.       
  44.     private static float F(int n) {  
  45.           
  46.         if(n == 0 || n == 1return 1;  
  47.         return F(n - 1) + F(n - 2);  
  48.     }  
  49.       
  50.     private static float fun(float x) {  
  51.         return (float) Math.sin(x);  
  52.     }  

0 0