禁忌搜索算法

禁忌搜索算法(Tabu Search or Taboo Search,TS)是一种迭代搜索算法,靠记忆来引导算法的搜索过程。

1 算法原理

主要包含2个方面:局部领域搜索、禁忌搜索,在领域搜索的基础上,通过禁忌准则来避免重复搜索,通过藐视准则来赦免一些被禁忌的优良状态,以实现全局优化。

1.1 局部领域搜索

局部领域搜索是基于贪婪准则持续在当前的领域中进行搜索,找到局部最优解。大致方法是选定一个可行解x^{0},并产生领域解集x^{neighour},逐一比较x^{0}x^{neighbour}的目标值,选出最优解更新x^{0},直到找不到更优为止,记为x^{best}

1.2 禁忌搜索

在局部搜索的基础上,建立禁忌表,记录近几次迭代过程中的移动(所谓移动,即产生领域解的变化),凡是处于禁忌表中的移动是不允许的,来避免算法重复访问最近几次已经访问过的解,从而防止陷入局部最优解。注意禁忌表记录可能是解,也可以是产生领域解的移动或变化。

1.3 藐视准则

藐视准则是为了不错过最优解。

一般来说,通过设置存在时间或禁忌表长度来实现特赦以前出现过的最优解相关移动。

2 算法流程

在此之前需要对解进行区分,当前解x^{now},领域解x^{neighour}(领域中最优的解),候选解x^{candidate},全局最优解x^{best}(也叫bestsofar)。以旅行商问题为例,当x^{now}经过移动(随机交换2个城市的访问顺序)会产生x^{neighour}x^{neighour}x^{now}好,x^{neighour}就会升级成x^{candidate}

 步骤1   生成初始解x^{now}和置禁忌表tabu为空 

步骤2    从当前解产生若干领域解x^{neighour},并确定若干候选解x^{candidate}

步骤3    如果x^{candidate}优于x^{now},则更新x^{now}=x^{candidate}和将x^{candidate}对应的禁忌对象加入禁忌表tabu,否则基于禁忌表tabu从x^{candidate}中选出次优解,更新x^{now}和tabu

步骤4    更新x^{best}=x^{now}和基于藐视准则更新tabu

步骤5    判断结束或继续步骤2-5

3 关键参数

初始解

适配值函数

领域结构

从一个解通过“移动”产生另一个解的途径,常用方法互换、插值、逆序

禁忌对象

即放入禁忌表中的变化元素,可以是状态本身(解本身)或状态分量(领域结构中的移动

候选解选择

切记要选择充分,保证在领域内充分搜索

禁忌表

一般是先进先出的队列

禁忌长度

禁忌对象在禁忌表中的任期,可以是常量也可以是变量

藐视准则

搜索策略

终止准则

4 仿真实例

旅行商问题(TSP问题)

假设1个旅行商要对31个省会城市进行拜访,要求距离最短,不能重复拜访,且最终要回到出发城市。

31个城市坐标:

  [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];

代码

close all;
clear 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];
n=size(C,1);
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=21;
Ca=200;
canum=zeros(Ca,n);
s0=randperm(n);
bestsofar=s0;
bestlen=func1(D,bestsofar,n);
g=1;
G=1000;
%%%%%算法循环
while g<G
    %%%%%产生领域解canum,产生200个,只取前100
    %%%%%确保交换不重复
    A=zeros(Ca,2);
    p=1;
    while p<=Ca
        A(p,:)=ceil(rand(1,2)*n);
        while A(p,1)==A(p,2)   
            A(p,:)=ceil(rand(1,2)*n);
        end
        temp1=min(A(p,1),A(p,2));
        A(p,2)=max(A(p,1),A(p,2));
        A(p,1)=temp1;
        if p==1
            k=0;%查重
        else
            for j=1:p-1
                if A(p,1)==A(j,1) && A(p,2)==A(j,2)
                    k=1;
                    break;
                else
                    k=0;
                end
            end
        end  
        if k==0
            p=p+1;
        end
    end
    for i=1:Ca
        canum(i,:)=s0;
        canum(i,[A(i,1),A(i,2)])=s0([A(i,2),A(i,1)]);
        canumlen(i)=func1(D,canum(i,:),n);
    end
    [canumlen,index]=sort(canumlen);
    canum=canum(index,:);
    A=A(index,:);
    bestca=canum(1:Ca/2,:);
    %%%%%藐视准则
    if canumlen(1) < bestlen    %领域解更优
        bestlen=canumlen(1);
        s0=bestca(1,:);
        bestsofar=s0;
        for i=1:n
            for j=1:n
                if tabu(i,j)~=0
                    tabu(i,j)=tabu(i,j)-1;
                end
            end
        end
        tabu(A(1,1),A(1,2))=tabuL;
    else
        for k=1:Ca/2
            if tabu(A(k,1),A(k,2))==0
                s0=bestca(k,:);
                for i=1:n
                    for j=1:n
                        if tabu(i,j)~=0
                            tabu(i,j)=tabu(i,j)-1;
                        end
                    end
                end
                tabu(A(k,1),A(k,2))=tabuL;
                break;
            end
        end
    end
    arrbestlen(g)=bestlen;
    g=g+1;    
end
%%%%%画图
for i=1:n-1
    plot([C(bestsofar(i),1),C(bestsofar(i+1),1)],[C(bestsofar(i),2),C(bestsofar(i+1),2)],'o-');
    hold on;
end
plot([C(bestsofar(n),1),C(bestsofar(1),1)],[C(bestsofar(n),2),C(bestsofar(1),2)],'ro-');
title([num2str(g),'次最短距离:',num2str(bestlen)]);
hold off;
%%%%%输出优化结果
figure;
plot(arrbestlen);
xlabel('迭代次数');
ylabel('目标函数值');
title('适应度进化曲线');
%%%%%路径长度函数
function result = func1(D,f,N)
    len=D(f(1),f(N));
    for j=2:N
        len=D(f(j),f(j-1))+len;
    end
    result=len;
end

结果

  • 6
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NPC_0001

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值