1. 程式人生 > >MATLAB(1)基於遺傳演算法解決最優化問題及相應的MATLAB遺傳工具箱使用

MATLAB(1)基於遺傳演算法解決最優化問題及相應的MATLAB遺傳工具箱使用

     對於取最小值的最優化問題,遺傳演算法借鑑生物遺傳現象使具有一定數量的候選解的種群向更好的解進化,該方法是通過種群進化,使得適應度函式代入估計引數後達到最值來得到最優解。借鑑生物種群的進化,遺傳演算法先隨機產生一組初始解,作為初始種群,以數值解為例,這些解都是通過二進位制程式碼儲存在計算機中,類似於染色體,於是可以進行生物上的交叉、變異、遺傳等。通過對第一代個體選擇,保留一些個體並讓上一代解“組合”、“變異”、“遺傳”,由此產生下一代的解。而每一代中都有個體被淘汰,淘汰的指標就是適應度函式。生物法則“適者生存”,通過目標來建立適應度函式,在每一代中挑選適應度函式值大的個體留下來,對比目標的容許誤差,達到目標容許誤差,或達到預先設定的遺傳代數,則停止計算,返回最優解。
      遺傳演算法的一個很大的特點就是能跳出極值。對於一些多峰的問題,一些演算法極其容易陷入區域性最優解而得不到全域性最優解。而歸功於遺傳演算法中的變異交叉步驟,遺傳演算法在每一代中都能不受上一代最優解控制的產生新解,由此為跳出區域性最優解提供了途徑。      此外,還有一點想要說明的是,筆者在閱讀一些相關資料時,發現準則是適應度函式是取最大值,而實際應用中是讓適應度函式取最小值,至少在MATLAB中是這樣的。我個人還是比較認可第一種的,因為“適者生存”嘛,自然是適應度高的解應當生存下來。對於第二種,我猜想可能是在實際應用中,為了方便,不區分適應度函式和目標函式,二者混用,確實表達的是一個意思。所幸,這一點在運用時並不會產生什麼麻煩。
     起初接觸遺傳演算法時,想到要自己設定種群規模,規定交叉變異遺傳方式等等就頗為頭疼,幸好後面發現MATLAB有自帶的遺傳工具箱,下面我就舉個簡單的例子來演示一下如何使用MATLAB的遺傳工具箱。      對於求解方程組:{x-y-3=0;  3x-8y-14=0}      為近似求解上述方程組,令 f1=x-y-3; f2=3x-8y-14; f=f1^2+f2^2; 則問題轉換為求解使得f取最小值的x,y變數值,f即可當做適應度函式。使用MATLAB2015a的遺傳工具箱實現求解。      首先根據對問題的轉換,編寫m檔案如下:         然後在命令視窗輸入:  >>optimtool('ga')   通過此命令來開啟遺傳工具箱,初始介面如下:  
  可以看到工具箱主要分為兩欄,左邊主要是求解的函式的基本資訊,右邊是對遺傳演算法中引數的設定。在此例中,我們在Fitness function中輸入控制代碼函式格式@ga1,又因為此例中變數的數目為2(x,y),所以在 number of variables中輸入2,而對於下面的Constrains(約束), 由於在此例中變數的取值範圍為整個實數域,因而沒有約束條件,該部分保持空白即可。
     對於右邊對遺傳演算法引數的設定,我一般都只是更改Population size(種群的規模), Generations(遺傳演算法執行的總代數,可以理解為遺傳到多少代時停止),Stall generations(停滯的代數,可以理解為當連續遺傳多少代後適應度函式的加權平均值變化小於Function tolerance時停止計算),Function tolerance(適應度函式值偏差),其他的我基本都是用預設設定,不做更改。當然,有時,也會根據實驗對其他引數進行除錯,如對精英數量,交叉比例等。在此例中,我們設定Population size 為100,Generations和Stall generations均為200,Function tolerance為1e-100. 同時在Plot functions中勾選best fitness 和best individual如下:
       然後點選偏左下方的Start按鈕,執行,最後的結果將顯示在左下方的final point中。一次執行的結果如下:


      由於此題的方程組非常簡單,筆算可得解為x=2,y=-1, 對比遺傳演算法的結果可以知道解是非常逼近真實值的,而且智慧演算法的時間複雜度低,執行效率高。當然在使用遺傳演算法時,由於演算法對初始種群的選取是隨機的,因而每次計算結果可能不同,讀者必須執行多次,分析結果,將離群點排除後取均值是個不錯的選擇。