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)来提高算法的收敛速度。
在蚁群算法中,过早收敛可能是由于参数设置不合理导致的。您可以尝试以下几种方法来改进蚁群算法,提高其对最优解的收敛性:
调整信息素挥发因子和信息素吸收因子。这些因子可以影响蚂蚁的搜索行为,如果设置不当会导致过早收敛。
增加蚂蚁的数量。增加蚂蚁的数量可以使算法更具随机性,更大可能找到更优解
选择合适的贪心规则。 选择合适的贪心规则可以使算法更具随机性,更大可能找到更优解
增加搜索的迭代次数。增加搜索的迭代次数可以使算法有更多的机会找到最优解
使用多种策略。混合使用多种策略(如蚁群算法,遗传算法,模拟退火算法,等)来求解问题
适当增加蚁群算法中其它参数,如最大迭代次数、信息素浓度等参数,来避免过早收敛
改变蚁群算法的退火策略,例如模拟退火策略替代概率退火策略
使用更先进的蚁群算法,如基于粒子群算法的蚁群算法、基于遗传算法的蚁群算法等
还有,对于280个城市的 TSP问题来说,蚁群算法并不是比较有效的做法,相对来说更高效的解决办法可以考虑 2-opt,3-opt等更优秀的算法。