遗传算法求解TSP问题

1、TSP问题

1.1 TSP问题定义

旅行商问题(Traveling Salesman Problem,TSP)称之为货担郎问题,TSP问题是一个经典组合优化的NP完全问题,组合优化问题是对存在组合排序或者搭配优化问题的一个概括,也是现实诸多领域相似问题的简化形式。

1.2 TSP问题解法

传统精确算法:穷举法,动态规划
近似处理算法:贪心算法,改良圈算法,双生成树算法
智能算法:模拟退火,粒子群算法,蚁群算法,遗传算法等

2、遗传算法

2.1 遗传算法简介

遗传算法的实质是通过群体搜索技术,根据适者生存的原则逐代进化,最终得到最优解或准最优解。它必须做以下操作:初始群体的产生、求每一个体的适应度、根据适者生存的原则选择优良个体、被选出的优良个体两两配对,通过随机交叉其染色体的基因并随机变异某些染色体的基因生成下一代群体,按此方法使群体逐代进化,直到满足进化终止条件。

2.2 实现方法

  1. 根据具体问题确定可行解域,确定一种编码方法,能用数值串或字符串表示可行解域的每一解。
  2. 对每一解应有一个度量好坏的依据,它用一函数表示,叫做适应度函数,一般由目标函数构成。
  3. 确定进化参数群体规模、交叉概率、变异概率、进化终止条件。

3、实例分析

3.1 案例导入

我方有一个基地,经度和纬度为(70,40)。假设我方飞机的速度为1000km/h。我方派一架飞机从基地出发,侦察完所有目标,再返回原来的基地。在每一目标点的侦察时间不计,求该架飞机所花费的时间(假设我方飞机巡航时间可以充分长)。已知100个目标的经度、纬度如下表所列。
遗传算法求解TSP问题_第1张图片
遗传算法求解TSP问题_第2张图片
遗传算法求解TSP问题_第3张图片
解:
遗传算法求解TSP问题_第4张图片

遗传算法求解TSP问题_第5张图片

3.2 模型及算法

求解的遗传算法的参数设定如下:
种群大小M=50;最大代数G=100;
交叉率pc=1,交叉概率为1能保证种群的充分进化;
变异概率pm=0.1,一般而言,变异发生的可能性较小。

  1. 编码策略遗传算法求解TSP问题_第6张图片

  2. 初始种群
    遗传算法求解TSP问题_第7张图片

  3. 目标函数
    遗传算法求解TSP问题_第8张图片

  4. 交叉操作
    遗传算法求解TSP问题_第9张图片

  5. 变异操作遗传算法求解TSP问题_第10张图片

  6. 选择
    遗传算法求解TSP问题_第11张图片

3.3 算法流程图

遗传算法求解TSP问题_第12张图片

4、效果及代码展示

4.1 结果:

最短距离:3.9365e+04 km 最短时间:39.4h
巡航路径:
遗传算法求解TSP问题_第13张图片

4.2代码(MATLAB语言)

clc,clear
sj0=load('sj.txt');       %加载100个目标的数据
x=sj0(:,1:2:8);
x=x(:);
y=sj0(:,2:2:8); 
y=y(:);
sj=[x y]; 
d1=[70,40]; 
sj=[d1;sj;d1];  %102个点,己方基地编号为1,中间为100个目标,第102个为己方基地
sj2=sj;
sj=sj*pi/180;  %单位化成弧度
d=zeros(102); %距离矩阵d的初始值
for i=1:101
  for j=i+1:102
  d(i,j)=6370*acos(cos(sj(i,1)-sj(j,1))*cos(sj(i,2))*cos(sj(j,2))+sin(sj(i,2))*sin(sj(j,2)));
  end
end
d=d+d'; 
w=50;
g=100; %w为种群的个数,g为进化的代数
rand('state',sum(clock)); %初始化随机数发生器
for k=1:w  %通过改良圈算法选取初始种群
    c=randperm(100); %产生1...100的一个全排列  
    c1=[1,c+1,102]; %生成初始解
    for t=1:102 %该层循环是修改圈 
        flag=0; %修改圈退出标志
    for m=1:100
      for n=m+2:101
        if d(c1(m),c1(n))+d(c1(m+1),c1(n+1))<d(c1(m),c1(m+1))+d(c1(n),c1(n+1))
           c1(m+1:n)=c1(n:-1:m+1);  flag=1; %修改圈
        end
      end
    end
   if flag==0
      J(k,c1)=1:102;
       break %记录下较好的解并退出当前层循环
   end
   end
end
J(:,1)=0; J=J/102; %把整数序列转换成[0,1]区间上的实数,即转换成染色体编码
for k=1:g  %该层循环进行遗传算法的操作 
    A=J;  %交配产生子代B的初始染色体
    c=randperm(w); %产生下面交叉操作的染色体对 
  for i=1:2:w  
        F=2+floor(100*rand(1));%产生交叉操作的地址
        temp=A(c(i),[F:102]); %中间变量的保存值
        A(c(i),[F:102])=A(c(i+1),[F:102]); %交叉操作
        A(c(i+1),F:102)=temp;  
    end
    by=[];  %为了防止下面产生空地址,这里先初始化
    while ~length(by)
        by=find(rand(1,w)<0.1); %产生变异操作的地址
    end
    B=A(by,:); %产生变异操作的初始染色体
    for j=1:length(by)
         bw=sort(2+floor(100*rand(1,3)));  %产生变异操作的3个地址
        B(j,:)=B(j,[1:bw(1)-1,bw(2)+1:bw(3),bw(1):bw(2),bw(3)+1:102]); %交换位置
    end
     G=[J;A;B];%父代和子代种群合在一起
     [SG,ind1]=sort(G,2); %把染色体翻译成1...,102的序列ind1  按行排序
      num=size(G,1);  %计算G的行数
      long=zeros(1,num); %路径长度的初始值
      for j=1:num
         for i=1:101
            long(j)=long(j)+d(ind1(j,i),ind1(j,i+1)); %计算每条路径长度
         end
      end
      [slong,ind2]=sort(long); %对路径长度按照从小到大排序
       J=G(ind2(1:w),:); %精选前w个较短的路径对应的染色体
end
path=ind1(ind2(1),:),flong=slong(1) %解的路径及路径长度
xx=sj2(path,1);
yy=sj2(path,2);
plot(xx,yy,'-*') %画出路径
title('巡航路径示意图');
for i=1:102
    xu(1,i)=i;
end
max_text = num2str(xu);  %数字转字符
max_text = deblank(max_text);  %去除字符串首尾空格
xuhao = regexp(max_text, '\s+', 'split');  %分割字符串
text(xx+1,yy-1,xuhao)
xlabel('经度');
ylabel('纬度');
grid on 

sj.txt放出来给大家看一下,会对求距离矩阵有所帮助。
遗传算法求解TSP问题_第14张图片

参考书:《数学建模算法及应用》司守奎

司老师书上的程序在画路径上面有点失误,本文已经改正了,并把路径标记做上去了。希望对大家有所帮助

你可能感兴趣的:(数学建模)