最優化第二講——一維搜索法(斐波那契法和java實現)

先看一下斐波那契數列

這個很容易理解,就是當前的值等於前兩個值的和

斐波那契法的遞歸結構如下


步驟一:我們首先要知道需要精確到的區間長度,例如要在[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.     }  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章