遗传算法解决TSP问题

 

 

 

 

function ga_TSP  
 
CityNum=30;
[dislist,Clist]=tsp(CityNum);  
  
inn=30; %初始种群大小  
gnmax=600;  %最大代数  
pc=0.8; %交叉概率  
pm=0.1; %变异概率  
  
%产生初始种群  
s=zeros(inn,CityNum);  
for i=1:inn  
    s(i,:)=randperm(CityNum);  
end  
[~,p]=objf(s,dislist);  
  
gn=1;  
ymean=zeros(gn,1);  
ymax=zeros(gn,1);  
xmax=zeros(inn,CityNum);  
scnew=zeros(inn,CityNum);  
smnew=zeros(inn,CityNum);  
while gn<gnmax+1  
   for j=1:2:inn  
      seln=sel(p);  %选择操作  
      scro=cro(s,seln,pc);  %交叉操作  
      scnew(j,:)=scro(1,:);  
      scnew(j+1,:)=scro(2,:);  
      smnew(j,:)=mut(scnew(j,:),pm);  %变异操作  
      smnew(j+1,:)=mut(scnew(j+1,:),pm);  
   end  
   s=smnew;  %产生了新的种群  
   [f,p]=objf(s,dislist);  %计算新种群的适应度  
   %记录当前代最好和平均的适应度  
   [fmax,nmax]=max(f);  
   ymean(gn)=1000/mean(f);  
   ymax(gn)=1000/fmax;  
   %记录当前代的最佳个体  
   x=s(nmax,:);  
   xmax(gn,:)=x;  
   drawTSP(Clist,x,ymax(gn),gn,0);  
   gn=gn+1;  
end  
[min_ymax,index]=min(ymax);  
drawTSP(Clist,xmax(index,:),min_ymax,index,1);  
  
figure(2);  
plot(ymax,'r'); hold on;  
plot(ymean,'b');grid;  
title('搜索过程');  
legend('最优解','平均解');  
fprintf('遗传算法得到的最短距离:%.2f\n',min_ymax);  
fprintf('遗传算法得到的最短路线');  
disp(xmax(index,:));  
end  
  
%------------------------------------------------  
%计算所有种群的适应度  
function [f,p]=objf(s,dislist)  
  
inn=size(s,1);  %读取种群大小  
f=zeros(inn,1);  
for i=1:inn  
   f(i)=CalDist(dislist,s(i,:));  %计算函数值,即适应度  
end  
f=1000./f'; %取距离倒数  
  
%根据个体的适应度计算其被选择的概率  
fsum=0;  
for i=1:inn  
   fsum=fsum+f(i)^15;% 让适应度越好的个体被选择概率越高  
end  
ps=zeros(inn,1);  
for i=1:inn  
   ps(i)=f(i)^15/fsum;  
end  
  
%计算累积概率  
p=zeros(inn,1);  
p(1)=ps(1);  
for i=2:inn  
   p(i)=p(i-1)+ps(i);  
end  
p=p';  
end  
  
%--------------------------------------------------  
%根据变异概率判断是否变异  
function pcc=pro(pc)  
test(1:100)=0;  
l=round(100*pc);  
test(1:l)=1;  
n=round(rand*99)+1;  
pcc=test(n);     
end  
  
%--------------------------------------------------  
%“选择”操作  
function seln=sel(p)  
  
seln=zeros(2,1);  
%从种群中选择两个个体,最好不要两次选择同一个个体  
for i=1:2  
   r=rand;  %产生一个随机数  
   prand=p-r;  
   j=1;  
   while prand(j)<0  
       j=j+1;  
   end  
   seln(i)=j; %选中个体的序号  
   if i==2&&j==seln(i-1)    %%若相同就再选一次  
       r=rand;  %产生一个随机数  
       prand=p-r;  
       j=1;  
       while prand(j)<0  
           j=j+1;  
       end  
   end  
end  
end  
  
%------------------------------------------------  
%“交叉”操作  
function scro=cro(s,seln,pc)  
  
bn=size(s,2);  
pcc=pro(pc);  %根据交叉概率决定是否进行交叉操作,1则是,0则否  
scro(1,:)=s(seln(1),:);  
scro(2,:)=s(seln(2),:);  
if pcc==1  
   c1=round(rand*(bn-2))+1;  %在[1,bn-1]范围内随机产生一个交叉位  
   c2=round(rand*(bn-2))+1;  
   chb1=min(c1,c2);  
   chb2=max(c1,c2);  
   middle=scro(1,chb1+1:chb2);  
   scro(1,chb1+1:chb2)=scro(2,chb1+1:chb2);  
   scro(2,chb1+1:chb2)=middle;  
   for i=1:chb1 
       while find(scro(1,chb1+1:chb2)==scro(1,i))  
           zhi=find(scro(1,chb1+1:chb2)==scro(1,i));  
           y=scro(2,chb1+zhi);  
           scro(1,i)=y;  
       end  
       while find(scro(2,chb1+1:chb2)==scro(2,i))  
           zhi=find(scro(2,chb1+1:chb2)==scro(2,i));  
           y=scro(1,chb1+zhi);  
           scro(2,i)=y;  
       end  
   end  
   for i=chb2+1:bn  
       while find(scro(1,1:chb2)==scro(1,i))  
           zhi=logical(scro(1,1:chb2)==scro(1,i));  
           y=scro(2,zhi);  
           scro(1,i)=y;  
       end  
       while find(scro(2,1:chb2)==scro(2,i))  
           zhi=logical(scro(2,1:chb2)==scro(2,i));  
           y=scro(1,zhi);  
           scro(2,i)=y;  
       end  
   end  
end  
end  
  
%--------------------------------------------------  
%“变异”操作  
function snnew=mut(snew,pm)  
  
bn=size(snew,2);  
snnew=snew;  
  
pmm=pro(pm);  %根据变异概率决定是否进行变异操作,1则是,0则否  
if pmm==1  
   c1=round(rand*(bn-2))+1;  %在[1,bn-1]范围内随机产生一个变异位  
   c2=round(rand*(bn-2))+1;  
   chb1=min(c1,c2);  
   chb2=max(c1,c2);  
   x=snew(chb1+1:chb2);  
   snnew(chb1+1:chb2)=fliplr(x);  
end  
end  
  
%------------------------------------------------  
%城市位置坐标  
function [DLn,cityn]=tsp(n)  
DLn=zeros(n,n);  
 if n==30  
    city30=[18 54;87 76;74 78;71 71;25 38;58 35;4 50;13 40;18 40;24 42;71 44;64 60;68 58;  
        83 69;58 69;54 62;51 67;37 84;41 49;2 99;7 64;22 60;25 62;62 32;87 7;91 38;83 46;41 26;45 21;44 35];
    for i=1:30  
        for j=1:30  
            DLn(i,j)=((city30(i,1)-city30(j,1))^2+(city30(i,2)-city30(j,2))^2)^0.5;  
        end  
    end  
    cityn=city30;  
 end
end
  
%------------------------------------------------  
%适应度函数  
function F=CalDist(dislist,s)  
  
DistanV=0;  
n=size(s,2);  
for i=1:(n-1)  
    DistanV=DistanV+dislist(s(i),s(i+1));  
end  
DistanV=DistanV+dislist(s(n),s(1));  
F=DistanV;  
  
end  
  
%------------------------------------------------  
%画图  
function drawTSP(Clist,BSF,bsf,p,f)  
CityNum=size(Clist,1);  
for i=1:CityNum-1  
    plot([Clist(BSF(i),1),Clist(BSF(i+1),1)],[Clist(BSF(i),2),Clist(BSF(i+1),2)],'ms-','LineWidth',2,'MarkerEdgeColor','k','MarkerFaceColor','g');  
    text(Clist(BSF(i),1),Clist(BSF(i),2),['  ',int2str(BSF(i))]);  
    text(Clist(BSF(i+1),1),Clist(BSF(i+1),2),['  ',int2str(BSF(i+1))]);  
    hold on;  
end  
plot([Clist(BSF(CityNum),1),Clist(BSF(1),1)],[Clist(BSF(CityNum),2),Clist(BSF(1),2)],'ms-','LineWidth',2,'MarkerEdgeColor','k','MarkerFaceColor','g');  
title([num2str(CityNum),'城市TSP']);  
if f==0&&CityNum~=10  
    text(5,5,['第 ',int2str(p),' 代','  最短距离为 ',num2str(bsf)]);  
else  
    text(5,5,['最后结果:最短距离 ',num2str(bsf),', 在第 ',num2str(p),' 代达到']);  
end  
if CityNum==10  
    if f==0  
        text(0,0,['第 ',int2str(p),' 代','  最短距离为 ',num2str(bsf)]);  
    else  
        text(0,0,['最后结果:最短距离 ',num2str(bsf),', 在第 ',num2str(p),' 代达到']);  
    end  
end  
hold off;  
pause(0.05);   
end  


 


 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zgsslf

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值