<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ## 無約束最優化方法 最優化(Optimization)是工程技術、經濟管理、 科學研究、社會生活中經常遇到的問題, 如:結構設計,資源分配,生產計劃,運輸方案等等。 最優化: 在一定條件下,尋求使目標最大(小)的決策解決優化問題的手段 ? 經驗積累,主觀判斷 ? 作試驗,比優劣 ? 建立數學模型,求解最優策略 ### 優化問題的數學模型 無約束優化問題標準形式: 求n維決策變量x=[x1,x2,…,xn]T在可行域Ω中 使得目標函數f(x)→min,x?Ω?Rn ? ![這里寫圖片描述](https://box.kancloud.cn/2016-07-25_5795bdc2f0216.jpg "") **可行解**只滿足(2),**最優解**滿足(1)(2) **無約束優化**只有(1),**約束優化**需要(1)(2) ### 無約束優化的基本方法 ### 求解無約束優化的基本思路:[下山法](http://blog.csdn.net/u013007900/article/details/43525733) #### 基本思想: 和爬山法基本思想一樣,在Rn中某一點,確定一個**搜索放向**然后沿著該方向的**移動步長**,得到使目標函數下降的最新點。 #### 迭代步驟: Step 1 初始化:初始點x0,終止準則等 Step 2 迭代改進:方向dk,步長αk xk+1=xk+(αd)k?且?f(xk+1)<f(xk) Step 3 終止檢驗:得到近優解或k+1?k轉2> 選擇dk,αk使得f下降更快?利用不同的算法 ### 最速下降法(梯度法) 泰勒級數: ![](https://box.kancloud.cn/2016-07-25_5795bdc317591.png "") 其中Δx可正可負,但必須充分接近于0。 X沿D方向移動步長α后,變為X+αD。由泰勒展開式:![](https://box.kancloud.cn/2016-07-25_5795bdc32ec6e.png "") 目標函數:![](https://box.kancloud.cn/2016-07-25_5795bdc3439d9.png "") α確定的情況下即最小化:![](https://box.kancloud.cn/2016-07-25_5795bdc3547a3.png "") 向量的內積何時最小?當然是兩向量方向相反時。所以X移動的方向應該和梯度的方向相反。 **下降方向:**?fT(xk)dk<0 **最速下降方向:**dk=??f(xk)負梯度方向 **迭代改進形式:**xk+1=xk??f(xk) 算法特點:在初始狀態改進較快,在最優解附近改進緩慢。 求函數f(x1,x2)=x21+4x22在極小點,以初始點X0=(1,1)T。 ~~~ #include"matrix.h"//大家自己YY一個矩陣類吧 #include<iostream> #include<iomanip> #include<cmath> #include<limits> #include<cassert> using namespace std; const int SIZE=2; const double ZETA=0.001; inline double func(Matrix<double> &X){ assert(SIZE==X.getRows()); double x1=X.get(0,0); double x2=X.get(1,0); return x1*x1+4*x2*x2; } inline Matrix<double> gradient(Matrix<double> &X){ assert(SIZE==X.getRows()); double x1=X.get(0,0); double x2=X.get(1,0); Matrix<double> rect(SIZE,1); rect.put(0,0,2*x1); rect.put(1,0,8*x2); return rect; } inline Matrix<double> Hesse(Matrix<double> &X){ Matrix<double> rect(SIZE,SIZE); rect.put(0,0,2); rect.put(0,1,0); rect.put(1,0,0); rect.put(1,1,8); return rect; } int main(int agrc,char *argv[]){ Matrix<double> X(SIZE,1); X.put(0,0,1); X.put(1,0,1); int iteration=0; double value=func(X); double newValue=numeric_limits<double>::max(); while(++iteration){ Matrix<double> G=gradient(X); double factor=((G.getTranspose()*G).get(0,0))/((G.getTranspose()*Hesse(X)*G).get(0,0)); for(int i=0;i<G.getRows();++i) for(int j=0;j<G.getColumns();++j) G.put(i,j,G.get(i,j)*factor); Matrix<double> newX=X-G; //cout<<"X=["<<newX.get(0,0)<<","<<newX.get(1,0)<<"]"<<endl; newValue=func(newX); if(fabs(newValue-value)<ZETA) break; else{ X=newX; value=newValue; } //cout<<"本次迭代找到的極小值"<<value<<endl; } cout<<"迭代次數"<<iteration<<endl; cout<<"極小值"<<value<<endl; return 0; } ~~~ > 這份算法使用的是利用Hesse矩陣和泰勒公式計算最優步長 若f(X)具有二階連續偏導,由泰勒展開式可得: ![](https://box.kancloud.cn/2016-07-25_5795bdc368a0b.png "") H是f(X)的Hesse矩陣。 ![](https://box.kancloud.cn/2016-07-25_5795bdc37ab36.png "") 可得最優步長: ![](https://box.kancloud.cn/2016-07-25_5795bdc38d688.png "") g是f(X)的梯度矩陣。 此時: ![](https://box.kancloud.cn/2016-07-25_5795bdc39f52f.png "") 可見最速下降法中最優步長不僅與梯度有關,而且與Hesse矩陣有關。 ### 牛頓迭代法 將f(xk+1)在xk點作泰勒展開至二階項,用d替代dk,有 f(xk+1)=f(xk+d)=f(xk)+?fT(xk)d+12dT?2f(xk)d 求d使得f(xk+1)極小?右端對d的導數為0??f(xk)+?2f(xk)d=0 可得到> **牛頓方程**?2f(xk)d?=???f(xk) **牛頓方向**dk?=??(?2f(xk))?1?f(xk) **迭代格式**xk+1?=?xk?(?2f(xk))?1?f(xk) 其中?2f(xk)為[Hessen矩陣](http://baike.baidu.com/link?url=E2wdH1BhTKFos1JYd_NhHvkmGAyABsHJDIgSyygvzTuoAs41tvb4OGzzWThbUMwobdBAEPpS7nzia-GQUHHf7a) 可見x的搜索方向是?(?2f(xk))?1?f(xk),函數值在此方向上下降,就需要它與梯度方向相反,即??f(xk)(?2f(xk))?1?f(xk)<0,所以要求在每一個迭代點上Hessian矩陣必須是正定的。 算法特點: 牛頓法是二次收斂的,并且收斂階數是2。一般目標函數在最優點附近呈現為二次函數,于是可以想像最優點附近用牛頓迭代法收斂是比較快的。而在開始搜索的幾步,我們用梯度下降法收斂是比較快的。將兩個方法融合起來可以達到滿意的效果。 收斂快是牛頓迭代法最大的優點,但也有致命的缺點:Hessian矩陣及其逆的求解計算量大,更何況在某個迭代點Xk處Hessian矩陣的逆可能根本就不存在(即Hessian 矩陣奇異),這樣無法求得Xk+1。 求f(x1,x2)=(x1?2)4+(x1?2x2)2的極小點,初始點取X=(0,3)T ~~~ #include"matrix.h" #include<iostream> #include<iomanip> #include<cmath> #include<limits> #include<cassert> using namespace std; const int SIZE=2; const double ZETA=0.001; inline double func(Matrix<double> &X){ assert(SIZE==X.getRows()); double x1=X.get(0,0); double x2=X.get(1,0); return pow(x1-2,4)+pow(x1-2*x2,2); } inline Matrix<double> gradient(Matrix<double> &X){ assert(SIZE==X.getRows()); double x1=X.get(0,0); double x2=X.get(1,0); Matrix<double> rect(SIZE,1); rect.put(0,0,4*pow(x1-2,3)+2*(x1-2*x2)); rect.put(1,0,-4*(x1-2*x2)); return rect; } inline Matrix<double> Hesse(Matrix<double> &X){ Matrix<double> rect(SIZE,SIZE); double x1=X.get(0,0); double x2=X.get(1,0); rect.put(0,0,12*pow(x1-2,2)+2); rect.put(0,1,-4); rect.put(1,0,-4); rect.put(1,1,8); return rect; } int main(int agrc,char *argv[]){ Matrix<double> X(SIZE,1); X.put(0,0,0); X.put(1,0,3); int iteration=0; double value=func(X); double newValue=numeric_limits<double>::max(); while(++iteration){ Matrix<double> G=gradient(X); Matrix<double> H=Hesse(X); Matrix<double> newX=X-H.getInverse()*G; cout<<"X=["<<newX.get(0,0)<<","<<newX.get(1,0)<<"]"<<endl; newValue=func(newX); if(fabs(newValue-value)<ZETA) break; else{ X=newX; value=newValue; } cout<<"本次迭代找到的極小值"<<value<<endl; } cout<<"迭代次數"<<iteration<<endl; cout<<"極小值"<<value<<endl; return 0; } ~~~ ### 擬牛頓法 Hessian矩陣在擬牛頓法中是不計算的,擬牛頓法是構造與Hessian矩陣相似的正定矩陣,這個構造方法,使用了目標函數的梯度(一階導數)信息和兩個點的“位移”(Xk?Xk?1)來實現。 有人會說,是不是用Hessian矩陣的近似矩陣來代替Hessian矩陣,會導致求解效果變差呢?事實上,效果反而通常會變好。 擬牛頓法與牛頓法的迭代過程一樣,僅僅是各個Hessian矩陣的求解方法不一樣。 在遠離極小值點處,Hessian矩陣一般不能保證正定,使得目標函數值不降反升。而擬牛頓法可以使目標函數值沿下降方向走下去,并且到了最后,在極小值點附近,可使構造出來的矩陣與Hessian矩陣“很像”了,這樣,擬牛頓法也會具有牛頓法的二階收斂性。 對目標函數f(X)做二階泰勒展開: f(x)=f(xk+1)+(x?xk+1)T?f(xk+1)+12(x?xk+1)TG(xk+1)(x?xk+1) 其中?2f(xk)??G(xk+1) 上式兩邊對x求導: ?f(x)=?f(xk+1)+G(xk+1)(x?xk+1) 當x=xk的時候,有 G?1(xk+1)[?f(xk+1)??f(xk)]=xk+1?xk 這里我們用Hk表示在點xk處的Hessian矩陣的**逆矩陣** Hk+1[?fd(xk+1)??f(xk)]=xk+1?xk?......(5) (5)式就是**擬牛頓方程** 下面提供兩種擬牛頓法 ![這里寫圖片描述](https://box.kancloud.cn/2016-07-25_5795bdc3b5dd4.jpg "") ### 非線性最小二乘(Least Square)擬合 問題: 給定(ti,yi),i=1,…n, 擬合一個函數y=f(t,x), 其中x為待定的參數向量, f 對x非線性。 記誤差ri(x)=yi?f(ti,x)?????r(x)=(r1(x),…,rn(x))T 優化模型: minxR(x)=rT(x)r(x) 記r(x)的雅克比行列式為J(x)=(?ri?xj)n×m ?R=2J(x)Tr(x)?2R=2J(x)TJ(x)+2SS=∑ni=1ri(x)?2ri(x)?2ri(x)=(?2ri?xk?xl)n×m 牛頓法要計算Hessian矩陣,其中S計算量大 若f 對x線性, 則化為線性最小二乘擬合, 此時 S=0 特定算法考慮如何忽略或近似矩陣S #### Gauss-Newton算法(GN):忽略矩陣S ?R=2J(x)Tr(x)?2R=2J(x)TJ(x) 牛頓方程:?2f(xk)d=??f(xk) f用R代替,下降方向dk滿足 J(x)TJ(x)dk=?J(x)Tr(x) GN算法收斂性特點: S=∑ni=1ri(x) 收斂性依賴f對x的線性程度,即偏差r的大小(”小殘差問題“) #### LM算法: Levenbery (1944), Marquardt (1963) G-N算法修正 J(x)TJ(x)dk=?J(x)Tr(x) ? (J(x)TJ(x)+αkI)dk=?J(x)Tr(x) 其中αk>0為修正參數,防止JTJ出現病態。 LM算法特點 dk位于GN方向(αk很小)和負梯度方向(αk很大)之間 LM算法的另一種觀點 min∥r(xk)+J(xk)(x?xk)∥2 s.t.?????∥x?xk∥2≤hk????(?)置信域 其解為 (J(x)TJ(x)+αkI)dk=?J(x)Tr(x) 若GN方向滿足約束(*),αk=0,否則ak>0 置信域算法特點: 先確定最長步長hk,再確定方向dk
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看