遺傳算法求解TSP問題


一、簡介

  遺傳算法是基於達爾文的生物進化論,是人工智能算法的的重要分支,主要用於解決一類求最優解問題。如旅行商(TSP)問題。

  遺傳算法是將狀態當成染色體,狀態里的每一個決策都是染色體上的一個基因。然后根據實際情況生成一個適應度函數,計算每一串染色體對環境的適應度。讓適應度高的遺傳到下一代,適應度低的淘汰掉,另外在實現的過程中也許會發生變異,導致一些決策改變。除此之外,遺傳算法是隨機性近似算法,所以當我們運用該算法時必須采取措施使其收斂到全局最優解,並且盡量提高達到最優解的概率。遺傳算法除了設計適應度函數以外,還有很重要的三個部分:選擇,交叉,變異。

 

二、遺傳算法實現步驟

1.評估每條染色體所對應個體的適應度。

2.遵照適應度越高,選擇概率越大的原則,從種群中選擇兩個個體作為父方和母方。

3.抽取父母雙方的染色體,進行交叉,產生子代。

4.對子代的染色體進行變異。

5.重復2,3,4步驟,直到新種群的產生。

 

三、遺傳算法求解TSP實現步驟

1.確定影響因素

   城市序列、城市個數N、種群個數M、交叉概率Pc、變異概率Pmutation等;

2.初始化數據

 2.1初始化影響因素:城市序列、城市個數N、種群個數M、交叉概率Pc、變異概率Pmutation

 2.2 初始化數據:讀入數據源,將坐標轉換為距離矩陣(標准化歐式距離)

3.計算種群適應度
  已知任意兩個城市之間的距離,每個染色體可計算出總距離,因此可以將一個隨機全排列的總距離的倒數作為適應度函數,即距離越短,適應度函數越好。

4.迭代
選擇算子:賭輪選擇策略挑選下一代個體。
交叉運算:在交叉概率的控制下,對群體中的個體兩兩進行交叉。
變異運算:在變異概率的控制下,對群體中的個體兩兩進行變異,即對某一個體的基因進行隨機調整。
計算新的種群適應度以及個體累積概率,並更新最優解。
將新種群復制到舊種群中,准備下一代進化(迭代)。

5.輸出
輸出迭代過程中產生的最短路徑長度以及最短路徑。

四、代碼實現

  main.m(主函數):

%main
clear;
clc;
%%%%%%%%%%%%%%%輸入參數%%%%%%%%
N=25;               %%城市的個數
M=100;               %%種群的個數
ITER=2000;               %%迭代次數
%C_old=C;
m=2;                %%適應值歸一化淘汰加速指數
Pc=0.8;             %%交叉概率
Pmutation=0.05;       %%變異概率
%%生成城市的坐標
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(交叉操作函數):

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(對調函數):

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

  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(變異函數):

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

  mylength.m(染色體的路程代價函數):

function len=myLength(D,p)%p是一個排列
[N,NN]=size(D);
len=D(p(1,N),p(1,1));
for i=1:(N-1)
    len=len+D(p(1,i),p(1,i+1));
end
end

   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

五、實驗結果與分析

  分別測試城市序列、城市個數N、種群個數M、交叉概率Pc、變異概率Pmutation等影響因素對實驗結果的影響

 1、不同城市序列對實驗結果的影響:

 

 

 

 

 

 

 

 

 

 

 

 

  分析:在本算法實現過程中,城市序列采用隨機生成,當城市序列不同時,算法運行時間和最短回路距離也會不同。

 

2、種群個數M(其他因素不變)對實驗結果的影響:

M=100,城市個數N=35,其坐標分別如下:(在后面的測試中各城市坐標均如下所示)

 

 

 M=100(如圖顯示約迭代1100次得到最短回路距離為20.92):

 

 

 M=80(如圖顯示約迭代1000次得到最短回路距離為23.25)

 

 

 M=60(如圖顯示約迭代1400次得到最短回路距離為23.59)

 

 M=40(如圖顯示約迭代1750次得到最短回路距離為24.06)

 

 

 

分析:如上4組數據所示,當種群規模增大時,算法收斂到最優解的可能性越大,全局搜索能力也有所增強;另外可以看出當種群規模增大后,在解空間中搜索時,可以在相對較少的代數中找到最優解,進化代數也隨着種群規模的增大而變小了。種群規模越大算法結果越精確,適應度越好。

 

3、交叉概率Pc對實驗結果的影響

Pc=0.8(如圖顯示約迭代1000次得到最短回路距離為22.21)

 

 Pc=0.6(如圖顯示約迭代900次得到最短回路距離為23.08)

 Pc=0.4(如圖顯示約迭代1100次得到最短回路距離為23.36)

 

 

 

 

 

  Pc=0.2(如圖顯示約迭代1700次得到最短回路距離為22.23)

 

 

 

 Pc=0.01(如圖顯示約迭代1800次得到最短回路距離為25.14)

 

 

 

 分析:如以上五組測試數據和運行結果可以看出,當交叉概率越小,迭代次數越大且得不到最優解,當交叉概率越大時,迭代次數越是且得到的結果更優。所以交叉概率較大時,結果越優。

 

4、變異概率Pmutation對實驗結果的影響

Pmutation=0.05(如圖顯示約迭代1100次得到最短回路距離為22.57)

 

 

 

 Pmutation=0.1(如圖顯示約迭代1600次得到最短回路距離為21.52)

 

 

 

 Pmutation=0.3(如圖顯示約迭代1500次得到最短回路距離為23.20)

 

 

 

 Pmutation=0.6(如圖顯示約迭代2000次得到最短回路距離為28.56)

 

 

 

  Pmutation=0.005(如圖顯示約迭代1700次得到最短回路距離為24.38)

 

 

 

 分析:如以上五組測試數據和運行結果可以看出,當變異概率大於0.1時,變異概率越大,迭代次數越大且最短回路距離也變得越大,得不到最優解。當變異概率小於0.1時,變異概率越小,迭代次數越大且最短回路距離也變得越大,也無法得到最優解!!所以當變異概率越接近0.1時,越能得到最優解。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM