遺傳算法是一種通用的最優化方法,具體原理可以看:遺傳算法詳解與實驗。下面記錄在Matlab中如何使用遺傳算法來做優化。
用法
調用方式如下:
1 x = ga(fun,nvars) 2 x = ga(fun,nvars,A,b) 3 x = ga(fun,nvars,A,b,Aeq,beq) 4 x = ga(fun,nvars,A,b,Aeq,beq,lb,ub) 5 x = ga(fun,nvars,A,b,Aeq,beq,lb,ub,nonlcon) 6 x = ga(fun,nvars,A,b,Aeq,beq,lb,ub,nonlcon,options) 7 x = ga(fun,nvars,A,b,[],[],lb,ub,nonlcon,IntCon) 8 x = ga(fun,nvars,A,b,[],[],lb,ub,nonlcon,IntCon,options) 9 x = ga(problem) 10 [x,fval] = ga(___) 11 [x,fval,exitflag,output] = ga(___) 12 [x,fval,exitflag,output,population,scores] = ga(___)
參數解釋
fun: 要執行最優化的函數,用於輸入待優化變量$x$。只能包含一個參數,可以是單個標量,也可以是向量。輸出一個標量。
nvars: 最優化函數傳入向量的元素數量。
A, b: 線性不等式約束的系數。即待優化變量$x$要滿足$A\cdot x \le b$。
Aeq, beq: 線性等式約束的系數。即待優化變量$x$要滿足$Aeq\cdot x = beq$。
lb, ub: 傳入向量的取值范圍。即待優化變量$x$要滿足$lb\le x\le ub$。
nonlcon: 定義非線性不等式約束和等式約束的函數。該函數只能包含一個參數用於接受待優化變量$x$,然后輸出不等式約束值$C(x)$和等式約束值$Ceq(x)$。約束$x$滿足$C(x)\le 0$和$Ceq(x)=0$。
IntCon: 限制待優化參數為整數,傳入需要限制為整數的待優化參數的位置。如對於3維變量$x$,設置IntCon為$[1,3]$表示第一和第三維的元素被限制為整數。
options: 遺傳算法的設置,設置初始化、迭代次數、種群大小等。具體請看鏈接。
[]: 對於不想使用的約束,可以用中括號[]省略。
傳出參數
x: 最優化后的變量。
fval: $x$對應的函數值。
exitflag: 遺傳算法結束標志,一個整數。分別解釋如下:
output: 遺傳算法的優化過程信息。
population: 遺傳迭代最后的種群。數組每行表示一個函數變量。
scores: 最后種群的個體值。也就是數組中各個變量的函數值。
例子
首先定義待優化函數:
1 function outp = func(varargin) 2 narginchk(1,2); 3 if nargin == 1 4 x = varargin{1}(1); 5 y = varargin{1}(2); 6 elseif nargin == 2 7 x = varargin{1}; 8 y = varargin{2}; 9 end 10 outp = 2*exp((-(x+3).^2-(y-3).^2)/10) + 1.2*exp((-(x-3).^2-(y+3).^2)/10) + exp(-cos(3*x)-sin(3*y)); 11 outp = -outp; 12 end
然后是該函數的可視化和優化:
1 %% 函數可視化 2 x = linspace(-5,0,500); 3 y = linspace(0,5,500); 4 [X, Y] = meshgrid(x, y); 5 6 Z = func(X, Y); 7 mesh (X,Y,Z); 8 9 %% 優化 10 [x, f] = ga(@func, 2);
通過可視化可以看到最小值大概在$(-3.14, 3.66)$附近:
優化結果也是如此: