遗传算法解决TSP问题

一、遗传算法简介

1.遗传算法的概述

遗传算法的基本思想是从初始种群出发,采用优胜劣汰、 适者生存的自然法则选择个体,并通过杂交、变异来产生新 一代种群,如此逐代进化,直到满足目标为止。遗传算法所 涉及到的基本概念主要有以下几个:
• 种群(Population):种群是指用遗传算法求解问题时, 初始给定的多个解的集合。遗传算法的求解过程是从这个子 集开始的。

•个体(Individual):个体是指种群中的单个元素,它通常 由一个用于描述其基本遗传结构的数据结构来表示。例如, 可以用0、1组成的长度为l的串来表示个体。

• 染色体(Chromosome):染色体是指对个体进行编码后 所得到的编码串。染色体中的每1位称为基因,染色体上由 若干个基因构成的一个有效信息段称为基因组。

• 适应度(Fitness)函数:适应度函数是一种用来对种群中 各个个体的环境适应性进行度量的函数。其函数值是遗传 算法实现优胜劣汰的主要依据

• 遗传操作(Genetic Operator):遗传操作是指作用于种 群而产生新的种群的操作。标准的遗传操作包括以下3种基本形式:
– 选择(Selection)
– 杂交(Crosssover)
– 变异(Mutation)

2.TSP问题

旅行商问题是图论中的一个著名问题。
假设有一个旅行商人要拜访N个城市,要求他从一个城市出发,每个城市最多拜访一次,最后要回到出发的城市,保证所选择的路径长度最短。

二、代码实现

1.相关参数

N : 城市的个数
M : 种群的个数
ITER: 迭代次数
m: 适应值归一化淘汰加速指数
Pc: 交叉概率
Pmutation: 变异概率

2.相关代码

(1)主函数main
%main
clear;
clc;
%%%%%%%%%%%%%%%输入参数%%%%%%%%
N=25;               %%城市的个数
M=100;               %%种群的个数
ITER=2000;               %%迭代次数
%C_old=C;
m=2;                %%适应值归一化淘汰加速指数
Pc=0.8;             %%交叉概率
Pmutation=0.05;       %%变异概率
%%生成城市的坐标
load citys.mat
pos=citys;

%%生成城市之间距离矩阵
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);
(2)保存城市坐标函数city
N=25;
citys=randn(N,2);
save citys.mat
(3)交叉操作函数cross
%交叉操作函数  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
(4)对调函数exchange
%对调函数 exchange.m

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

(5)适应度函数fit
%适应度函数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
(6)变异函数mutation
%变异函数 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
(7)染色体的路程代价函数myLength
%染色体的路程代价函数  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
(8)连点画图函数plot_route
%连点画图函数 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=25,种群数量m=100,交叉概率Pc=0.8,变异概率Pmutation=0.05时:
城市位置分布图:
遗传算法解决TSP问题_第1张图片
初始种群路线:
遗传算法解决TSP问题_第2张图片
最终路线:
遗传算法解决TSP问题_第3张图片
2000次迭代后路径总长的变化,当迭代次数为462次时,已找到最短路径:
遗传算法解决TSP问题_第4张图片
遗传算法解决TSP问题_第5张图片

1.改变种群数量:

m=200:

遗传算法解决TSP问题_第6张图片
遗传算法解决TSP问题_第7张图片
遗传算法解决TSP问题_第8张图片
遗传算法解决TSP问题_第9张图片

m=300:

遗传算法解决TSP问题_第10张图片
遗传算法解决TSP问题_第11张图片
遗传算法解决TSP问题_第12张图片
遗传算法解决TSP问题_第13张图片

当城市位置、交叉概率、变异概率不变,改变种群数量,测试结果如下图:
种群个数 收敛时迭代次数 最短距离 运行时间
100 462 21.27 24.094
200 932 21.81 21.945
300 274 20.57 18.830

由结果可知,其他参数不变的前提下,随着种群数量的增加,收敛时迭代次数先减少后增加,最短距离先增后减,运行时间随着变化趋势而减少。说明种群数量应当适当。

2.改变交叉概率:

Pc=0.2:

遗传算法解决TSP问题_第14张图片
遗传算法解决TSP问题_第15张图片
遗传算法解决TSP问题_第16张图片
遗传算法解决TSP问题_第17张图片

Pc=0.4:

遗传算法解决TSP问题_第18张图片
遗传算法解决TSP问题_第19张图片
遗传算法解决TSP问题_第20张图片
遗传算法解决TSP问题_第21张图片

当城市位置、种群数量、变异概率不变,改变交叉概率时,测试结果如下图:
交叉概率 收敛时迭代次数 最短距离 运行时间
0.2 263 19.23 18.811
0.4 328 21.11 23.144
0.8 462 21.27 24.094

由结果可知,其他参数不变的前提下,当交叉概率逐渐增加,收敛时迭代次数和最短距离还有运行时间都逐渐增加。

3.改变变异概率:

Pmutation=0.02:

遗传算法解决TSP问题_第22张图片
遗传算法解决TSP问题_第23张图片
遗传算法解决TSP问题_第24张图片
遗传算法解决TSP问题_第25张图片

Pmutation=0.08:

遗传算法解决TSP问题_第26张图片
遗传算法解决TSP问题_第27张图片
遗传算法解决TSP问题_第28张图片
遗传算法解决TSP问题_第29张图片

当城市位置、种群数量、交叉概率不变,改变变异概率时,测试结果如下图:
变异概率 收敛时迭代次数 最短距离 运行时间
0.02 359 18.70 19.711
0.05 663 20.45 23.776
0.08 462 21.27 24.094

由结果可知,其他参数不变的前提下,当变异概率逐渐增加时,收敛时迭代次数先增加后减少,最短距离和运行时间都逐渐增加。

3.改变城市数量:

N=50:

遗传算法解决TSP问题_第30张图片
遗传算法解决TSP问题_第31张图片
在这里插入图片描述
遗传算法解决TSP问题_第32张图片

当种群数量、交叉概率、变异概率不变,改变城市数量时,测试结果如下图:
城市数量 收敛时迭代次数 最短距离 运行时间
25 462 21.27 24.094
50 1975 36.2 29.280

由结果可知,其他参数不变的前提下,当城市数量率逐渐增加时,收敛时迭代次数将逐渐逼近2000,最短距离和运行时间都大幅度增加。所以,在城市数量过大时,遗传算法解决TSP问题将存在缺陷,此时可用蚁群算法等其他算法来求解。

你可能感兴趣的:(遗传算法解决TSP问题)