【蚁群算法求解TSP问题】matlab实现

问题描述

旅行商问题(Traveling Salesman Problem,TSP)是一个著名的组合优化问题,其目标是找到一条最短路径,使得旅行商可以经过所有给定城市一次并回到起始城市。在这个问题中,假设有一位旅行商要访问多个城市,并且每两个城市之间都有确定的距离或成本。TSP的目标是找到一条路径,使得旅行商走过的总距离或总成本最小。

蚁群算法

实现步骤:
步骤1:初始化,设定相关参数:
全部城市数n
全部蚂蚁数m, m<n
循环(迭代)次数的最大值Nmax
初始时各路径信息素τi,j(0)=τ0
信息素挥发系数ρ以及α、β、Q等
建立禁忌列表Jk,并保证此时表中没有任何城市。

步骤2:将m只蚂蚁随机放在各个城市上,每个城市至多分布一个蚂蚁,并将m个蚂蚁所在城市存入禁忌列表Jk。
步骤3:所有蚂蚁依据概率选择下一城市,并将选择城市存入禁忌列表。

步骤4:所有蚂蚁都构建完一条完整的路径后,在所经过的路径上更新信息素,并记录本次迭代过程中的最优路径和最优路径长度。

步骤5:清空禁忌列表Jk,重复步骤2和步骤4直到每一只蚂蚁完成Nmax次迭代,或者出现停滞现象(所有蚂蚁都选择相同路径,路径不再变化),最后输出最优路径。

在这里插入图片描述
具体原理参考计算智能

代码实现

map = [18, 54; 87, 76; 74, 78; 71, 71; 25, 38; 58, 35; 04, 50; 13, 40; 18, 40; 24, 42;
 71, 44; 64, 60; 68, 58; 83, 69; 58, 69; 54, 62; 51, 67; 37, 84; 41, 94; 02, 99;
 07, 64; 22, 60; 25, 62; 62, 32; 87, 07; 91, 38; 83, 46; 41, 26; 45, 21; 44, 35];
n = size(map, 1); % 城市数
citys_idx = 1:n; % 城市序号
maxiter = 200; % 最大迭代次数
ant_num = 29; % 蚂蚁数量
alpha = 1; % 控制信息素权重
beta = 2; % 控制能见度权重
rho = 0.5; % 信息素挥发系数
Q = 1; % 信息素强度
Tau = ones(n, n); % 信息素矩阵,初始化为 1
% 计算每个城市之间的距离
D = zeros(n, n);
for i = 1:n
    for j = 1:n
        if i ~= j
            D(i, j) = distance(map(i, :), map(j, :));
        end
    end
end
Eta = 1 ./D; % 城市之间的启发度
iter = 1;
MinRoad = zeros(maxiter, n);
MinRoad_value = zeros(maxiter, 1);
while iter <= maxiter
     Table = zeros(ant_num, n); % 所有蚂蚁的路径表
     % 初始化所有蚂蚁的起点城市
     Table(:, 1) = randi(n, ant_num, 1);
     % 遍历蚂蚁
     for i = 1:ant_num
         % 遍历城市
         for j = 2:n % j 为下一个要访问的城市
             check = Table(i, 1:(j - 1)); % 第 i 只蚂蚁已访问 j - 1 个的城市(禁忌表)
             allowed = setdiff(citys_idx, check);
             % 计算到达各个城市的概率
             P = zeros(1, length(allowed));
             for k = 1:length(P)
                P(k) = Tau(check(end), allowed(k)) ^ alpha * Eta(check(end), allowed(k)) ^beta;
             end
             P = P / sum(P);
             % 轮盘赌选择下一个访问城市
             Pc = cumsum(P); % 累加概率
             target_index = find(Pc >= rand);
             target = allowed(target_index(1));
             Table(i,j) = target;
        end
    end
     % 计算各个蚂蚁的路径距离
     Dist = calculateDistances(Table, map);
     % 获得当前最短路径
     [Mindist, q] = min(Dist);
     MinRoad_it = Table(q, :);
     MinRoad_it_value = Mindist;
     % 更新信息素
     Delta_Tau = zeros(n, n);
     % 遍历蚂蚁
     for i = 1:ant_num
         % 遍历城市
         for j = 1:(n -1)
            Delta_Tau(Table(i, j), Table(i, j + 1)) = Delta_Tau(Table(i, j), Table(i, j +1)) + Q / Dist(i);
         end
         Delta_Tau(Table(i, n), Table(i, 1)) = Delta_Tau(Table(i, n), Table(i, 1)) + Q/Dist(i);
     end
     Tau = (1 - rho) * Tau + Delta_Tau;
     % 每次更新最优解
     MinRoad(iter, :) = MinRoad_it;
     MinRoad_value(iter, 1) = MinRoad_it_value;
     iter = iter + 1;
end
% 找出全局最优路径及其迭代次数
[MinestRoad_value, Iterindex] = min(MinRoad_value);
disp('最优路径为:');
disp(MinRoad(Iterindex, :));
disp('最优路径长度为:');
disp(MinestRoad_value);
disp('获得最佳路径的迭代次数为:');
disp(Iterindex);
% 城市路径图
figure;
% 初始路径
subplot(1, 2, 1);
draw_map = [map; map(1, :)];
plot(draw_map(:, 1), draw_map(:, 2), '*', 'DisplayName', '城市');
hold on;
plot(draw_map(:, 1), draw_map(:, 2), '-', 'LineWidth', 1, 'Color', [1, 0.5, 0],'DisplayName', '初始路径');
legend('show');
legend('Location', 'best');
for c = 1:n
    text(map(c, 1), map(c, 2), [' ' num2str(c)], 'Color', 'k', 'FontWeight', 'b');
end
% 最优路径
subplot(1, 2, 2);
ordered_map = map(MinRoad(Iterindex, :), :);
ordered_map = [ordered_map; ordered_map(1, :)];
plot(ordered_map(:, 1), ordered_map(:, 2), '*', 'DisplayName', '城市');
hold on;
plot(ordered_map(:, 1), ordered_map(:, 2), '-', 'LineWidth', 1, 'Color', [1, 0.5, 0],'DisplayName', '最优路径');
legend('show');
legend('Location', 'best');
for c = 1:n
    text(ordered_map(c, 1), ordered_map(c, 2), [' ' num2str(c)], 'Color', 'k','FontWeight', 'b');
end
% 迭代曲线图
figure;
plot(MinRoad_value);
title('迭代曲线');
xlabel('迭代次数');
ylabel('最短路径长度');
% 计算路径总长度
function Dist = calculateDistances(Table, map)
     Popsize = size(Table, 1); % 蚂蚁数量
     n = size(Table, 2); % 节点数量
     Dist = zeros(Popsize, 1); % 用于存储每条路径的距离
     for i = 1:Popsize
        dist = 0;
         for j = 1:(n - 1)
             A = Table(i, j);
             B = Table(i, j + 1);
             A1 = map(A, :);
             B1 = map(B, :);
             dist = dist + distance(A1, B1);
         end
     A = Table(i, 1);
     B = Table(i, n);
     A1 = map(A, :);
     B1 = map(B, :);
     dist = dist + distance(A1, B1);
     Dist(i, 1) = dist;
     end
end
% 计算两城市之间距离
function d = distance(A, B)
    d = sqrt((B(1) - A(1))^2 + (B(2) - A(2))^2);
end

输出结果

全局最优长度和对应迭代次数
在这里插入图片描述

初始路径与全局路径
在这里插入图片描述

迭代曲线
在这里插入图片描述

  • 9
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
算法是一种基于模拟蚂觅食行为的启发式算法,可以用于求解TSP问题。在MATLAB中,可以通过以下步骤实现: 1. 定义城市距离矩阵,即TSP问题的输入数据。 2. 初始化蚂的位置和信息素矩阵。 3. 迭代搜索过程中,每只蚂按照一定的概率选择下一个城市,并更新信息素矩阵。 4. 记录每次迭代中最优路径和路径长度。 5. 输出最优路径和路径长度。 以下是一个简单的MATLAB代码示例: ```matlab % 定义城市距离矩阵 dist = [...]; % 初始化参数 num_ant = 50; % 蚂数量 num_city = size(dist, 1); % 城市数量 pheromone = ones(num_city, num_city); % 信息素矩阵 alpha = 1; % 信息素重要程度因子 beta = 5; % 启发式因子 rho = 0.5; % 信息素挥发因子 Q = 100; % 信息素增加强度因子 % 开始迭代搜索 best_path = []; best_length = Inf;for iter = 1:100 % 初始化蚂位置 ant_pos = randi(num_city, num_ant, 1); for i = 1:num_city-1 % 计算每只蚂的下一个城市概率 prob = (pheromone(ant_pos(:,i),:) .^ alpha) .* ((1./dist(ant_pos(:,i),:)) .^ beta); prob(:, ant_pos(:,1:i-1)) = 0; % 已经访问过的城市概率为0 prob = prob ./ sum(prob, 2); % 按照概率选择下一个城市 [~, next_city] = max(rand(num_ant, 1) <= cumsum(prob, 2), [], 2); ant_pos(:,i+1) = next_city; end % 计算每只蚂的路径长度 path_length = sum(dist(sub2ind([num_city, num_city], ant_pos(:,end), ant_pos(:,1))), 1); for i = 1:num_ant-1 path_length(i+1) = sum(dist(sub2ind([num_city, num_city], ant_pos(i,:), ant_pos(i+1,:))), 2); end % 更新信息素矩阵 delta_pheromone = zeros(num_city, num_city); for i = 1:num_ant for j = 1:num_city-1 delta_pheromone(ant_pos(i,j), ant_pos(i,j+1)) = delta_pheromone(ant_pos(i,j), ant_pos(i,j+1)) + Q/path_length(i); end delta_pheromone(ant_pos(i,end), ant_pos(i,1)) = delta_pheromone(ant_pos(i,end), ant_pos(i,1)) + Q/path_length(i); end pheromone = (1-rho) * pheromone + delta_pheromone; % 记录最优路径和路径长度 if min(path_length) < best_length best_path = ant_pos(path_length == min(path_length), :); best_length = min(path_length); end end % 输出结果 disp(['Best path: ', num2str(best_path)]); disp(['Best length: ', num2str(best_length)]); ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值