Matlab如何改进蚁群算法求解最优值(代码已给)

Matlab如何改进蚁群算法求解最优值
有一个280个城市坐标的TSP问题,最短距离是2579,在通过尝试了多次调整参数后收敛结果始终在2800+上下徘徊,应如何解决这一过早收敛的问题呢,请各位指导,代码如下

clear all
close all
clc

%% II. 导入数据
citys =[
 288 149 
 288 129 
 270 133 
 256 141 
 256 157 
 246 157 
 236 169 
 228 169 
 228 161 
 220 169 
 212 169 
 204 169 
 196 169 
 188 169 
 196 161 
 188 145 
 172 145 
 164 145 
 156 145 
 148 145 
 140 145 
 148 169 
 164 169 
 172 169 
 156 169 
 140 169 
 132 169 
 124 169 
 116 161 
 104 153 
 104 161 
 104 169 
 90 165 
 80 157 
 64 157 
 64 165 
 56 169 
 56 161 
 56 153 
 56 145 
 56 137 
 56 129 
 56 121 
 40 121 
 40 129 
 40 137 
 40 145 
 40 153 
 40 161 
 40 169 
 32 169 
 32 161 
 32 153 
 32 145 
 32 137 
 32 129 
 32 121 
 32 113  
 40 113 
 56 113 
 56 105 
 48 99 
 40 99 
 32 97 
 32 89 
 24 89 
 16 97 
 16 109 
 8 109 
 8 97 
 8 89 
 8 81 
 8 73 
 8 65 
 8 57 
 16 57 
 8 49 
 8 41 
 24 45 
 32 41 
 32 49 
 32 57 
 32 65 
 32 73 
 32 81 
 40 83 
 40 73 
 40 63 
 40 51 
 44 43 
 44 35 
 44 27 
 32 25 
 24 25 
 16 25 
 16 17 
 24 17 
 32 17 
 44 11 
 56 9 
 56 17 
 56 25 
 56 33 
 56 41 
 64 41 
 72 41 
 72 49 
 56 49 
 48 51 
 56 57 
 56 65 
 48 63 
 48 73 
 56 73 
 56 81 
 48 83 
 56 89 
 56 97 
 104 97 
 104 105 
 104 113 
 104 121 
 104 129 
 104 137 
 104 145 
 116 145 
 124 145 
 132 145 
 132 137 
 140 137 
 148 137 
 156 137 
 164 137 
 172 125 
 172 117 
 172 109 
 172 101 
 172 93 
 172 85 
 180 85 
 180 77 
 180 69 
 180 61 
 180 53 
 172 53 
 172 61 
 172 69 
 172 77 
 164 81 
 148 85 
 124 85 
 124 93 
 124 109 
 124 125 
 124 117 
 124 101 
 104 89 
 104 81 
 104 73 
 104 65 
 104 49 
 104 41 
 104 33 
 104 25 
 104 17 
 92 9 
 80 9 
 72 9 
 64 21 
 72 25 
 80 25
 80 41 
 88 49 
 104 57 
 124 69 
 124 77 
 132 81 
 140 65 
 132 61 
 124 61 
 124 53 
 124 45 
 124 37 
 124 29 
 132 21 
 124 21 
 120 9 
 128 9 
 136 9 
 148 9 
 162 9 
 156 25 
 172 21 
 180 21 
 180 29 
 172 29 
 172 37 
 172 45 
 180 45 
 180 37 
 188 41 
 196 49 
 204 57 
 212 65 
 220 73 
 228 69 
 228 77 
 236 77 
 236 69 
 236 61 
 228 61 
 228 53 
 236 53 
 236 45 
 228 45 
 228 37 
 236 37 
 236 29 
 228 29 
 228 21 
 236 21 
 252 21 
 260 29 
 260 37 
 260 45 
 260 53 
 260 61 
 260 69 
 260 77 
 276 77 
 276 69 
 276 61 
 276 53 
 284 53 
 284 61 
 284 69 
 284 77 
 284 85 
 284 93 
 284 101 
 288 109 
 280 109 
 276 101 
 276 93 
 276 85 
 268 97 
 260 109  
 252 101 
 260 93 
 260 85 
 236 85 
 228 85 
 228 93 
 236 93 
 236 101 
 228 101 
 228 109 
 228 117 
 228 125 
 220 125 
 212 117 
 204 109 
 196 101 
 188 93 
 180 93 
 180 101 
 180 109 
 180 117 
 180 125 
 196 145 
 204 145 
 212 145 
 220 145 
 228 145 
 236 145 
 246 141 
 252 125 
 260 129 
 280 133];% 这里是坐标矩阵

%% III. 计算城市间相互距离
n = size(citys, 1);   % 城市的个数
D = zeros(n, n);
for i = 1:n
    for j = 1:n
        if i ~= j
            D(i, j) = sqrt(sum((citys(i, :)-citys(j, :)).^2));
        else
            D(i, j) = 1e-4;
        end
    end
end

%% IV. 初始化参数
m = 1200;                             % 蚂蚁数量
alpha = 1;                          % 信息素重要程度因子
beta = 0.1;                           % 启发函数重要程度因子
rho = 0.1;                          % 信息素挥发因子
Q = 1;                              % 常系数,信息素增加强度系数,计算信息素的系数
Eta = 1./D;                         % 启发函数,对各个点之间的距离取倒数
Tau = ones(n, n);                   % 信息素矩阵,各个位置的信息素矩阵
Table = zeros(m, n);                % 路径记录表,用于记录没一只蚂蚁的路线信息
iter = 1;                           % 迭代次数初值
iter_max = 400;                     % 最大迭代次数
Route_best = zeros(iter_max, n);    % 各代最佳路径
Length_best = zeros(iter_max, 1);   % 各代最佳路径长度
Length_ave = zeros(iter_max, 1);    % 各代路径的平均长度

%% V. 迭代寻找最佳路径
while iter <= iter_max
    clc
    iter
    % 随机产生各个蚂蚁的起点城市
    start = zeros(m, 1);   %  创建一个start数组用于存储出发点
    for i = 1:m
        temp = randperm(n);     % 1~n的随机排列 ,也可以使用randint,随机生成某一个城市作为初始点,这样没一只蚂蚁都有一个初始点
        start(i) = temp(1);
    end
    Table(:, 1) = start;    % Table是路径记录表,将每个出发点先写进去
    citys_index = 1:n;      % 城市索引
    % 逐个蚂蚁路径选择
    for i = 1:m  %对于蚁群当中的每一只蚂蚁
        % 逐个城市路径选择
        for j = 2:n
            tabu = Table(i, 1:(j-1));       % 已访问的城市集合(禁忌表)
            allow_index = ~ismember(citys_index, tabu); %把剩下的所有的城市都记录到为允许访问的标号
            
            allow = citys_index(allow_index);   % 待访问的城市集合
            P = allow;
            % 计算城市间转移概率,然后对每个点分别计算访问的概率
            for k = 1:length(allow)
                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;
        end
    end
    % 以上程序对于所有的蚂蚁都进行循环,然后找到所有的蚂蚁的活动路径
    % 计算各个蚂蚁的路径距离
    Length = zeros(m, 1); % 生成这个数据用于后续保存数据
    for i = 1:m
        Route = Table(i, :);% 读取蚁群中第i个蚂蚁运动的路径
        for j = 1: (n-1)
            Length(i) = Length(i) + D(Route(j), Route(j+1));% 将对应的路径加起来
        end
        Length(i) = Length(i) + D(Route(n), Route(1));  % 这个语句表示最终会返回出发点,结束循环,如果不需要返回出发点,可以去掉这一条语句
    end
    % 计算最短路径距离及平均距离
    if iter == 1
        [min_Length, min_index] = min(Length);
        Length_best(iter) = min_Length;
        Length_ave(iter) =mean(Length);
        Route_best(iter, :) = Table(min_index, :); % 如果是初次进行循环就直接求得最小的路程,其对应的路径还有平均距离
    else
        [min_Length, min_index] = min(Length);%  如果不是第一次的话需要判断最小路径是否小于上次的最小路径,如果小于上次的,对应的最值进行更新,否则直接保持与上次的一致
        Length_best(iter) = min(Length_best(iter-1), min_Length);
        Length_ave(iter) = mean(Length);
        if Length_best(iter) == min_Length
            Route_best(iter, :) = Table(min_index, :);
        else
            Route_best(iter, :) = Route_best((iter-1), :);
        end
    end
    % 更新信息素
    Delta_Tau = zeros(n, n);
    % 逐个蚂蚁计算
    for i = 1:m
        % 逐个城市计算
        for j = 1:(n-1)
            Delta_Tau(Table(i, j), Table(i, j+1)) = Delta_Tau(Table(i, j), Table(i, j+1)) + Q/Length(i);  % 利用的是蚁周模型
        end
        Delta_Tau(Table(i, n), Table(i, 1)) = Delta_Tau(Table(i, n), Table(i, 1)) + Q/Length(i); %  这里呢是计算终点到出发点之间的信息素的数值
    end
    Tau = (1-rho) * Tau + Delta_Tau;
    iter = iter + 1;
    Table = zeros(m, n);
end

%% VI. 结果显示
[Shortest_Length, index] = min(Length_best);
Shortest_Route = Route_best(index, :);
disp(['最短距离', num2str(Shortest_Length)]);
disp(['最短路径', num2str([Shortest_Route Shortest_Route(1)])]);

%% VII. 绘图  
plot([citys(Shortest_Route,1);citys(Shortest_Route(1),1)],...
     [citys(Shortest_Route,2);citys(Shortest_Route(1),2)],'o-');
grid on;
for i = 1:size(citys,1)
    text(citys(i,1),citys(i,2),['   ' num2str(i)]);
end
text(citys(Shortest_Route(1),1),citys(Shortest_Route(1),2),'       起点');
text(citys(Shortest_Route(end),1),citys(Shortest_Route(end),2),'       终点');
xlabel('城市位置横坐标')
ylabel('城市位置纵坐标')
title(['蚁群算法优化路径(最短距离:' num2str(Shortest_Length) ')'])
figure(2)
plot(1:iter_max,Length_best,'b',1:iter_max,Length_ave,'r:')
legend('最短距离','平均距离')
xlabel('迭代次数')
ylabel('距离')
title('各代最短距离与平均距离对比')


可以尝试改变蚁群算法的参数设置,如信息素挥发速率、蚂蚁搜索路径时的转向概率、每只蚂蚁对于信息素的敏感度等。还可以尝试改变蚁群算法的收敛策略,如增加迭代次数、增加蚂蚁数量等。如果还不行,可以尝试使用其他的优化算法,如遗传算法或模拟退火算法来寻找最优解。另外,你也可以尝试使用更精确的距离计算方式,比如使用曼哈顿距离或欧几里得距离来代替欧几里得距离的平方。还可以尝试改变蚁群算法的解决方案初始化方式,比如使用更优秀的解作为初始解。

此外,你还可以尝试使用启发式信息来引导蚂蚁的搜索,比如使用城市间的距离作为启发式信息,或者使用城市的流量作为启发式信息。这样可以使蚂蚁在搜索过程中得到更多的有用信息,帮助蚁群算法更快地找到最优解。

% III. 计算城市间相互距离
n = size(citys, 1); % 城市的个数
D = zeros(n, n);
for i = 1:n
for j = 1:n
if i ~= j
D(i, j) = sqrt(sum((citys(i, :)-citys(j, :)).^2));
else
D(i, j) = 1e-4; % 防止除0的情况,设为很小的数
end
end
end
 
% IV. 初始化参数
m = 1200; % 蚂蚁数量
alpha = 1; % 信息素重要程度因子
beta = 0.1; % 启发函数重要程度因子
rho = 0.1; % 信息素挥发因子
Q = 1; % 常系数,信息素增加强度系数,计算信息素的系数
Eta = 1./D; % 启发函数,对各个点之间的距离取倒数
Tau = ones(n, n); % 信息素矩阵,各个位置的信息素矩阵
Table = zeros(m, n); % 路径记录表,用于记录每一只蚂蚁的路线信息
iter = 1; % 迭代次数初值
iter_max = 400; % 最大迭代次数
Route_best = zeros(iter_max, n); % 各代最佳路径
Length_best = zeros(iter_max, 1); % 各代最佳路径长度
Length_ave = zeros(iter_max, 1); % 各代路径的平均长度
 
% V. 迭代寻找最佳路径
while iter <= iter_max
clc
iter
% 随机产生各个蚂蚁的起点城市
start = zeros(m, 1); % 创建一个start数组用于存储出发点for i = 1:m
start(i) = randi(n); % 随机生成某一个城市作为初始点,这样每一只蚂蚁都有一个初始点
end
Table(:, 1) = start; % Table是路径记录表,将每个出发点先写进去
citys_index = 1:n; % 城市索引
% 逐个蚂蚁路径选择
for i = 1:m
citys_index_temp = citys_index; % 将索引复制一份,用于暂时存储当前蚂蚁所能前往的城市的索引
citys_index_temp(start(i)) = []; % 去掉起点城市的索引
for j = 2:n
% 计算选择每一个城市的概率
P = (Tau(start(i), citys_index_temp).^alpha).*(Eta(start(i), citys_index_temp).^beta);
P_sum = sum(P);
P = P./P_sum; % 计算概率
% 转移到下一个城市
temp = rand;
for k = 1:length(citys_index_temp)
if temp < sum(P(1:k))
start(i) = citys_index_temp(k); % 更新当前蚂蚁的出发城市
Table(i, j) = start(i); % 将当前蚂蚁的出发城市存储到路径记录表中
break; % 跳出循环
end
end
end
end
% 计算各个蚂蚁的路径长度
Length = zeros(m, 1);
for i = 1:m
Length(i) = sum(D(Table(i, :), Table(i, [2:end, 1])));
end
[Length_best(iter), idx] = min(Length); % 找出最短路径的蚂蚁的索引
Route_best(iter, :) = Table(idx, :); % 找出最短路径的蚂蚁的路径
Length_ave(iter) =mean(Length); % 计算路径长度的平均值
% 更新信息素矩阵
Delta_Tau = zeros(n, n); % 创建一个Delta_Tau矩阵用于存储蚂蚁所携带的信息素
for i = 1:m
for j = 1:n-1
Delta_Tau(Table(i, j), Table(i, j+1)) = Delta_Tau(Table(i, j), Table(i, j+1)) + Q/D(Table(i, j), Table(i, j+1)); % 计算蚂蚁在每一段路径上所携带的信息素
end
Delta_Tau(Table(i, n), Table(i, 1)) = Delta_Tau(Table(i, n), Table(i, 1)) + Q/D(Table(i, n), Table(i, 1)); % 将蚂蚁携带的信息素存储到Delta_Tau中
end
Tau = (1-rho)*Tau + Delta_Tau; % 更新信息素矩阵
iter = iter+1; % 迭代次数加1
end
 % III. 计算城市间相互距离
n = size(citys, 1); % 城市的个数
D = zeros(n, n);
for i = 1:n
for j = 1:n
if i ~= j
D(i, j) = sqrt(sum((citys(i, :)-citys(j, :)).^2));
else
D(i, j) = 1e-4; % 防止除0的情况,设为很小的数
end
end
end
 
% IV. 初始化参数
m = 1200; % 蚂蚁数量
alpha = 1; % 信息素重要程度因子
beta = 0.1; % 启发函数重要程度因子
rho = 0.1; % 信息素挥发因子
Q = 1; % 常系数,信息素增加强度系数,计算信息素的系数
Eta = 1./D; % 启发函数,对各个点之间的距离取倒数
Tau = ones(n, n); % 信息素矩阵,各个位置的信息素矩阵
Table = zeros(m, n); % 路径记录表,用于记录每一只蚂蚁的路线信息
iter = 1; % 迭代次数初值
iter_max = 400; % 最大迭代次数
Route_best = zeros(iter_max, n); % 各代最佳路径
Length_best = zeros(iter_max, 1); % 各代最佳路径长度
Length_ave = zeros(iter_max, 1); % 各代路径的平均长度
% V. 迭代寻找最佳路径
while iter <= iter_max
clc
iter
% 随机产生各个蚂蚁的起点城市
start = zeros(m, 1); % 创建一个start数组用于存储出发点
for i = 1:m
start(i) = randi(n); % 随机生成某一个城市作为初始点,这样每一只蚂蚁都有一个初始点
end
Table(:, 1) = start; % Table是路径记录表,将每个出发点先写进去
citys_index = 1:n; % 城市索引
% 逐个蚂蚁路径选择
for i = 1:m
citys_index_temp = citys_index; % 将索引复制一份,用于暂时存储当前蚂蚁所能前往的城市的索引
citys_index_temp(start(i)) = []; % 去掉起点城市的索引
for j = 2:n
% 计算选择每一个城市的概率
P = (Tau(start(i), citys_index_temp).^alpha).*(Eta(start(i), citys_index_temp).^beta);
P_sum = sum(P);
P = P./P_sum; % 计算概率
% 转移到下一个城市
temp = rand;
for k = 1:length(citys_index_temp)
if temp < sum(P(1:k))
start(i) = citys_index_temp(k); % 更新当前蚂蚁的出发城市
Table(i, j) = start(i); % 将当前蚂蚁的出发城市存储到路径记录表中
break; % 跳出循环
end
end
end
end
 
% 计算各个蚂蚁的路径长度
Length = zeros(m, 1);
for i = 1:m
Length(i) = sum(D(Table(i, :), Table(i, [2:end, 1])));
end
[Length_best(iter), idx] = min(Length); % 找出最短路径的蚂蚁的索引
Route_best(iter, :) = Table(idx, :); % 找出最短路径的蚂蚁的路径
Length_ave(iter) = mean(Length); % 计算路径长度的平均值
% 更新信息素矩阵
Delta_Tau = zeros(n, n); % 创建一个Delta_Tau矩阵用于存储蚂蚁所携带的信息素
for i = 1:m
for j = 1:n-1
Delta_Tau(Table(i, j), Table(i, j+1)) = Delta_Tau(Table(i, j), Table(i, j+1)) + Q/D(Table(i, j), Table(i, j+1)); % 计算蚂蚁在每一段路径上所携带的信息素
end
Delta_Tau(Table(i, n), Table(i, 1)) = Delta_Tau(Table(i, n), Table(i, 1)) + Q/D(Table(i, n), Table(i, 1)); % 将蚂蚁携带的信息素存储到Delta_Tau中
end
Tau = (1-rho)*Tau + Delta_Tau; % 更新信息素矩阵
iter = iter+1; % 迭代次数加1
end
 

如果方便的话可以直接在原来的代码上修改,急急急

可以尝试以下方法:
1.调整信息素挥发速率(evaporation rate)和信息素强度(pheromone intensity),使算法能够更快地探索新的解决方案。

2.增加蚂蚁的数量,使算法能够更多地探索空间,从而更有可能找到全局最优解。

3.尝试使用不同的蚂蚁漫步策略,例如随机漫步或者贪心漫步,来更多地探索空间。

4.尝试使用其他的结合策略,例如解决决策树(decision tree)或者遗传算法(genetic algorithm)来提高算法的收敛速度。

在蚁群算法中,过早收敛可能是由于参数设置不合理导致的。您可以尝试以下几种方法来改进蚁群算法,提高其对最优解的收敛性:

  1. 调整信息素挥发因子和信息素吸收因子。这些因子可以影响蚂蚁的搜索行为,如果设置不当会导致过早收敛。

  2. 增加蚂蚁的数量。增加蚂蚁的数量可以使算法更具随机性,更大可能找到更优解

  3. 选择合适的贪心规则。 选择合适的贪心规则可以使算法更具随机性,更大可能找到更优解

  4. 增加搜索的迭代次数。增加搜索的迭代次数可以使算法有更多的机会找到最优解

使用多种策略。混合使用多种策略(如蚁群算法,遗传算法,模拟退火算法,等)来求解问题

  1. 适当增加蚁群算法中其它参数,如最大迭代次数、信息素浓度等参数,来避免过早收敛

  2. 改变蚁群算法的退火策略,例如模拟退火策略替代概率退火策略

  3. 使用更先进的蚁群算法,如基于粒子群算法的蚁群算法、基于遗传算法的蚁群算法等

还有,对于280个城市的 TSP问题来说,蚁群算法并不是比较有效的做法,相对来说更高效的解决办法可以考虑 2-opt,3-opt等更优秀的算法。