【国赛培训】蚁群算法

时间:2019.8.12
老师:祁永强
内容:蚁群算法基本原理
个性:“无中生有,自圆其说”,戴准帽子(套框架),优化算法必须能用matlab仿真,狠劲,炼狱式成长,书由厚到薄(按页)由薄到厚(),撕书式成长,佯装努力结果是没有差别的,为人师在于唤人醒,“日锯其半,万日不竭”,20页最佳

感想:从原理上了解了蚁群算法,所找的一份ACATSP代码成功复现,并理解了全过程。唯独在下一个访问地点的概率计算与选择上稍有存疑,写在了最后。欢迎交流探讨观点,e-mail:03170908@cumt.edu.cn

1.概述概念

起源:意大利M.Dorigo等,通过模拟自然界蚂蚁搜索路径的行为,提出的新型模拟进化算法。
原理:蚂蚁在运动过程中,能感知信息素,指导自己的运动方向(正反馈)。信息素越多越好,为什么,因为初始时,信息素越多说明往返越多(同样时间时),即路径最短。
核心:信息素+正反馈(所有群体算法的核心)
适用:求解TSP问题、分配问题、job-shop调度问题
优势:求解复杂优化问题(特别是离散优化问题)
比较优势:与大多数基于梯度的优化算法想比
1.无集中控制约束,不会因个别的故障影响整个问题的求解,保证鲁棒性
2.非直接信息交换,确保系统的扩展性
3.并行分布式
4.对问题定义的连续性无特殊要求
5.算法实现简单

2.蚁群算法基本思想

信息素要按一定比率挥发(避免局部最优)

每只蚂蚁的一部转移概率由图中的每条边上的两类参数决定:
1.信息素值也称信息素痕迹
2.可见度,即先验值

信息素的更新方式:
1 挥发 :所有路径上的信息素以一定比率进行减少
2 增强 :给蚂蚁评价,好蚂蚁加强

基于图的蚁群算法(GBAS)

3.基本蚁群算法

P_{ij}^k(t)表示t时刻蚂蚁k从城市i到城市j的转移概率,计算公式如下:

P^k(i,j)=\left\{ \begin{aligned} &\frac {\tau[(i,j)]^\alpha{\cdot}{\eta}[(i,j)]^\beta}{\sum \limits_{s\in{J}_k({i})}\tau[(i,s)]^\alpha{\cdot}{\eta}[(i,s)]^\beta} & if\ j\in{J}_k(i) \\ &0& {otherwise} \end{aligned}\tag{1} \right.

{\tau[(i,j)]^\alpha} :信息素
{{\eta}[(i,j)]^\beta} : 信息素增强(启发式的体现,和距离负相关)
\alpha\beta : 推荐1,5
信息素挥发系数\rho:推荐0.5
信息素增强\delta=Q/L,Q推荐1,L表示距离长度

规模和终止条件:
1 给定终止轮数
2 最优解了连续次相同
3 给定目标值

4.【进阶】收敛

马于尔科夫收敛定义,依概率收敛于1
证明收敛,才能说算法是可以实现的
蚁群算法分支:MAX-MIN蚂蚁,精英蚂蚁,蚁周算法,蚁密算法,蚁量算法

5.代码实例

蚁群算法针对TSP应用(超详细分析)
ant-colony-algorithm-for-TSP(MATLAB可直接运行代码)
原始出处:解放军信息工程大学老师
下面代码注释为本人针对上面的资料进行学习之后添加,欢迎交流。转移矩阵部分务必参考上面的公式

function [R_best,L_best,L_ave,Shortest_Route,Shortest_Length]=ACATSP(C,NC_max,m,Alpha,Beta,Rho,Q)
%%-------------------------------------------------------------------------
%% 主要符号说明
%% C n个城市的坐标,n×2的矩阵
%% NC_max 最大迭代次数
%% m 蚂蚁个数
%% Alpha 表征信息素重要程度的参数     1
%% Beta 表征启发式因子重要程度的参数  5
%% Rho 信息素蒸发系数                0.5
%% Q 信息素增加强度系数               1
%% R_best 各代最佳路线
%% L_best 各代最佳路线的长度
%%=========================================================================
 
%%第一步:变量初始化
n=size(C,1);%n表示问题的规模(城市个数)
D=zeros(n,n);%D表示完全图的赋权邻接矩阵
for i=1:n
    for j=1:n
        if i~=j
            D(i,j)=((C(i,1)-C(j,1))^2+(C(i,2)-C(j,2))^2)^0.5;
        else
            D(i,j)=eps;      %i=j时不计算,应该为0,但后面的启发因子要取倒数,用eps(浮点相对精度)表示
        end
        D(j,i)=D(i,j);   %对称矩阵
    end
end
Eta=1./D;          %Eta为启发因子,这里设为距离的倒数
Tau=ones(n,n);     %Tau为信息素矩阵
Tabu=zeros(m,n);   %存储并记录路径的生成
NC=1;               %迭代计数器,记录迭代次数
R_best=zeros(NC_max,n);       %各代最佳路线
L_best=inf.*ones(NC_max,1);   %各代最佳路线的长度,先赋值inf无穷大,后面更新
L_ave=zeros(NC_max,1);        %各代路线的平均长度
 
while NC<=NC_max        %停止条件之一:达到最大迭代次数,停止
    %%第二步:将m只蚂蚁放到n个城市上,全放完需要[m/n]轮
        Randpos=[];   %#随机存取,此处初始起点,可以固定设置
    for i=1:(ceil(m/n))
        Randpos=[Randpos,randperm(n)];%randperm产生1到n的随机序列
    end %使用这种随机分配方法可以保证初始去往各个城市的蚂蚁数量均匀,比全部随机要更好
    Tabu(:,1)=(Randpos(1,1:m))';    %取出前m个,赋给Tabu路径矩阵,即给出了m只蚂蚁的初始去往地点

    %%第三步:m只蚂蚁按概率函数选择下一座城市,对应公式中的转移矩阵
    for j=2:n     %所在城市不计算,j表示即将访问的下一座城市
        for i=1:m    
            visited=Tabu(i,1:(j-1)); %记录已访问的城市,避免重复访问
            J=zeros(1,(n-j+1));       %待访问的城市,总数n-j+1
            P=J;                      %待访问城市的选择概率分布
            Jc=1;                     %待访问的城市个数,初始为1(用于修改矩阵J时做下标)
            for k=1:n
                if isempty(find(visited==k, 1))%这里改善了寻找的性能,只要能找到一个等于K就非空
                    J(Jc)=k;
                    Jc=Jc+1;           %待访问的城市个数自加1
                end
            end                         %循环完成后将更新完待访问矩阵J
            %下面计算从当前城市visted(end)转移到待选城市k的概率分布,参照公式的分子
            %信息素的作用也仅体现在这里,计算转移矩阵概率
            for k=1:length(J)
                P(k)=(Tau(visited(end),J(k))^Alpha)*(Eta(visited(end),J(k))^Beta);
            end
            P=P/(sum(P));
            %按概率原则选取下一个城市
            Pcum=cumsum(P);     %cumsum,元素向上(或向前)累加求和
            Select=find(Pcum>=rand); %若计算的概率大于rand的就可以选择这条路线
            to_visit=J(Select(1));   %选择可选城市列表Select中的第一个作为将访问的下一个
            Tabu(i,j)=to_visit;
        end
    end

    if NC>=2
        Tabu(1,:)=R_best(NC-1,:);  
        %NC=2开始,第一只蚂蚁路径使用上一轮的最佳路线,参与下面的信息素更新
        %#所以其实上面i=1那只蚂蚁的路径推演是没必要的,可以用if去优化掉
    end

    %%第四步:记录本次迭代最佳路线
    L=zeros(m,1);     %开始距离为0,m*1的列向量
    for i=1:m
        R=Tabu(i,:);
        for j=1:(n-1)
            L(i)=L(i)+D(R(j),R(j+1));    %原距离加上第j个城市到第j+1个城市的距离
        end
        L(i)=L(i)+D(R(1),R(n));      %#一轮下来后走过的距离,此处假定了最终回到起点,可以修改
    end
    L_best(NC)=min(L);           %最佳距离取最小
    pos=find(L==L_best(NC));
    R_best(NC,:)=Tabu(pos(1),:); %此轮迭代后的最佳路线
    L_ave(NC)=mean(L);           %此轮迭代后的平均距离
    NC=NC+1;                      %迭代继续


    %%第五步:更新信息素
    Delta_Tau=zeros(n,n);        %开始时信息素增量为n*n的0矩阵
    for i=1:m
        for j=1:(n-1)
            Delta_Tau(Tabu(i,j),Tabu(i,j+1))=Delta_Tau(Tabu(i,j),Tabu(i,j+1))+Q/L(i);          
        %此次循环在路径(i,j)上的信息素增量
        end
            Delta_Tau(Tabu(i,n),Tabu(i,1))=Delta_Tau(Tabu(i,n),Tabu(i,1))+Q/L(i);
        %#此次循环在从n会到起点上的信息素增量,对应要求,单程可删去
    end
    Tau=(1-Rho).*Tau+Delta_Tau; %考虑信息素挥发掉Rho,更新后的信息素,加上Delta
    %%第六步:路径表清零
    Tabu=zeros(m,n);             %%直到最大迭代次数
end


%%第七步:输出结果
Pos=find(L_best==min(L_best));  %找到最佳路径(非0为真)
Shortest_Route=R_best(Pos(1),:) %最大迭代次数后最佳路径
Shortest_Length=L_best(Pos(1))  %最大迭代次数后最短距离

subplot(1,2,1)                  %绘制第一个子图形
DrawRoute(C,Shortest_Route)     %画路线图的子函数
subplot(1,2,2)                  %绘制第二个子图形
plot(L_best)
hold on                         %保持图形
plot(L_ave,'r')
title('平均距离和最短距离')     %标题

function DrawRoute(C,R)
%%=========================================================================
%% DrawRoute.m
%% 画路线图的子函数
%% C Coordinate 节点坐标,由一个N×2的矩阵存储
%% R Route 路线
%%=========================================================================
N=length(R);
scatter(C(:,1),C(:,2));
hold on
plot([C(R(1),1),C(R(N),1)],[C(R(1),2),C(R(N),2)],'g')%#这里绘制了起点到终点的直连线,非循环路径可删去
hold on

for i=2:N
    plot([C(R(i-1),1),C(R(i),1)],[C(R(i-1),2),C(R(i),2)],'g')
    hold on
end
title('旅行商问题优化结果 ')

关于代码的一点说明,结合蚁群算法的原理和主要的转移概率公式,理解代码不难。上面的代码是针对完全图的回路所计算的,其中有多处可以加以改动,在注释号之后加上了#号,体现我的一点个人见解。

此外,一个困惑:上面在计算待访问城市之后,关于下一个城市的选择,使用的是向前累加,取判断大于某个随机值rand,这样体现的是轮盘赌算法吗?

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容