人工智能8—遺傳算法實驗

目錄

一、遺傳算法的原理

二、遺傳算法的算法流程

三、代碼實現及分析

1、城市個數改變,隨機生成城市的座標

2、種羣個數改變

3、交叉概率改變

4、變異概率改變

四、代碼附錄



一、遺傳算法的原理

遺傳算法(GA)是一類借鑑生物界的進化規律(適者生存,優勝劣汰遺傳機制)演化而來的隨機化搜索方法,是模擬達爾文生物進化論的自然選擇和遺傳學機理的生物進化過程的計算模型,是一種通過模擬自然進化過程搜索最優解的方法。

首先,算法會隨機生成一定數量的個體,也可以人爲地設定,這樣可以提高初始種羣的質量。在每一代中,所有的個體都被評價,並通過計算適應度函數得到一個適應度數值,依照適應度,對種羣中的個體進行排序。然後,產生一個新的個體種羣,也就是選擇和繁殖,繁殖包括交配和突變。初始的數據便可以通過這樣的選擇原則組成一個相對優化的羣體。之後,被選擇的個體進入交配過程。經過這一系列的過程(選擇、交配和突變),產生的新一代個體不同於初始的一代,並一代一代向增加整體適應度的方向發展。過程不斷重複,每個個體被評價,計算出適應度,兩個個體交配,然後突變,產生第三代......直到滿足終止條件爲止。

二、遺傳算法的算法流程

(1)初始化規模爲 N的羣體,其中染色體每個基因的值採用隨機數產生器生成並滿足問題定義的範圍。當前進化代數Generation=0。

(2)採用評估函數對羣體中所有染色體進行評價,分別計算每個染色體的適應值,保存適應值最大的染色體Best。

(3)採用輪盤賭選擇算法對羣體的染色體進行選擇操作,產生規模同樣爲N的種羣。

(4)按照概率Pc 從種羣中選擇染色體進行交配。每兩個進行交配的父代染色體,交換部分基因,產生兩個新的子代染色體,子代染色體取代父代染色體進入新種羣。沒有進行交配的染色體直接複製進入新種羣。

(5)按照概率 Pm對新種羣中染色體的基因進行變異操作。發生變異的基因數值發生改變。變異後的染色體取代原有染色體進入新羣體,未發生變異的染色體直接講入新羣體。

(6)變異後的 新羣體取代原有羣體,重新計算羣體中各個染色體的適應值。倘若羣體的最大適應值大於Best的適應值,則以該最大適應值對應的染色體替代Best。

(7)當 前進化代數Generation加1。如果Generation超過規定的最大進化代數或Best達到規定的誤差要求,算法結束;否則返回第(3)步。

三、代碼實現及分析

1、城市個數改變,隨機生成城市的座標

(種羣個數、交叉概率、變異概率都不變)

(1)第一次隨機生成:城市個數N=25,種羣個數M=100,交叉概率Pc=0.8,變異概率Pmutation=0.05

 

 

 

 

 

(2)城市個數N=50,種羣個數M=100,交叉概率Pc=0.8,變異概率Pmutation=0.05

(3)結論

城市個數M可以影響算法的搜索能力和運行效率。當M較大時,曲線收斂的越快越平緩,說明此時算法的搜索能力較好,收斂的較快,反之M越小算法搜索能力越差,運行效率越低。

 

 

 

把城市個數爲50的數據保存下來進行以下的實驗

2、種羣個數改變

(城市個數和城市的座標、交叉概率、變異概率都不變)

(1)種羣個數M=200,城市個數N=50,交叉概率Pc=0.8,變異概率Pmutation=0.05

(2)種羣個數M=500,城市個數N=50,交叉概率Pc=0.8,變異概率Pmutation=0.05

(3)結論

 比較發現,羣體規模N可以影響算法的搜索能力和運行效率。當N較大時,保證了羣體的多樣性,可以提高算法的搜索能力,但是由於羣體中染色體的個數較多,增加了算法的計算量,降低了算法的運行效率。當N較小時,降低了計算量,同時也降低了每次進化中羣體包含更多較好染色體的能力。

 

 

 

3、交叉概率改變

(城市個數和城市的座標、種羣個數、變異概率都不變)

(1)交叉概率Pc=0.1,城市個數N=50,種羣個數M=100,變異概率Pmutation=0.05

(2)交叉概率Pc=0.5,城市個數N=50,種羣個數M=100,變異概率Pmutation=0.05 

 

(3)結論

交配概率Pc決定了進化過程種羣參加交配的染色體平均數目Pc*N,交叉概率越大進化過程中參加交配的染色體平均數目越多,Pc=0.5的比Pc=0.1的算法搜索能力和運行效率都比較好,Pc的取值一般爲0.4-0.99比較好。

 

 

 

4、變異概率改變

(城市個數和城市的座標、種羣個數、交叉概率都不變)

(1)變異概率Pmutation=0.5,城市個數N=50,種羣個數M=100,交叉概率Pc=0.8

(2)變異概率Pmutation=0.9,城市個數N=50,種羣個數M=100,交叉概率Pc=0.8

(3)結論

由圖可知變異概率過大的時候算法無法收斂,不存在最優解。變異概率Pmutation決定了進化過程種羣參加交配的染色體平均數目。Pm的值不宜過大,因爲變異對已找到的較優解具有一定的破壞作用,如果Pm的值太大,可能會導致算法目前所處的較好的搜索狀態倒退回原來較差的情況。Pm的取值一般爲0.001~0.1,也可採用自適應的方法調整算法運行過程中的Pm值。

 

 

 

四、代碼附錄

main.m

%main
clear;
clc;
%%%%%%%%%%%%%%%輸入參數%%%%%%%%
%N=50;               %%城市的個數
M=100;               %%種羣的個數
ITER=2000;               %%迭代次數
%C_old=C;
m=2;                %%適應值歸一化淘汰加速指數
Pc=0.8;             %%交叉概率
Pmutation=0.9;       %%變異概率

% 導入數據
load citys_data.mat
% 計算城市間相互距離
fprintf('Computing Distance Matrix... \n');
N = size(citys,1);
%%生成城市的座標
pos=randn(N,2);
%%生成城市之間距離矩陣
D=zeros(N,N);
for i=1:N
    for j=i+1:N
        dis=(pos(i,1)-pos(j,1)).^2+(pos(i,2)-pos(j,2)).^2;
        D(i,j)=dis^(0.5);
        D(j,i)=D(i,j);
    end
end

%%生成初始羣體

popm=zeros(M,N);
for i=1:M
    popm(i,:)=randperm(N);%隨機排列,比如[2 4 5 6 1 3]
end
%%隨機選擇一個種羣
R=popm(1,:);
figure(1);
scatter(pos(:,1),pos(:,2),'rx');%畫出所有城市座標
axis([-3 3 -3 3]);
figure(2);
plot_route(pos,R);      %%畫出初始種羣對應各城市之間的連線
axis([-3 3 -3 3]);
%%初始化種羣及其適應函數
fitness=zeros(M,1);
len=zeros(M,1);

for i=1:M%計算每個染色體對應的總長度
    len(i,1)=myLength(D,popm(i,:));
end
maxlen=max(len);%最大回路
minlen=min(len);%最小回路

fitness=fit(len,m,maxlen,minlen);
rr=find(len==minlen);%找到最小值的下標,賦值爲rr
R=popm(rr(1,1),:);%提取該染色體,賦值爲R
for i=1:N
    fprintf('%d ',R(i));%把R順序打印出來
end
fprintf('\n');

fitness=fitness/sum(fitness);
distance_min=zeros(ITER+1,1);  %%各次迭代的最小的種羣的路徑總長
nn=M;
iter=0;
while iter<=ITER
    fprintf('迭代第%d次\n',iter);
    %%選擇操作
    p=fitness./sum(fitness);
    q=cumsum(p);%累加
    for i=1:(M-1)
        len_1(i,1)=myLength(D,popm(i,:));
        r=rand;
        tmp=find(r<=q);
        popm_sel(i,:)=popm(tmp(1),:);
    end 
    [fmax,indmax]=max(fitness);%求當代最佳個體
    popm_sel(M,:)=popm(indmax,:);

    %%交叉操作
    nnper=randperm(M);
%    A=popm_sel(nnper(1),:);
 %   B=popm_sel(nnper(2),:);
    %%
    for i=1:M*Pc*0.5
        A=popm_sel(nnper(i),:);
        B=popm_sel(nnper(i+1),:);
        [A,B]=cross(A,B);
  %      popm_sel(nnper(1),:)=A;
  %      popm_sel(nnper(2),:)=B; 
         popm_sel(nnper(i),:)=A;
         popm_sel(nnper(i+1),:)=B;
    end

    %%變異操作
    for i=1:M
        pick=rand;
        while pick==0
             pick=rand;
        end
        if pick<=Pmutation
           popm_sel(i,:)=Mutation(popm_sel(i,:));
        end
    end

    %%求適應度函數
    NN=size(popm_sel,1);
    len=zeros(NN,1);
    for i=1:NN
        len(i,1)=myLength(D,popm_sel(i,:));
    end

    maxlen=max(len);
    minlen=min(len);
    distance_min(iter+1,1)=minlen;
    fitness=fit(len,m,maxlen,minlen);
    rr=find(len==minlen);
    fprintf('minlen=%d\n',minlen);
    R=popm_sel(rr(1,1),:);
    for i=1:N
        fprintf('%d ',R(i));
    end
    fprintf('\n');
    popm=[];
    popm=popm_sel;
    iter=iter+1;
    %pause(1);

end
%end of while

figure(3)
plot_route(pos,R);
axis([-3 3 -3 3]);
figure(4)
plot(distance_min);

cross.m

%交叉操作函數  cross.m
function [A,B]=cross(A,B)
L=length(A);
if L<10
    W=L;
elseif ((L/10)-floor(L/10))>=rand&&L>10
    W=ceil(L/10)+8;
else
    W=floor(L/10)+8;
end
%%W爲需要交叉的位數
p=unidrnd(L-W+1);%隨機產生一個交叉位置
%fprintf('p=%d ',p);%交叉位置
for i=1:W
    x=find(A==B(1,p+i-1));
    y=find(B==A(1,p+i-1));
    [A(1,p+i-1),B(1,p+i-1)]=exchange(A(1,p+i-1),B(1,p+i-1));
    [A(1,x),B(1,y)]=exchange(A(1,x),B(1,y));
end

end

exchange.m

%對調函數 exchange.m

function [x,y]=exchange(x,y)
temp=x;
x=y;
y=temp;
 
end

fit.m

%適應度函數fit.m,每次迭代都要計算每個染色體在本種羣內部的優先級別,類似歸一化參數。越大約好!
function fitness=fit(len,m,maxlen,minlen)
fitness=len;
for i=1:length(len)
    fitness(i,1)=(1-(len(i,1)-minlen)/(maxlen-minlen+0.0001)).^m;
end

Mutation.m

%變異函數 Mutation.m

function a=Mutation(A)
index1=0;index2=0;
nnper=randperm(size(A,2));
index1=nnper(1);
index2=nnper(2);
%fprintf('index1=%d ',index1);
%fprintf('index2=%d ',index2);
temp=0;
temp=A(index1);
A(index1)=A(index2);
A(index2)=temp;
a=A;

end

plot_route.m

%連點畫圖函數 plot_route.m

function plot_route(a,R)
scatter(a(:,1),a(:,2),'rx');
hold on;
plot([a(R(1),1),a(R(length(R)),1)],[a(R(1),2),a(R(length(R)),2)]);
hold on;
for i=2:length(R)
    x0=a(R(i-1),1);
    y0=a(R(i-1),2);
    x1=a(R(i),1);
    y1=a(R(i),2);
    xx=[x0,x1];
    yy=[y0,y1];
    plot(xx,yy);
    hold on;
end

end

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章