如果你對遺傳算法感興趣或者正在做有關GA的研究,不妨關注博客右側專欄 → 智能計算-深入遺傳算法 ,一步一步深入算法,分享算法每一個流程模塊(如選擇策略,交叉機制等等)的眾多參考觀點。代碼和Demo咱從來不缺。
寫在之前
說明: 本文用一個實際的二進制編碼求解一元函數最值的代碼例子闡明基本遺傳算法的運行機理 。 本文會用Matlab代碼寫明關鍵之處的算子,源碼的下載 請帶好大挪移令和靈石進傳送陣
目標函數分析
目標函數如下:
max:F(x)=x+10sin(5x)+7cos(4x),x∈[0,10]m
a
x
:
F
(
x
)
=
x
+
10
s
i
n
(
5
x
)
+
7
c
o
s
(
4
x
)
,
x
∈
[
0
,
10
]
該函數圖形如下:
從圖像中很容易看出函數在x∈[0,10]x
∈
[
0
,
10
] 上的最值Fmax≈24.8F
m
a
x
≈
24.8 ,Fmin≈−12F
m
i
n
≈
−
12 ,並且在x≈3.2x
≈
3.2 附近,有一個局部極大值。
初步分析與算法流程
本文列在入門篇,所以求解函數選用最為簡單的一元函數,並且定義域無負值。而所采用的遺傳算法也采用最傳統的算法思想與最傳統的算子:二進制編碼,賭輪(輪盤賭)選擇算子,多基因交叉,多基因變異。
算法流程:
Created with Raphaël 2.1.2
開始
生成初始種群
計算適應度
選擇,交叉,變異
新種群
是否滿足停止准則?
End
yes
no
生成初始種群:編碼VS解碼
初始參數,種群的規模,也是個體的數量NP=80N
P
=
80 , 迭代次數G=100G
=
100 。
因為是一元函數,變量只有一個,所以采用二進制編碼,精度(個體基因位數)設置為L=20L
=
20 。也就是說,初始種群實際上就是一個隨機生成的由0和1組成的NP∗LN
P
∗
L 的二維矩陣 。MATLAB代碼如下:
f=randi([0,1],NP,L); %隨機獲得初始種群矩陣
這樣,每個個體都是由20位的0和1基因組成,我們知道,其實每個個體就是函數的一個變量,在進行求解適應度時,需要將該變量帶入函數運算,這時,就需要將二進制編碼的個體解碼成在定義域內的十進制,解碼的原理和對應法則大家可以看如下的MATLAB代碼:
for i=1:NP
U =f(i,:);
m=0;
for j=1:L
m=U(j)*2^(j-1)+m;
end
x(i)=Xx+m*(Xs-Xx)/(2^L-1); %x(i)為[0,10]內的實數
end
關於適應度函數
適應度函數是為了更好的編寫代碼,更好的參與選擇、交叉和變異算子而在目標函數的基礎上做的一系列改進,本文要求解的目標函數非常普通,而且本文求解的是最大值,即,個體的目標函數值越大,說明該個體越好,適應度就越好,所以就直接把目標函數當做適應度函數,本文提到的適應度函數就是目標函數。
需要提一下的是,源碼中對適應度值做了歸一化的處理。大家可不用理會 。
思考:若本文求的是最小值呢?目標函數能不能直接當適應度函數用?
回答: 不可以。我們所說的目標函數的概念是待優化的函數,而適應度函數是適應度的變化函數。如果求解目標函數的最小值,則目標函數值越小的,適應度越高,所以適應度函數的設計就應該考慮把目標函數做取反,或者取倒數操作 。
關於 適應度函數的設計我們放到深入遺傳算法系列時再說。
選擇策略
在遺傳算法中,選擇策略用的最多的就是輪盤賭選擇,也叫賭輪選擇或者適應度比例選擇法 。輪盤賭選擇的原理並不難理解,我們這里給出一個簡單的理解,詳細的探討將留在”深入遺傳算法系列“中 。
假設我們有4個個體個體:A 個體:B 個體:C 個體:D,其適應度、選擇概率、累計概率如下表所示 :
個體
適應度
選擇概率
累計概率
A
10
0.1
0.1
B
40
0.4
0.5
C
30
0.3
0.8
D
20
0.2
1
我們用累計概率畫出一個餅圖(賭博的輪盤):
畫好圖后,就開始選擇了。首先我們准備一個骰(tou)子,隨機拋入輪盤中,落入0.0~0.1區域就選中個體A,落入0.1~0.5區域就選中個體B,落入0.5~0.8區域就選中個體C,落入0.8~1.0區域就選中個體D。 一共拋種群規模NP次,選出NP個個體組成新的種群。
以上的思想就是輪盤賭的思想,其實還有另一個方式玩這個游戲,就是把骰子固定不動,我們轉NP次輪盤,骰子指向哪個區域,就選中對應區域的個體。貌似這種方式只是變換了一下參考系而已。
用代碼實現上述的思想,也就會有兩種方式,希望大家在看別的代碼實現的時候能夠搞清楚是哪兩種方式。下面是MATLAB代碼實現: (用的是輪盤轉,骰子不動的思維方式)
sum_Fit = sum(Fit) ;
fitvalue = Fit ./sum_Fit ; %選擇概率,將Fit的每個元素除以sum_Fit
fitvalue = cumsum(fitvalue) ; %累積概率
ms = sort (rand(NP,1)) ; %產生NP個0~1之間的隨機數,並且升序排序
fiti =1;
newi=1;
while newi<=NP %輪盤開始轉,一共轉NP次
if(ms(newi)
nf(newi,:) = f(fiti , :) ; % 把個體給新的種群
newi = newi + 1;
else
fiti=fiti +1;
end
end
交叉與變異機制
交叉,選出兩個個體,通過交叉概率Pc確定是否需要交叉,如果交叉,則兩個個體某些對應基因位上的基因進行交換即可。
變異,每個個體通過變異概率Pm確定是否需要變異,如果變異,則某些基因位取反即可。
附上交叉代碼:
for i = 1:2:NP % 從1到NP ,每隔兩個
p = rand ;
if p
q=randi([0,1],1,L);
for j =1:L
if q(j) == 1
temp=nf(i+1,j);
nf(i+1,j) = nf(i,j);
nf(i,j) = temp;
end
end
end
end
附上變異代碼:
i = 1;
while i<=round(NP*Pc) % 四舍五入
h=randi([1,NP],1,1) ; %隨機選取一個需要變異的染色體
for j = 1:round(L*Pc)
g = randi([1,20],1,1);%隨機選取需要變異的基因數
%g=rand;
nf(h,g) = ~ nf(h,g);
end
i=i+1;
end
精英策略的重要性
所謂的精英策略是指: 上一代最好的個體不經過選擇、交叉、變異,直接復制到下一代中。不要小看精英策略,實踐證明,經營策略是增強算法收斂的最主要,最強大的手段,是經過理論證實。如果算法中缺乏精英策略,會嚴重影響收斂速度。
MATLAB繪圖得出結果
什么 ?你還不會用MATLAB畫圖,太out了!趕緊帶好大挪移令進傳送陣-三個實例搞定MATLAB二維繪圖閉關修煉去吧,恕不遠送!!
首先,我們要清楚要繪制怎樣的結果圖。你可以繪制一幅種群平均適應度隨迭代次數的變化,也可以繪制一幅當前代種群的最大適應度,而本次我們繪制的是一幅迄今為止種群中最大適應度隨迭代次數的變化,如下圖:
至於是怎么繪制的 ?其實很簡單,定義一個G(代數)維數組,盛放每一代中迄今為止的最大值,然后用plot繪圖函數繪制即可。