目標函數存在累加的非線性優化問題的求解思路zzzzzzzzzzzzzzzzzzzz(1)


馬上要畢業了,最近正在弄畢業論文(快馬加編),這幾天被一個優化問題卡住了,花了點時間對matlab和lingo的對非線性規划問題的求解方法進行了一個總結,適合小白或者懂一點點相關知識的朋友,希望能幫上有需要的朋友,要是哪里有問題歡迎交流,但是不要罵我,我玻璃心。

首先簡單說一下線性規划問題的形式,下面是矩陣形式:

 

一般就是上面這種形式,一個優化問題中可能存在不等式約束、等式約束、變量范圍約束和變量類型約束。先來個簡單的實例:

 

 

如果用matlab求解,要先把它轉化成標准型(標准型為求極小值,約束條件中常數項在右側):

 

 

來看matlab的求解方法:

Matlab的非線性約束最優化問題的求解器是fmincon,如果要解線性問題或者無約束問題也有類似的求解器,調用方式都差不多。

求解器的具體形式是: [x,fval]=fmincon(fun,x0,A,b,Aeq,beq,lb,ub)

這里的fun就是優化目標,x0是初始解,A是不等式約束的系數項,b是不等式約束對應的常數項,Aeq,beq對應等式約束,lb與xb就是范圍約束。Fun,x0,A,b為必選,其他的為可選。x是求解器得到的解,fval是求解器得到的最優值。

由於我們的約束中只存在不等式約束,所以只需要設置fun,x0,A,b。

fun就是我們的優化目標,這里可以利用matlab的匿名函數(優化目標簡單的時候就可以用匿名函數),具體形式是:

  fun=@(x) -x(1)*x(2)*x(3)

這里的@是用於聲明變量,@(x)就是表示我們的自變量為x。

之后就是A與b:

  A = [1,2,3;-1,-2,-3]

  b = [72;0]

A與b的每一行要對應,用;來分割行

x0是初始解,需要我們自己設置,這個理論上隨便設置,這里設置為:

  x0 = [5,5,5]

在優化問題中可能存在多個解,我們可以試着多次改變x0,看看能不能得到其他解。

下面就是整體代碼:

  fun=@(x) -x(1)*x(2)*x(3);

  A = [1,2,3;-1,-2,-3];

  b = [72;0];

  x0 = [5,5,5];

  [x,fval]=fmincon(fun,x0,A,b);

運行之后在matlab的變量欄就能看到求解結果了。

 

但其實很多時候,我們的目標函數不可能這么簡單,比如我們的優化目標中存在變量累加的情況,或者約束條件中存在奇怪的形式,如我要解的東西就存在下面形式:

 

這看着還可以,但寫起來很惡心的,特別是這種累加形式,理論上我們可以把累加拆開,然后采用匿名函數的形式,一個一個寫(我一開始就這么干的),結果我的目標函數就變成了:

 

 

 

這只是一部分,我還沒寫完,寫到一半發現好丟人啊,這也太沒水平了。

感覺這種累積形式的函數應該能用for循環來寫,但由於之前沒怎么寫過也不太明白。后面百度搜了一下也沒搜到相關內容,可能是我沒學好信息檢索這門課。之后看了下書,大概知道怎么操作了。

這里把我的目標函數改改,舉個栗子來做說明for循環怎么用於目標函數的定義。

 

 

后面這項的Xavg是指x的平均值,這一項類似於一個平方差。

首先新建一個matlab腳本,我們把優化目標寫成一個函數,第一行寫上:

function f= qiujie(x) //我的腳本名稱就是qiujie,這個可以自己修改

分析一下這個目標項,后面那個有點復雜,需要求平均,因為for循環是從x1一個一個加到x50的,所以一開始沒有這個信息,因此我們可以用兩個循環來做,第一個循環就是優化目標的第一項,同時記錄x1...x50,根據記錄的x1...x50,第二個循環就可以加上第二項了。

這里的c,t都是常數項,所以我們提前設置好,比如

  c = [1,2,3,...,50]

  t = [1,2,3...50]

先定義一個f,再定義一個temp用於存儲x1...x50的信息

  f = 0;

  temp = 0;//temp用來記錄

接下來就可以用for循環來寫了,

  for k= 1:50

         f = f+(x(k)-c(k))*x(k)^t(k);//第一項

         temp = temp+x(k);

  end

現在求一下平均值,並加上后面那項

  temp = temp/50

  for k = 1:50

         f = f -(x(k)-temp)^2;//第二項

  end

這樣我們的優化目標項就定義好了,之后我們把約束項定義好,就可以進行求解了,形式為:

  [x,fval]=fmincon(@qiujie,x0,A,b);

上面就是整個求解過程的思路,具體情況需要根據自己的需求來寫。

不過這樣看其實也還好,但很多時候約束項才是讓人頭疼的,比如我們的系數矩陣A,當變量比較多時,系數矩陣會很大,如果有規律,我們可以利用for循環來寫,但如果系數矩陣沒有規律,通常需要我們人工輸入,目前我還不知道在matlab中怎么能很好解決這個問題,有知道的可以v我一下。(我覺得一般應該是有規律的)

Lingo求解非線性約束優化問題:

暫時還沒學完,學完再寫。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM