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

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

  1. 初始化参数。
  2. 将蚂蚁随机的放在城市上。
  3. 蚂蚁各自按概率选择下一座城市。
  4. 蚂蚁完成各自的周游。
  5. 更新信息素,进行下一次迭代。

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

结果如下:

最短路径变化图
蚁群算法找到的最优路径

主函数

主函数如下:

clc;
clear;

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

推荐阅读更多精彩内容