1. 程式人生 > >凸優化理論——無約束最優化方法 + Lagrange multipliers + KKT conditions

凸優化理論——無約束最優化方法 + Lagrange multipliers + KKT conditions

蠻久前學過了凸優化理論,今天要用到重溫了一下。
只是mark一下優秀的部落格~

  • 梯度:方向與等值面垂直,並且指向函式值提升的方向。

  • 正定二次型函式

    n 階實對稱矩陣 Q,對於任意的非0向量 X,如果有 XTQX>0,則稱 Q 是正定矩陣。
    對稱矩陣 Q 為正定的充要條件是:Q 的特徵值全為正。
    二次函式:

    f(x)=12XTQX+bTX+c
    Q是正定的,則稱f(X)為正定二次函式。
  • 二次收斂:指一個演算法用於具有正定二次型函式時,在有限步可達到它的極小點。二次收斂與二階收斂沒有盡然聯絡,更不是一回事,二次收斂往往具有超線性以上的收斂性。一階收斂不一定是線性收斂。

黃金分割法

黃金分割法適用於任何單峰函式求極小值問題。

求函式在[a, b]上的極小點,我們在[a, b]內取兩點c,d,使得a<c<d<b。並且有

caba=bdba=r(1)
  1. 如果f(c)<f(d),則最小點出現在[a, d]上,因此[a, d]成為下一次的搜尋區間。
  2. 如果f(c)>f(d),則[c,b]成為下一次的搜尋區間。

假如確定了[a, d]是新的搜尋區間,我們並不希望在[a, d]上重新找兩個新的點使之滿足(1)式,而是利用已經抗找到有c點,再找一個e點,使滿足:

eada=dcda=r(2)
可以解得r=
0.382
,而黃金分割點是0.618。

練習:求函式f(x)=x210x+36在[1, 10]上的極小值。

#include<stdio.h> 
#include<math.h> 
#include<limits.h> 
double func(double x){
    return x*x-10*x+36; 
} 
void main(){
    double zeta=0.001; 
    double a=1.0,b=10.0; 
    double t1=a-1; 
    double t2=b+1; 
    double v1=0.0; 
    double
v2=0.0; double min_value=INT_MAX; int iteration=0; while(++iteration){ if(t1==a-1){ t1=a+0.382*(b-a); v1=func(t1); } if(t2==b+1){ t2=a+0.618*(b-a); v2=func(t2); } if(v1<v2){ min_value=v1; b=t2; t2=t1; v2=v1; t1=a-1; } else{ min_value=v2; a=t1; t1=t2; v1=v2; t2=b+1; } if(fabs(b-a)<zeta) break; printf("當前極小值%f\n",min_value); } printf("迭代次數%d\n",iteration); printf("極小值%f\n",min_value); }

最速下降法

利用梯度資訊不斷優化目標函式

泰勒級數告訴我們:

f(x+Δx)=f(x)+f(x)Δx+f(2)(x)2!Δx2+f(3)(x)3!Δx3+(3)
其中Δx可正可負,但必須充分接近於0。

X⃗ 沿D⃗ 方向移動步長α後,變為X⃗ +aD⃗ 。由泰勒展開式:

f(X⃗ +αD⃗ )=f(X⃗ )+αf(D⃗ )
目標函式:maxf(X⃗ )f(X⃗ +αD⃗ )
α確定的情況下,即最小化:
minf(X⃗ )D⃗ 
向量的內積何時最小?當然是兩向量方向相反時。所以X⃗ 移動的方向應該和梯度的方向相反。

接下來的問題是步長α應該怎麼定才能使迭代的次數最少?

f(X)具有二階連續偏導,由泰勒展開式可得: