- 起源於解決TSP問題。蟻羣算法在解決規格較小的TSP問題上效果顯著。
實質:(正反饋機制)通過“信息素”的多少來選擇路徑,算法的迭代過程就是“信息素”的積累過程。(最優路徑上螞蟻數量的增加→信息素強度增加→螞蟻選擇概率增大→最優路徑上螞蟻數量更大增加)
“信息素”的積累有三種方法(即螞蟻系統包括三部分):蟻周算法,蟻密算法,蟻量算法。
缺點:收斂速度過慢(在大規模TSP問題中尤爲突出)。
解決方法:
自適應蟻羣算法:對蟻羣算法的狀態轉移概率、信息素揮發因子、信息量等因素採用自適應調節策略爲一種基本改進思路的蟻羣算法。
自適應蟻羣算法中兩個最經典的方法:蟻羣系統(AntColony System, ACS)和最大-最小蟻羣系統(MAX-MINAnt System, MMAS)。
-
蟻周算法、
信息量的增加與本次搜索的整體線路有關,屬於全局信息更新(所有螞蟻都走完一次後纔會更新
若螞蟻經過(i,j)則:
- τ(ij)爲城市i,j的信息素濃度
-
ρ是0-1之間的常數,(1-ρ)表示揮發因子
- derta t(ij)表示在一次旅行後所有經過(i,j)的螞蟻留下的信息素總量。
- 表示第k只螞蟻在本次迭代中在路徑(i,j)上留下的信息素量。
- Q爲常數,Lk表示螞蟻k已經走過的路徑總長度
在信息素的作用下,螞蟻對每條路徑的選擇概率
否則第k只螞蟻在(i,j)留下的信息素爲0
- 是一個啓發式因子
d(i,j)爲城市(i,j)之間的距離
- alpha,信息素重要程度因子;beta啓發函數重要程度因子
實現
-
變量初始化
-
計算城市間距離
-
迭代尋找最佳路徑
- 隨機產生個螞蟻起點
- 遍歷城市
- 記錄迭代最佳城市
- 更新信息表
說明:
-
城市距離矩陣不能爲零,後邊需要取倒數(初始化時可直接eps
-
螞蟻選擇下一城市採用輪盤賭法,可以增大拓展其他路徑選擇的機率
使用輪盤賭法,使用cumsum的原因是,剛開始信息素未積累時,選擇路徑隨機,在信息素積累到一定程度,所選擇的下一個城市大概率是信息素最大的城市
-
初始時信息素濃度都爲1,故哪條路徑都相同
-
禁忌表的作用是,推出未訪問過的城市在選擇城市中用到。迭代過程中的最優路線記錄在禁忌表中
-
所有螞蟻都前進一個城市後禁忌表更新
matlab
clear
% city 城市
% alpha 信息素重要程度因子 【1,4】
% beta 啓發式重要程度因子 【3,5】
% rho 信息素揮發係數
% eta 啓發式因子
% NC 最大迭代次數
% m 螞蟻個數
% n 城市個數
% Q 信息素增強係數
% L 螞蟻已走路徑長度
% d 兩城市間的距離
% tau 信息素矩陣
% tabu 禁忌表
% 城市座標
city = [1304 2312 ; 3639 1315; 4177 2244; 3712 1399; 3488 1535; 3326 1556; 3238 1229; 4196 1044; 4312 790; 4386 570; 3007 1970; 2562 1756; 2788 1491; 2381 1676; 1332 695; 3715 1678; 3918 2179; 4061 2370; 3780 2212; 3676 2578; 4029 2838; 4263 2931; 3429 1980; 3507 2376; 3394 2643; 3439 3201; 2935 3240; 3140 3550; 2545 2357; 2778 2826; 2370 2975];
n = size(city,1);
d = zeros(n,n);
%初始化城市距離矩陣
for i = 1:n
for j = 1:n
if i == j
d(i,j) = eps;
else
d(i,j) = sqrt(sum((city(i,:) - city(j,:)).^2));
end
end
end
%初始化參數
m = 50;
alpha = 1;
beta = 5;
eta = 1./d;
Q = 100;
rho = 0.25;
tau = ones(n,n);
tabu = zeros(m,n);
NC = 100;
iter = 1;%當前迭代次數
r_best = zeros(NC,n); %各代最佳路徑
L_brst = inf.*ones(NC,1); %每一代最佳路徑長度 初始無窮大
%迭代尋找最佳路徑
while iter <= NC
%螞蟻所在城市初始化
start = zeros(m,1);
for i = 1:m
start(i) = randperm(n,1);
end
tabu(:,1) = start;
for i = 2:n
for j = 1:m
visited = tabu(j,1:(i-1));%信息素
%city_vist = 1:N;
%unvisited = ~ismember(city_vist,visited); %這兩句有點妙,作用和下邊循環一樣
unvisited = zeros(1,(n+1-i));%初始化待訪問城市
P = unvisited;
pos = 1;
for k = 1:n
if isempty(find(visited == k)) %待訪問城市
unvisited(pos) = k;
pos = pos +1;
end
end
%根據信息素計算待選擇城市的概率 公式三
for k = 1:length(unvisited)
P(k) = ((tau(visited(end),unvisited(k))^alpha) * (eta(visited(end),unvisited(k))^beta));
end
P = P/sum(P);
%根據概率選擇下一個要訪問的城市(輪盤賭法
pc = cumsum(P);
slc_index = find(pc >= rand); %下一城市索引
slc = unvisited(slc_index(1));
tabu(j,i) = slc;
end
end
%當前最優路線記錄在禁忌表中
if iter >= 2
tabu(1,:) = r_best(iter-1,:);
end
%記錄m只螞蟻迭代的最佳路線長度
L = zeros(1,m);
for i = 1:m
R = tabu(i,:);
L(i) = d(R(n),R(1));%加上最後回到初始城市的距離
for j = 1:(n-1)
L(i) = L(i) + d(R(j),R(j+1));
end
end
%記錄每一代中最短距離
L_best(iter) = min(L);
%記錄每一代最優路徑
pos = find(L == L_best(iter));
r_best(iter,:) = tabu(pos(1),:);
% 更新信息素的值 公式二
Delta_tau = zeros(n,n);
for i = 1:m
for j = 1:(n-1)
Delta_tau(tabu(i,j),tabu(i,j+1)) = Delta_tau(tabu(i,j),tabu(i,j+1)) + Q/L(i);
end
end
%更新路徑上的信息素含量 公式一
tau = (1 - rho).*tau + Delta_tau;
%禁忌表清零
tabu = zeros(m,n);
%每次迭代過程城市連接圖
for i = 1:(n-1)
% 1 各次迭代最優路線的橫座標 2 各次迭代路線的縱座標
plot([city(r_best(iter,i),1),city(r_best(iter,i+1),1)],[city(r_best(iter,i),2),city(r_best(iter,i+1),2)],'bo-');
hold on;
end
plot([city(r_best(iter,n),1),city(r_best(iter,1),1)],[city(r_best(iter,n),2),city(r_best(iter,1),2)],'ro-');
title(['最短路徑:',num2str(L_best(iter))]);
hold off;
time = 0.05;
pause(time);
iter = iter+1;
end
figure(2);
plot(L_best);
title('路徑長度變化曲線');
xlabel('迭代次數');
ylabel('路徑長度數值');
應用:二次分配問題
二次分配問題
將n臺設備分配到n個地點。
參考
https://blog.csdn.net/zj1131190425/article/details/89517223
1;
end
figure(2);
plot(L_best);
title(‘路徑長度變化曲線’);
xlabel(‘迭代次數’);
ylabel(‘路徑長度數值’);
應用:二次分配問題
###### 二次分配問題
將n臺設備分配到n個地點。
參考
https://blog.csdn.net/zj1131190425/article/details/89517223