旅行商问题--蚁群优化算法求解(matlab实现)

2023-05-16

今天给大家分享一下matlab实现蚁群优化算法,解决旅行商问题。
在上一篇博客中对蚁群优化算法做了较为详细的介绍,有需要的小伙伴可以看一下
https://blog.csdn.net/HuangChen666/article/details/115827732

1. 初始化城市信息
     1.1 随机获取城市坐标
     1.2 求出城市之间距离
2. 初始化参数
3. 迭代寻找最佳路径
     3.1 随机产生蚂蚁起点城市
     3.2 迭代计算选择城市概率
     3.3 轮盘赌选出下一个城市
     3.4 更新最短路径
     3.5 更新信息素
4. 得出结果
5. 全部代码

1. 初始化城市信息

第一步初始化城市的信息,例如数量、坐标、距离等等。

1.1 随机获取城市坐标

首先随机产生n个城市的坐标,使用randperm(100,n)产生n个城市的横坐标和纵坐标,randperm(100,n)表示随机产生n个1~100(包含1和100)的整数,然后使用plot函数进行描点,例如:

在这里插入图片描述

1.2 求出城市之间距离

计算各个城市之间的距离,存放如一个n*n的矩阵中,由于距离在后面的公式要放在分母上,所以城市i到城市i的距离不能是0,这里设置成eps,即一个非常小的数。

在这里插入图片描述
对角线上是城市 i 到 i 的距离,用一个很小的数代替。

2. 初始化参数

迭代寻找最佳路径之前,对一些必要的参数进行初始化,比如信息素重要程度因子、启发函数重要程度因子、信息素挥发因子、启发函数等等。

在这里插入图片描述

3. 迭代寻找最佳路径

准备工作做好后,下面就是迭代寻找最佳路径,对m只蚂蚁和n个城市进行循环,核心是蚁群优化算法的两个公式,一个是计算选择城市概率的,另一个是更新信息素的。

3.1 随机产生蚂蚁起点城市

首选将蚂蚁随机放在n个城市上,当然这里并不是真的拿蚂蚁过来放,而是随机产生1~n的数字,即代表第 i 只蚂蚁的初始城市。

在这里插入图片描述

3.2 迭代计算选择城市概率

计算蚂蚁选择目前没有去过的城市的概率,需要事先去掉已经访问过的城市,计算选择城市概率公式如下:

在这里插入图片描述
在这里插入图片描述

3.3 轮盘赌选出下一个城市

求出蚂蚁选择其他未访问过的城市的选择概率后,并不能一味地就选择概率最大的那个,这样很容易陷入局部最优解,这样采用轮盘赌的方法进行选择,对轮盘赌不熟悉的同学可以借鉴下这个博客

https://blog.csdn.net/xuxinrk/article/details/80158786

3.4 更新最短路径

因为最终还是要求最短路径的嘛,到了这一步就是对上面选择完城市后的路径一一求和,得出每只蚂蚁在该次周游中的路径和(还要加上最后一个节点回到起点的距离)
***这里需要注意的是计算出本次的最短路径和上一次的最短路径相比不一定更小,结果得到的最短路径的收敛轨迹波动会特别大,比如下面这样

在这里插入图片描述

所以这里可以改进一下,基本思想是:如果本次周游中的最短路径大小比上一次的要大,则本次的最短路径大小改为和上一次一样,这样就不会出现后面迭代出比前面还要打的最短距离,这样处理会更符合人们的观念,更加合理,修改后如下所示

在这里插入图片描述

3.5 更新信息素

所有的蚂蚁周游后开始下一次周游,下一次周游前更新信息素,信息素=上一次的信息素*(1-挥发因子)+上一轮增加的信息素,路径上走的蚂蚁越多,信息素增加越多,相比信息素越浓。

在这里插入图片描述

4. 得出结果

根据上述步骤编写代码,以75只蚂蚁,30个城市为例,得到结果如下,最短路径路线图

在这里插入图片描述
下面是最短距离收敛曲线和平均距离收敛曲线

在这里插入图片描述
命令行输出结果

在这里插入图片描述

5. 全部代码

代码借鉴了两个视频,大家有兴趣有耐心可以看下,我觉得这两个讲的都不错,第二个视频有一个后记视频讲了关于调参的事情。

https://www.bilibili.com/video/BV1c4411W7zc
https://www.bilibili.com/video/BV1Z7411H78S?from=search&seid=14512389210209190890

clc;clear;
t0=clock;   %用于计时
%% 初始化城市信息
n=30;                    %定义城市个数
city=[(randperm(100,n))',(randperm(100,n))'];  %获取城市坐标
figure('name','蚁群优化算法');
plot(city(:,1),city(:,2),'o');  %描点
for i=1:n
    text(city(i,1)+0.5,city(i,2),num2str(i));       %标号
end
title('蚁群优化算法');
%设置横纵坐标范围
grid on     %网格线
hold on

%% 求出各个城市之间的距离
D=zeros(n,n);      %新建一个n*n的矩阵存放距离
for i=1:n
   for j=1:n
       if i~=j
           D(i,j)=sqrt(sum((city(i,:)-city(j,:)).^2));
       else
           D(i,j)=eps;     %设置成一个很小的数,但不能为0,因为后面分母中会用到
       end
   end
end

%% 初始化参数
m=75;                   %蚂蚁数量
alpha = 1;              %信息素重要程度因子
beta = 5;               %启发函数重要程度因子
rho = 0.2;              %信息素挥发因子
Q=10;                   %常系数
Eta = 1./D;             %启发函数(距离的倒数)
Tau = ones(n,n);        %信息素矩阵(初始时每条路上的信息素都设为1)
Table = zeros(m,n);     %路径记录表,记录m个蚂蚁走过的路径
iter = 1;               %迭代次数初值
iter_max = 100;         %最大迭代次数
Route_best = zeros(iter_max,n);     %各代最佳路径
Length_best = zeros(iter_max,1);    %各代最佳路径的长度
Length_ave = zeros(iter_max,1);     %各代路径的平均长度

%% 迭代寻找最佳路径
for iter=1:iter_max
    %随机产生蚂蚁的起点城市
    for i=1:m
       Table(i,1)=randperm(n,1);
    end
    citys_index=1:n;        %定义全部城市索引
    for i=1:m               %遍历所有蚂蚁
       for j=2:n            %遍历其他所有城市
           tabu=Table(i,1:(j-1));      %已访问城市(禁止访问表)
           allow=citys_index(~ismember(citys_index,tabu)); %除去已访问城市(待访问城市)
           P=allow;         %存放概率,定义成什么都可以,只要和allow长度一样
           %计算城市间的选择概率
           for k=1:length(allow)
               %tabu(end)代表该蚂蚁此刻所在城市,allow(k)代表该蚂蚁即将去向的城市
               P(k)=Tau(tabu(end),allow(k))^alpha*Eta(tabu(end),allow(k))^beta;
           end
           P=P/sum(P);      %得到最终去往其他城市的概率集合
           Pc=cumsum(P);    %累计概率
           %轮盘赌选择下一个城市
           target_index=find(Pc>=rand);     %从累计概率中找出大于随机值的情况
           target=allow(target_index(1));   %取出第一个即为轮盘赌的结果
           Table(i,j)=target;               %确定第i只蚂蚁去往的第j-1个城市 
       end
    end
    %每只蚂蚁周游一遍后计算每只蚂蚁的路径长度
    Length=zeros(m,1);
    for i=1:m
        for j=1:(n-1)
            Length(i)=Length(i)+D(Table(i,j),Table(i,j+1));
        end
        %最后加上最后一个点回到起点的距离
        Length(i)=Length(i)+D(Table(i,n),Table(i,1));
    end
    %% 计算最短路径距离及平均距离
    [min_length,min_index]=min(Length);     %取出最短路径及其下标
    if iter==1
        Length_best(iter)=min_length;           %保存此次最短路径距离
    else
        Length_best(iter)=min(Length_best(iter-1),min_length);  %选择本次和上次中最短路径较小的
    end
    Route_best(iter,:)=Table(min_index,:);  %保存此次最短路线路径
    Length_ave(iter)=mean(Length);          %保存此次路线距离平均值
    
    %% 更新信息素
    Tau_Ant=Q./Length;          %每条蚂蚁在路径上留下的信息素浓度
    Tau_Temp=zeros(n,n);
    for i=1:m
        for j=1:n-1
            %更新信息素
            Tau_Temp(Table(i,j),Table(i,j+1))=Tau_Temp(Table(i,j),Table(i,j+1))+Tau_Ant(i);
        end
        %最后更新最后一个节点到起点的信息素
        Tau_Temp(Table(i,n),Table(i,1))=Tau_Temp(Table(i,n),Table(i,1))+Tau_Ant(i);
    end
    Tau=(1-rho)*Tau+Tau_Temp;   %信息素挥发后再加上新增的信息素
    Table = zeros(m,n);     %清空路线,进行下一轮周游
end

%% 命令行窗口显示结果
[min_length,min_index]=min(Length_best);         %取出最短路径及其下标
Finnly_Route=Route_best(min_index,:);
last_time=etime(clock,t0);
disp(['最短距离为:' num2str(min_length)]);
disp(['最短路径为:' num2str(Finnly_Route)]);
disp(['运行时间:' num2str(last_time) '秒']);

%% 绘图
plot([city(Finnly_Route,1);city(Finnly_Route,1)],...
     [city(Finnly_Route,2);city(Finnly_Route,2)],'bo-');  %描点
text(city(Finnly_Route(1),1),city(Finnly_Route(1),2),'    起点');
text(city(Finnly_Route(end),1),city(Finnly_Route(end),2),'    终点');

figure(2);
subplot(1,2,1);     %显示在一行两列图像中的第一列
plot(Length_best);
xlabel('迭代次数');
ylabel('最短距离');
title('最短距离收敛曲线');

subplot(1,2,2);     %显示在一行两列图像中的第二列
plot(Length_ave);
xlabel('迭代次数');
ylabel('平均距离');
title('平均距离收敛曲线');
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

旅行商问题--蚁群优化算法求解(matlab实现) 的相关文章

  • MATLAB 中最有效的矩阵求逆

    在 MATLAB 中计算某个方阵 A 的逆矩阵时 使用 Ai inv A should be the same as Ai A 1 MATLAB 通常会通知我这不是最有效的求逆方法 那么什么是更有效率的呢 如果我有一个方程系统 可能会使用
  • 在另一列中添加具有特定条件的一列,如 excel 的 sumif

    我有一个像这样的矩阵 A 1 2 2 3 3 4 4 5 5 6 6 8 7 9 8 5 9 4 现在我想添加第二列 条件是如果 limit 0 interval 3 且 limit limit interval 或者换句话说 当第 1 列
  • 如何在 Matlab 中使用谷歌翻译?

    我正在编写一个程序 使用 Matlab 列出电影字幕文件中的所有唯一单词 现在我有一个独特的单词列表 我想将其翻译成我的语言并在观看电影之前了解其含义 有谁知道如何在 Matlab 中使用 Google Translate 以便完成我的脚本
  • 不等间隔时间序列的移动平均线

    我有一个证券交易所股票价格的数据集 时间 价格 但数据点之间的间隔并不相等 从 1 到 2 分钟不等 在这种情况下计算移动平均值的最佳实践是什么 如何在Matlab中实现呢 我倾向于认为 点的权重应该取决于自上一个点以来的最后时间间隔 Ma
  • 为什么旋转 3D 点云后顶点法线会翻转?

    我有两个人脸 3D 点云样本 蓝色点云表示目标面 红色点云表示模板 下图显示目标面和模板面在不同方向上对齐 目标面大致沿 x 轴 模板面大致沿 y 轴 Figure 1 The region around the nose is displ
  • 什么是 ANN 中的纪元以及它如何转换为 MATLAB 中的代码?

    我试图理解 并可视化 训练人工神经网络的时代到底是什么 我们有一个包含约 7000 个产品的训练集 其中有 10 个特征 输入 这些产品必须根据这 10 个输入分为 7 个类别 我们的 ANN 有 10 个输入 这些输入进入由 10 个神经
  • 使用 MATLAB 进行线路跟踪

    我有一个图像 我想将其转换为逻辑图像 包括线条为黑色 背景为白色 当然 可以使用阈值方法来实现这一点 但我不想使用这种方式来做到这一点 我想通过使用线路跟踪方法或类似的方法来检测它 这是关于视网膜血管检测的 我找到了一个article ht
  • MATLAB 特征函数

    我很好奇哪里可以找到完整的描述FEATURE功能 它接受哪些论点 没有找到文档 我只听说过memstats and getpid 还要别的吗 gt gt which feature built in undocumented 注意 更完整的
  • MATLAB 教程中的 SIFT 实现

    我正在寻找 MATLAB 中的一些基本 SIFT 实现 我需要从第一原则来写它 另外 我正在寻找一些可以解释程序中发生的事情的内容 Vedali 的代码和 David Lowe 的代码超出了我的理解范围 如果您是 Matlab 用户 您一定
  • 使用符号求解器仅求解某些变量

    我正在尝试在 MATLAB 中求解包含 3 个变量和 5 个常量的方程组 是否可以使用solve求解三个变量 同时保持常量为符号而不用数值替换它们 当您使用SOLVE http www mathworks com access helpde
  • matlab中的正则逻辑回归代码

    我正在尝试正则化 LR 在 matlab 中使用以下公式很简单 成本函数 J theta 1 m sum y i log h x i 1 y i log 1 h x i lambda 2 m sum theta j 梯度 J theta t
  • 检测植物图片中的所有分支

    我想知道有什么可以检测下图中的所有绿色树枝 目前我开始应用 Frangi 过滤器 options struct FrangiScaleRange 5 5 FrangiScaleRatio 1 FrangiBetaOne 1 FrangiBe
  • 如何在 matlab 中创建由多个 3d 图像数据数组组成的数组

    我正在阅读 15 张图片imagedata imread imagename jpg 它的大小总是320 by 320 by 3 如何将数据放入数组中 使用 for for 循环 以便在访问新数组的第一个元素时获得输入的第一个图像的 RGB
  • MATLAB - 冲浪图数据结构

    我用两种不同的方法进行了计算 对于这些计算 我改变了 2 个参数 x 和 y 最后 我计算了每种变体的两种方法之间的 误差 现在我想根据结果创建 3D 曲面图 x gt on x axis y gt on y axis Error gt o
  • glpk.LPX 向后兼容性?

    较新版本的glpk没有LPXapi 旧包需要它 我如何使用旧包 例如COBRA http opencobra sourceforge net openCOBRA Welcome html 与较新版本的glpk 注意COBRA适用于 MATL
  • MATLAB 中的霍夫变换

    有谁知道如何使用霍夫变换来检测二值图像中最强的线 A zeros 7 7 A 6 10 18 24 36 38 41 1 使用 rho theta 格式 其中 theta 以 45 为步长 从 45 到 90 以及如何在 MATLAB 中显
  • 图像处理 - 使用 opencv 进行服装分割

    我正在使用 opencv 进行服装特征识别 第一步 我需要通过从图像中移除脸部和手来分割 T 恤 任何建议表示赞赏 我建议采用以下方法 Use 阿德里安 罗斯布鲁克的用于检测皮肤的皮肤检测算法 谢谢罗莎 格隆奇以获得他的评论 在方差图上使用
  • MATLAB:在不使用循环的情况下提取矩阵的多个部分

    我有一个巨大的 2D 矩阵 我想从中提取 15 个不同的 100x100 部分 我有两个向量 x 和 y 其中保存了零件的左上角索引 我用过这样的东西 result cam1 x 1 end x 1 end 99 y 1 end y 1 e
  • matlab中求和函数句柄

    Hi我试图对两个函数句柄求和 但它不起作用 例如 y1 x x x y2 x x x 3 x y3 y1 y2 我收到的错误是 对于 function handle 类型的输入参数 未定义函数或方法 plus 这只是一个小例子 实际上我实际
  • 检测分段常数信号中的阶跃

    我有一个分段恒定信号 如下所示 我想检测步骤转换的位置 标记为红色 我目前的做法 使用移动平均滤波器平滑信号 http www mathworks com help signal examples signal smoothing html

随机推荐