基于遗传算法的TSP问题解决.docx
《基于遗传算法的TSP问题解决.docx》由会员分享,可在线阅读,更多相关《基于遗传算法的TSP问题解决.docx(11页珍藏版)》请在冰豆网上搜索。
基于遗传算法的TSP问题解决
基于遗传算法的TSP问题解决
—余小欢B07330230
概述:
TSP问题是一个经典的运筹学的组合优化问题,针对此问题,研究人员提出了个中各样的算法,主要有贪婪算法,遗传算法,混沌搜索算法等。
在本文中分别用贪婪算法和遗传算法去解决30个城市的最短路径问题,并把两者得到了最优解进行比较,发现用遗传算法解决TSP问题非常具有优越性,同时在文章的最后提出了对此遗传算法进行改进的方向。
1.贪婪算法
x=[188774712558413182471646883585451374127222562879183414544];
y=[5476787138355040404042446058696962678494996460623273846262135];
a=zeros(30,30);
fori=1:
30
forj=1:
30
a(i,j)=sqrt((x(i)-x(j))^2+(y(i)-y(j))^2);%求取距离矩阵的值
end
a(i,i)=1000;%主对角线上的元素置为1000作为惩罚
end
b=0;
c=zeros(30);
forj=1:
30
[m,n]=min(a(:
j));
b=b+m;%得到的b值即为贪婪最佳路径的总距离
a(n,:
)=1000;%已经选择的最小值对应的行的所有值置为1000作为惩罚
c(j)=n;
end
x1=zeros(30);
y1=zeros(30);
fort=1:
30
x1(t)=x(c(t));
y1(t)=y(c(t));
end
plot(x1,y1,'-or');
xlabel('Xaxis'),ylabel('Yaxis'),title('Ì°À·Â·¾¶');
axis([0,1,0,1]);
axis([0,100,0,100]);
axison
用贪婪算法得出的最佳路径走遍30个城市所走的路程为449.3845km
其具体的路径图如下:
2.遗传算法
1主函数部分
clc;
clearall;
closeall;
globalxy
cityfile=fopen('city30.txt','rt');%取30个城市的样本
cities=fscanf(cityfile,'%f%f',[2,inf]);%fscanf返回数据的个数
fclose(cityfile);
t=30+1;%城市的数目是30个
s=1500;%样本的数目是1400个
G=300;%运算的代数
c=25;%选择算子中每次替代的样本的数量
x=cities(1,:
);
y=cities(2,:
);
pc=0.10;%交叉的概率
pm=0.8;%变异的概率
pop=zeros(s,t);%得初始的pop矩阵,矩阵的最后一列表示所在行的样本的路径距离
fori=1:
s
pop(i,1:
t-1)=randperm(t-1);%随机产生1—(t-1)的t-1个数
end
fork=1:
1:
G%GA开始
ifmod(k,50)==1
k
end
pop=distance(pop);%调用距离函数求距离
pop=select(pop,c);%调用选择函数
p1=rand;
ifp1>=pc
pop=cross(pop);%调用交叉函数
end
p2=rand;
ifp2>=pm
pop=mutate(pop);%调用变异函数
end
end%GA结束
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bestL=min(pop(:
t))
J=pop(:
t);
fi=1./J;
[Oderfi,Indexfi]=sort(fi);%对于fi进行排序
BestS=pop(Indexfi(s),:
);%得到最短路
I=BestS;
fori=1:
1:
t-1
x1(i)=x(I(i));
y1(i)=y(I(i));
end
x1(t)=x(I
(1));
y1(t)=y(I
(1));
cities_new=[x1;y1];
disp('BestRouteis:
');disp(cities_new);
pos=[cities_newcities_new(:
1)];
lentemp=0;
fori=1:
1:
t-1
temp=sqrt((pos(1,i)-pos(1,i+1))^2+(pos(2,i)-pos(2,i+1))^2);
lentemp=lentemp+temp;
end
disp('ShortestLengthis:
');disp(lentemp);
figure
(1);
subplot(1,2,1);%窗口分割的左边部分
x(t)=x
(1);y(t)=y
(1);
plot(x,y,'-or');
xlabel('Xaxis'),ylabel('Yaxis'),title('原始路径');
axis([0,1,0,1]);
axis([0,100,0,100]);
axison
holdon;
subplot(1,2,2);%窗口分割的右边部分
plot(x1,y1,'-or');
xlabel('Xaxis'),ylabel('Yaxis'),title('最新的路径');
axis([0,1,0,1]);
axis([0,100,0,100]);
axison
2距离函数
function[pop]=distance(pop)
globalxy
[s,t]=size(pop);
fori=1:
1:
s
dd=0;
pos=pop(i,1:
t-1);
pos=[pospos(:
1)];
forj=1:
1:
t-1
m=pos(j);
n=pos(j+1);
dd=dd+sqrt((x(m)-x(n))^2+(y(m)-y(n))^2);
end
pop(i,t)=dd;
end
3选择函数
unction[pop]=select(pop,c)
[s,t]=size(pop);
m11=(pop(:
t));
m11=m11';
mmax=zeros(1,c);
mmin=zeros(1,c);
num=1;
whilenum[a,mmax(num)]=max(m11);%选取当前样本的最大值并记录样本编号给mmax(num)
m11(mmax(num))=0;
num=num+1;
end
num=1;
whilenum[b,mmin(num)]=min(m11);
m11(mmin(num))=a;
num=num+1;
end
fori=1:
c
pop(mmax(i),:
)=pop(mmin(i),:
);%用距离小的C个样本替换距离大的C个样本
end
4交叉函数
function[pop]=cross(pop)
[s,t]=size(pop);
pop_1=pop;
n=randperm(s);%将种群随机排序
fori=1:
2:
s
%随机选择两个交叉点
m=randperm(t-3)+1;
crosspoint
(1)=min(m
(1),m
(2));
crosspoint
(2)=max(m
(1),m
(2));
%任意两行交叉
x1=n(i);
x2=n(i+1);
%将x1左边与x2的左边互换
middle=pop(x1,1:
crosspoint
(1));
pop(x1,1:
crosspoint
(1))=pop(x2,1:
crosspoint
(1));
pop(x2,1:
crosspoint
(1))=middle;
%将x1右边与x2的右边互换
middle=pop(x1,crosspoint
(2)+1:
t);
pop(x1,crosspoint
(2)+1:
t)=pop(x2,crosspoint
(2)+1:
t);
pop(x2,crosspoint
(2)+1:
t)=middle;
%检查x1左边的重复性并得到x1的左边
forj=1:
crosspoint
(1)
whilefind(pop(x1,crosspoint
(1)+1:
crosspoint
(2))==pop(x1,j))
zhi=find(pop(x1,crosspoint
(1)+1:
crosspoint
(2))==pop(x1,j));%确定重复位置
temp=pop(x2,crosspoint
(1)+zhi);
pop(x1,j)=temp;
end
end
%检查x1的右边的重复性并得到x1的右边
forj=crosspoint
(2)+1:
t-1
whilefind(pop(x1,crosspoint
(1)+1:
crosspoint
(2))==pop(x1,j))
zhi=find(pop(x1,crosspoint
(1)+1:
crosspoint
(2))==pop(x1,j));%确定重复的位置
temp=pop(x2,crosspoint
(1)+zhi);
pop(x1,j)=temp;
end
end
%检查x2左边的重复性并得到x2的左边
forj=1:
crosspoint
(1)
whilefind(pop(x2,crosspoint
(1)+1:
crosspoint
(2))==pop(x2,j))
zhi=find(pop(x2,crosspoint
(1)+1:
crosspoint
(2))==pop(x2,j));%确定重复位置
temp=pop(x1,crosspoint
(1)+zhi);
pop(x2,j)=temp;
end
end
%检查x2的右边的重复性并得到x2的右边
forj=crosspoint
(2)+1:
t-1
whilefind(pop(x2,crosspoint
(1)+1:
crosspoint
(2))==pop(x2,j))
zhi=find(pop(x2,crosspoint
(1)+1:
crosspoint
(2))==pop(x2,j));%确定重复的位置
temp=pop(x1,crosspoint
(1)+zhi);
pop(x2,j)=temp;
end
end
end
%生成的新的种群与交叉前进行比较,并取两者最优
[pop]=distance(pop);
fori=1:
s
ifpop_1(i,t)pop(i,:
)=pop_1(i,:
);
end
end
5变异函数
function[pop]=mutate(pop)
[s,t]=size(pop);
pop_1=pop;
fori=1:
2:
s
m=randperm(t-3)+1;
%随机取两个点
mutatepoint
(1)=min(m
(1),m
(2));
mutatepoint
(2)=max(m
(1),m
(2));
%用倒置变异的方法倒置两个点中间部分的位置
mutate=round((mutatepoint
(2)-mutatepoint
(1))/2-0.5);
forj=1:
mutate
zhong=pop(i,mutatepoint
(1)+j);
pop(i,mutatepoint
(1)+j)=pop(i,mutatepoint
(2)-j);
pop(i,mutatepoint
(2)-j)=zhong;
end
end
[pop]=distance(pop);%生成的新的种群与变异前比较,并取两者最优
fori=1:
s
ifpop_1(i,t)pop(i,:
)=pop_1(i,:
);
end
end
用上面的贪婪算法在matlab里运算的结果如下:
30个城市的初始路线和优化后的路线如下:
从上面的结果可以很明显的发现用遗传算法得到的结果远比用贪婪算法解得的好。
3、上面的算法改进的方向
1对于TSP,好的路径中城市一般都和其临近城市相连接,很少出现直接同较远城市连接的情况。
故而可以采用贪婪法生成初始种群:
以每一城市为起点,选择比较临近城市作为下站,然后将固定的两城市经过移位操作移动到编码末尾,这样以提高初始种群质量,使搜索的复杂度降低。
2、采用精英保留策略,把当前代中适应度最好的个体保留到下一代群体,而不被交叉变异算法破坏掉,从而保证遗传算法的全局收敛性,而且根据精英个体可能产生适应度更高新个体。