【TSP】基于matlab禁忌搜索算法求解31城市旅行商问题【含Matlab源码 1143期】

时间:2021-07-23 17:44:31   收藏:0   阅读:0

一、简介

1 局部领域搜索
又称爬山启发式算法,从当前的节点开始,和周围的邻居节点的值进行比较。如果当前节点是最大的,那么返回当前节点,作为最大值(即山峰最高点);反之就用最高的邻居节点替换当前节点,从而实现向山峰的高处攀爬的目的。它是禁忌搜索的基础,TS算法是在其上改进而来。

1.1 优点:
容易理解,容易实现,具有较强的通用性;
局部开发能力强,收敛速度很快。

1.2 缺点:
全局开发能力弱,只能搜索到局部最优解;
搜索结果完全依赖于初始解和邻域的映射关系。
通过针对爬山法的分析,提出了TS搜索算法:
改进1:接受劣解。
改进2:引入禁忌表。
改进3:引入长期表和中期表。

2 TS算法的特点:
2.1 基本思想——避免在搜索过程中的循环
2.2 只进不退的原则,通过禁忌表实现
2.3 不以局部最优作为停止准则
2.4 邻域选优的规则模拟了人类的记忆功能

TS算法构成要素:
(1)编码方式
将不相同的n件物品分为m组,可以用的编码:
a、带分隔符的顺序编码
以自然数1~n分别代表n件物品,n个数加上 m-1个分割符号混编在一起,随机排列。 如:1-3-4-0-2-6-7-5-0-8-9
b、自然数编码
编码的每一位分别代表一件物品,而每一位的值代表该物品所在的分组。
如:1-2-1-1-2-2-2-3-3
(2)初始解的获取
可以随机给出初始解,也可以事先使用其他启发式等算法给出一个较好的初始解。
(3)移动邻域
移动是从当前解产生新解的途径,例如上述问题中用移动s产生新解s(x)。 从当前解可以进行的所有移动构成邻域,也可以理解为从当前解经过“一步”可以到达的区域。
(4)禁忌表
禁忌表的作用:防止搜索出现循环?
(1)记录前若干步走过的点、方向或目标值,禁止返回
(2)表是动态更新的
(3)表的长度称为Tabu-Size

禁忌表的主要指标(两项指标)
禁忌对象:禁忌表中被禁的那些变化元素
禁忌长度:禁忌的步数

禁忌对象(三种变化)
以状态本身或者状态的变化作为禁忌对象
以状态分量以及分量的变化作为禁忌对象
采用类似的等高线做法,以目标值变化作为禁忌对象

禁忌长度:可以是一个固定的常数(T=c),也可以是动态变化的,可按照某种规则或公式在区间内变化。
禁忌长度过短,一旦陷入局部最优点,出现循环无法跳出;
禁忌长度过长,候选解全部被禁忌,造成计算时间较大,也可能造成计算无法继续下去。

(5)渴望水平函数

A(x,s)一般为历史上曾经达到的最好目标值,若有C(s(x))<A(x,s)则S(x)是不受T表限制。即使s(x)∈T,仍可取 x=s(x)。A(x,s)称为渴望水平函数。

(6)停止准则
(1)给定最大迭代步数(最常用 )
(2)设定某个对象的最大禁忌频率。
(3)设定适配值的偏离阈值。

二、源代码

%%%%%%%%%%%%%%%%%%%%禁忌搜索算法解决TSP问题%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%初始化%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clear all;                        %清除所有变量
close all;                        %清图 
clc;                              %清屏
C = [1304 2312;3639 1315;4177 2244;3712 1399;3488 1535;3326 1556;...
    3238 1229;4196 1044;4312  790;4386  570;3007 1970;2562 1756;...
    2788 1491;2381 1676;1332  695;3715 1678;3918 2179;4061 2370;...
    3780 2212;3676 2578;4029 2838;4263 2931;3429 1908;3507 2376;...
    3394 2643;3439 3201;2935 3240;3140 3550;2545 2357;2778 2826;...
    2370 2975];                   %31个省会城市坐标
N=size(C,1);                      %TSP问题的规模,即城市数目
D=zeros(N);                       %任意两个城市距离间隔矩阵
%%%%%%%%%%%%%%%%%%%%%求任意两个城市距离间隔矩阵%%%%%%%%%%%%%%%%%%%%%
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
Tabu=zeros(N);                      %禁忌表
TabuL=round((N*(N-1)/2)^0.5);       %禁忌长度
Ca=200;                             %候选集的个数(全部领域解个数)
CaNum=zeros(Ca,N);                  %候选解集合
S0=randperm(N);                     %随机产生初始解
bestsofar=S0;                       %当前最佳解
BestL=Inf;                          %当前最佳解距离
figure(1);
p=1;
Gmax=1000;                          %最大迭代次数   
%%%%%%%%%%%%%%%%%%%%%%%%%%%禁忌搜索循环%%%%%%%%%%%%%%%%%%%%%%%%%%
while p<Gmax
    ALong(p)=func1(D,S0);            %当前解适配值
    %%%%%%%%%%%%%%%%%%%%%%%%%%%交换城市%%%%%%%%%%%%%%%%%%%%%%%%%%
    i=1;
    A=zeros(Ca,2);                   %解中交换的城市矩阵
    %%%%%%%%%%%%%%%%%求领域解中交换的城市矩阵%%%%%%%%%%%%%%%%%%%%%
    while i<=Ca
        M=N*rand(1,2);
        M=ceil(M);         
        if M(1)~=M(2)
            A(i,1)=max(M(1),M(2));
            A(i,2)=min(M(1),M(2));
            if i==1
                isa=0;
            else
                for j=1:i-1
                    if A(i,1)==A(j,1) && A(i,2)==A(j,2)
                        isa=1;
                        break;
                    else
                        isa=0;
                    end
                end
            end
            if ~isa
                i=i+1;
            else
            end
        else
        end
    end
    %%%%%%%%%%%%%%%%%%%%%%%%%产生领域解%%%%%%%%%%%%%%%%%%%%%%%%%%
    %%%%%%%%%%%%%%%%保留前BestCaNum个最好候选解%%%%%%%%%%%%%%%%%%%
    BestCaNum=Ca/2;
    BestCa=Inf*ones(BestCaNum,4);
    F=zeros(1,Ca);
    for i=1:Ca
        CaNum(i,:)=S0;
        CaNum(i,[A(i,2),A(i,1)])=S0([A(i,1),A(i,2)]);
        F(i)=func1(D,CaNum(i,:));
        if i<=BestCaNum
            BestCa(i,2)=F(i);
            BestCa(i,1)=i;
            BestCa(i,3)=S0(A(i,1));
            BestCa(i,4)=S0(A(i,2));
        else
            for j=1:BestCaNum
                if F(i)<BestCa(j,2)
                    BestCa(j,2)=F(i);
                    BestCa(j,1)=i;
                    BestCa(j,3)=S0(A(i,1));
                    BestCa(j,4)=S0(A(i,2));
                    break;
                end
            end
        end
    end
   
    %%%%%%%%%%%%%%%%%%%%%%%%藐视准则%%%%%%%%%%%%%%%%%%%%%%%%%%%
    if BestCa(1,2)<BestL
        BestL=BestCa(1,2);
        S0=CaNum(BestCa(1,1),:);
        bestsofar=S0;
        for m=1:N
            for n=1:N
                if Tabu(m,n)~=0
                    Tabu(m,n)=Tabu(m,n)-1;    
                    %更新禁忌表
                end
            end
        end
        Tabu(BestCa(1,3),BestCa(1,4))=TabuL;
        %更新禁忌表
    else
        for  i=1:BestCaNum
            if  Tabu(BestCa(i,3),BestCa(i,4))==0
                S0=CaNum(BestCa(i,1),:);
                for m=1:N
                    for n=1:N
                        if Tabu(m,n)~=0
                            Tabu(m,n)=Tabu(m,n)-1;
                            %更新禁忌表
                        end
                    end
                end
                Tabu(BestCa(i,3),BestCa(i,4))=TabuL;
                %更新禁忌表
                break;
            end
        end
    end

三、运行结果

技术图片

四、备注

版本:2014a

评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!