同模擬退火算法一樣,都是現代優化算法之一。模擬退火是在一定接受程度的情況下仍然接受一個比較差的解。
遺傳算法,是真真正正的和大自然的遺傳進化有着非常緊密的聯系的,當然遺傳進化的只是在生物學中已經講過了,8個字,物競天擇,適者生存。
-
簡介
《物種起源》,有興趣可以看看達爾文的著作。
物競天擇,適者生存,這兩句話,也可以說是對遺傳算法過程的偽代碼描述了,物競天擇,就是我們的目標函數,只有越滿足我們的目標函數的個體才會留下來,適者生存,就是我們在算法的過程中要淘汰一些個體。
-
基因編碼方式
生物學里面告訴我們,遺傳,變異都是以種群為研究對象的,怎么表示一個解呢?用他的基因表示,嘿嘿,組成這個解的步驟表示,第一步干什么,第二步干什么,怎么在程序中編碼呢?
常用兩種編碼方式:二進制編碼,浮點數編碼。
二進制編碼:一定精度的二進制只能表示一定精度的浮點數。栗子,要求精確到6位小數,而區間是 [-1,2],至少要把區間划分為3*10^6等分。編碼也就需要22位。這里就涉及到一個二進制串轉換到一個區間為 [-1,2] 的實數,兩者相互轉換。比如得到的十進制數為 x,那么對應的 [-1,2] 區間的浮點數就是

浮點數編碼:為改善遺傳算法的復雜度,提出來浮點數編碼
-
適應評分及選擇函數
適應評分函數就是用來衡量哪個個體應該被淘汰。但是也不能說,取值差點的個體一定就被淘汰了,這里會有一個概率存在,怎么建立一種概率關系呢?常用的方法是輪盤法。假設種群數為 n,某個個體 i 的適應度為 fi,那么個體 i 被選擇的概率是:

So,遺傳算法中的自然選擇過程:
適應評分函數——求出各個體的適應評分值
輪盤選擇——個體被選擇的概率
-
基因重組與基因突變
在生物學中,基因重組有兩種情況。
基因重組,就是兩個個體基因發生交換。
基因突變是一種小概率事件。
使得一個基因變成他的等位基因,引起一定的表現型變化。
-
TSP問題求解
TSP問題,之前已經用費用流,和模擬退火做過了,現在用遺傳來討論。
程序過程和自然界中的遺傳與進化是一樣的。
-
生成50個個體,形成種群,並基因編碼。
-
基因重組,突變,和父代,一起進行天擇。
-
重復100次進化。得到較優的解。
clc,clear; sj0 = load('sj.txt'); x = sj0(:,1:2:8); x = x(:); y = sj0(:,2:2:8); y = y(:); sj = [x,y];d1 = [70,40]; sj = [d1;sj;d1]; sj = sj*pi/180; d = zeros(102); for i = 1:101 for j = i+1:102 d(i,j) = 6370*acos(cos(sj(i,1)-sj(j,1))*cos(sj(i,2))*cos(sj(j,2))+sin(sj(i,2))*sin(sj(j,2))); end end d = d + d'; % w 為種群數,g為進化的代數 w = 50; g = 100; rand('state',sum(clock)); % 改良圈算法選取初始種群 for k=1:w %通過改良圈算法選取初始種群 c=randperm(100); %產生1,...,100的一個全排列 c1=[1,c+1,102]; %生成初始解 for t=1:102 %該層循環是修改圈 flag=0; %修改圈退出標志 for m=1:100 for n=m+2:101 if d(c1(m),c1(n))+d(c1(m+1),c1(n+1))<d(c1(m),c1(m+1))+d(c1(n),c1(n+1)) c1(m+1:n)=c1(n:-1:m+1); flag=1; %修改圈 end end end if flag==0 J(k,c1)=1:102; break %記錄下較好的解並退出當前層循環 end end end % 染色體編碼 J(:,1) = 0; J = J/102; % 100次進化 for k = 1:g A = J; c = randperm(w); for i = 1:2:w % 基因重組 F = 2 + floor(100*rand(1)); % 產生交叉操作的染色體對 tmp = A(c(i),[F:102]); A(c(i),[F:102]) = A(c(i+1),[F:102]); A(c(i+1),F:102) = tmp; end % 變異 by = []; while ~isempty(by) % 變異的個體數也是隨機的 by =find(rand(1,w)<0.1); end B = A(by,:); % 變異染色體 for j = 1:length(by) bw = sort(2+floor(100*rand(1,3))); % 產生變異操作的3個地址 B(j,:) = B(j,[1:bw(1),bw(2)+1:bw(3),bw(1):bw(2),bw(3)+1:102]); end G=[J;A;B]; % 父代和子代 % 基因翻譯為解空間,把染色體翻譯成1,...,102的序列ind1 [SG,ind1] = sort(G,2); num = size(G,1); % 父子種群的總個體數 long = zeros(1,num); % 每一個體的優劣 for j = 1:num for i = 1:101 long(j) = long(j)+d(ind1(j,i),ind1(j,i+1)); end end [slong,ind2] = sort(long); J = G(ind2(1:w),:); end path = ind1(ind2(1),:); flong = slong(1); xx = sj(path,1); yy = sj(path,2); plot(xx,yy,'-o');
參考:
ACdreamer
司守奎