1、问题介绍
2、遗传算法与程序
1、问题介绍
旅行商问题(TSP问题)介绍。
假设有一个旅行商人要拜访全国48个省会城市,他需要选择所要走的路径,路径的限制是每个城市只能拜访一次,而且最后要回到原来出发的城市。对路径选择的要求是:所选路径的路程为所有路径之中的最小值。
全国48个省会城市的坐标如下:
[6734 1453
2233 10
5530 1424
401 841
3082 1644
7608 4458
7573 3716
7265 1268
6898 1885
1112 2049
5468 2606
5989 2873
4706 2674
4612 2035
6347 2683
6107 669
7611 5184
7462 3590
7732 4723
5900 3561
4483 3369
6101 1110
5199 2182
1633 2809
4307 2322
675 1006
7555 4819
7541 3981
3177 756
7352 4506
7545 2801
3245 3305
6426 3173
4608 1198
23 2216
7248 3779
7762 4595
7392 2244
3484 2829
6271 2135
4985 140
1916 1569
7280 4899
7509 3239
10 2676
6807 2993
5185 3258
3023 1942]; 。
2、遗传算法与程序
遗传算法参数
(1)、初始化种群数目为NP=200, 染色体基因维数为N=48(即每个省会为一个基因), 最大进化代数为G=1000。
(2)、产生初始种群,计算个体适应度值,即路径长度;采用基于概率的方式选择进行操作的个体;对选中的成对个体,随机交叉所选中的成对城市坐标,以确保交叉后路径每个城市只到访一次;对选中的单个个体,随机交换其一对城市坐标作为变异操作,产生新的种群,进行下一次遗传操作。
(3)、判断是否满足终止条件:若满足,则结束搜索过程,输出优化值;若不满足,则继续进行迭代优化。
具体MATLAB实现程序与介绍如下
// 遗传算法程序
clear all; %清除所有变量
close all; %清图
clc; %清屏
C=[6734 1453
2233 10
5530 1424
401 841
3082 1644
7608 4458
7573 3716
7265 1268
6898 1885
1112 2049
5468 2606
5989 2873
4706 2674
4612 2035
6347 2683
6107 669
7611 5184
7462 3590
7732 4723
5900 3561
4483 3369
6101 1110
5199 2182
1633 2809
4307 2322
675 1006
7555 4819
7541 3981
3177 756
7352 4506
7545 2801
3245 3305
6426 3173
4608 1198
23 2216
7248 3779
7762 4595
7392 2244
3484 2829
6271 2135
4985 140
1916 1569
7280 4899
7509 3239
10 2676
6807 2993
5185 3258
3023 1942]; %48个省会城市坐标
N=size(C,1); %TSP问题的规模,即城市数目(size计算矩阵的大小)
D=zeros(N); %存放任意两个城市距离间隔的矩阵 48*48
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%求任意两个城市距离间隔矩阵(用勾股定理求得)
for i=1:N
for j=1:N
D(i,j)=((C(i,1)-C(j,1))^2+(C(i,2)-C(j,2))^2)^0.5;
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%初始化
NP=200; %种群规模
G=1000; %最大遗传代数
f=zeros(NP,N); %用于存储种群矩阵 200*48
F=[]; %种群更新中间存储
for i=1:NP
f(i,:)=randperm(N); %随机生成初始种群 randperm随机生成1到N的不重复的矩阵
end
R=f(1,:); %存储最优种群
len=zeros(NP,1); %存储每个染色体路径长度 矩阵200*1
fitness=zeros(NP,1); %存储归一化适应值 矩阵200*1
gen=0;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%遗传算法循环
%%%这个地方用for循环也行因为次数为一定的。
while gen<G
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%计算路径长度(200个种群的路径长度)
for i=1:NP
len(i,1)=D(f(i,N),f(i,1)); %计算每个染色体最后一个基因到第一个基因的距离
for j=1:(N-1)
len(i,1)=len(i,1)+D(f(i,j),f(i,j+1)); %计算每个染色体剩下几个城市的距离
end
end
maxlen=max(len); %求最长路径
minlen=min(len); %求最短路径
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%更新最短路径
rr=find(len==minlen); %找路境中与minlen相等元素的位置
R=f(rr(1,1),:); %最短路径
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%计算归一化适应值 +0.001不知道是干嘛的 (1-是将归一化的的值进行取反)
for i=1:length(len) %length计算矩阵的行数
fitness(i,1)=(1-((len(i,1)-minlen)/(maxlen-minlen+0.001)));
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%选择操作
nn=0;
%%%对200各种群随机抽nn个放入F中
for i=1:NP
if fitness(i,1)>=rand %归一化后的适应度随机选择
nn=nn+1;
F(nn,:)=f(i,:); %f为种群数
end
end
[aa,bb]=size(F); %aa为F矩阵行数,bb为F矩阵列数
%%%对F中nn个项进行交叉
%%%这个地方只能用while
while aa<NP
nnper=randperm(nn); %nn为一个可变的数
A=F(nnper(1),:);
B=F(nnper(2),:);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%交叉操作
W=ceil(N/10); %交叉点个数 ceil为进1取整函数
p=unidrnd(N-W+1); %随机选择交叉范围,从p到p+W,unidrnd(5)表示随机产生1-5中的一个数
%%%对两个数据进行W位的交叉
for i=1:W
x=find(A==B(p+i-1)); %找A中与B(p+i-1)相等元素的位置 例如 x=7
y=find(B==A(p+i-1)); %找B中与A(p+i-1)相等元素的位置 例如 Y=29
temp=A(p+i-1); % 例如 p=21 temp=34
A(p+i-1)=B(p+i-1); % A里重了13
B(p+i-1)=temp; % B里重了34
temp=A(x); % A中7位置的值给 temp=13
A(x)=B(y); % A中7的位置变为34(即与B中29的位置交换)
B(y)=temp; % B中29的位置变为13
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%变异操作
p1=floor(1+N*rand()); %N为城市数 floor向下取整
p2=floor(1+N*rand());
while p1==p2
p1=floor(1+N*rand());
p2=floor(1+N*rand());
end
tmp=A(p1);
A(p1)=A(p2);
A(p2)=tmp;
tmp=B(p1);
B(p1)=B(p2);
B(p2)=tmp; %一次变异两个个体
F=[F;A;B]; %将交叉变异后的个体存入F中
[aa,bb]=size(F);
end
if aa>NP
F=F(1:NP,:); %保持种群规模为NP=200个
end
f=F; %更新种群
f(1,:)=R; %保留每代最优个体
clear F; %重点(这个地方一定要清空)
gen=gen+1;
Rlength(gen)=minlen; %存储最短路径
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%连接最短的路径
figure
for i=1:N-1
plot([C(R(i),1),C(R(i+1),1)],[C(R(i),2),C(R(i+1),2)],'bo-');
hold on;
end
plot([C(R(N),1),C(R(1),1)],[C(R(N),2),C(R(1),2)],'ro-');
title(['优化最短距离:',num2str(minlen)]);
figure
plot(Rlength)
xlabel('迭代次数')
ylabel('目标函数值')
title('适应度进化曲线')
仿真结果如图1,2所示:
** 图1 最短路径图**
** 图2 迭代次数图**
文章来源
文章大部分来自于智能优化算法及其MATLAB实例(第2版)的例2.3。可能是MATLAB版本的原因,书中的程序无法运行,本文将其进行了改写和解释。