为了账号安全,请及时绑定邮箱和手机立即绑定

蚁群算法解决旅行商(TSP)问题

标签:
算法

使用蚁群算法解决旅行商问题步骤如下:

  1. 初始化参数。

  2. 将蚂蚁随机的放在城市上。

  3. 蚂蚁各自按概率选择下一座城市。

  4. 蚂蚁完成各自的周游。

  5. 更新信息素,进行下一次迭代。

在更新信息素的过程中,只有最优路线上的信息素会进行增加操作,且不能超过信息素最大值。

结果如下:

webp

最短路径变化图

webp

蚁群算法找到的最优路径

主函数

主函数如下:

clc;
clear;

pos = load('berlin52.txt'); % 7542pos = pos(:, 2:3);
pos = pos';

dm = makeDistanceMatrix(pos);           % 距离矩阵n = size(dm, 1);        % 城市个数m = 80;                 % 蚂蚁个数alpha = 1.4;            % 信息素重要程度beta = 2.2;             % 启发式因子重要程度rho = 0.15;             % 信息素挥发系数Q = 10^6;               % 信息素增加强度eta = makeEta(dm);      % 启发因子,为距离的倒数tau = ones(n, n);       % 信息素矩阵taumax = 1;             % 信息素上界maxgen = 120;
path = zeros(m, n);
bestpath = zeros(maxgen, n);for gen = 1:maxgen    % 随机生成第1个城市
    for i = 1:m
        path(i, :) = randperm(n);    end
    for i = 1:m        % 确定后续城市
        for j = 2:n
            surepath = path(i, 1:j-1);
            testcities = path(i, j:n);
            city = surepath(end);            % 使用轮盘赌法进行选择
            [nextcity, lastcities] =  ...
                getNextCity(city, testcities, tau, alpha, eta, beta);
            path(i, :) = [surepath nextcity lastcities];        end
    end
    % 记录最优路线
    len = callength(path, dm);
    [~, minindex] = min(len);
    bestpath(gen, :) = path(minindex, :);    
    % 更新信息素
    bpath = path(minindex, :);
    blen = len(minindex);
    tau = updateTau(tau, rho, Q, taumax, bpath, blen);endlen = callength(bestpath, dm);
[~, minindex] = min(len);
bpath = bestpath(minindex, :);
plotroute(pos, bpath);

figure();
plot([1:1:maxgen], len');

一些其他函数

轮盘赌法求下一个城市的方法如下:

function [nextcity, lastcities] = getNextCity(city, testcities, tau, alpha, eta, beta)% 使用轮盘赌法给出下一个城市% city          input  当前城市% testcities    input  待选城市% tau           input  信息素矩阵% alpha         input  信息素重要程度% eta           input  启发式因子矩阵% beta          input  启发式因子重要程度% nextcity      output 下一个城市% lastcities    output 待选城市p = tau(city, testcities) .^ alpha .* eta(city, testcities) .^ beta;
p = p / (sum(p));
p = cumsum(p);
index = find(p >= rand);
nextcity = testcities(index(1));
lastcities = testcities(testcities ~= nextcity);end

更新信息素矩阵的函数如下:

function ntau = updateTau(tau, rho, q, taumax, bestpath, bestlen)% 更新信息素矩阵,只有最优路径上的信息素会被增加% tau           input  信息素矩阵% rho           input  信息素挥发系数% q             input  信息素增加系数% taumax        input  信息素上限% bestpath      input  最优路径% bestlen       input  最优路径长度% ntau          output 更新后的信息素矩阵n = size(tau, 1);
ntau = (1 - rho) .* tau;for i = 2:n
    city1 = bestpath(i-1);
    city2 = bestpath(i);
    ntau(city1, city2) = ntau(city1, city2) + q / bestlen;
    ntau(city2, city1) = ntau(city2, city1) + q / bestlen;endntau(ntau > taumax) = taumax;end

制作距离矩阵的函数如下:

function dm = makeDistanceMatrix(pos)% 制作距离矩阵% pos       input  城市坐标% dm        output 距离矩阵[~, len] = size(pos);
deltax = repmat(pos(1,:)', 1, len) - repmat(pos(1,:), len, 1);
deltay = repmat(pos(2,:)', 1, len) - repmat(pos(2,:), len, 1);
dm = round((deltax .^ 2 + deltay .^ 2) .^ 0.5);end

制作启发式因子矩阵的函数如下:

function eta = makeEta(dm)% 制作启发式因子的倒数,是距离矩阵的倒数% dm            input  距离矩阵% eta           output 启发式因子矩阵[rn, cn] = size(dm);
dm = dm + ones(rn, cn); % 加1以防止除0eta = 1 ./ dm;end

求路径距离的函数如下:

function len = callength(pop, dm)% 求路径距离% pop           input  种群% dm            input  距离矩阵% len           output 距离[NP, D] = size(pop);
pop = [pop pop(:,1)];
sum = zeros(NP, 1);for i = 1:NP    for j = 1:D
        sum(i,1) = sum(i,1) + dm(pop(i, j), pop(i, j+1));    endendlen = sum;end

绘制路径的函数如下:

function plotroute(pos, v)% 绘制路径% pos           input  城市坐标点% v             input  城市序列figure();
plot(pos(1,:), pos(2,:), 'bo');
hold on;for i = 1:(size(v,2)-1)
    x1 = pos(1,v(i)); y1 = pos(2,v(i));
    x2 = pos(1,v(i+1)); y2 = pos(2,v(i+1));
    plot([x1, x2], [y1, y2], 'b');
    hold on;endplot([pos(1,v(end)), pos(1,v(1))], [pos(2,v(end)), pos(2,v(1))], 'b');
hold off;end



作者:mwangjs
链接:https://www.jianshu.com/p/f7ff8e3933be


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消