蟻羣算法筆記

  • 起源於解決TSP問題。蟻羣算法在解決規格較小的TSP問題上效果顯著。

實質:(正反饋機制)通過“信息素”的多少來選擇路徑,算法的迭代過程就是“信息素”的積累過程。(最優路徑上螞蟻數量的增加→信息素強度增加→螞蟻選擇概率增大→最優路徑上螞蟻數量更大增加)

​ “信息素”的積累有三種方法(即螞蟻系統包括三部分):蟻周算法,蟻密算法,蟻量算法。

缺點:收斂速度過慢(在大規模TSP問題中尤爲突出)。

解決方法:

自適應蟻羣算法:對蟻羣算法的狀態轉移概率、信息素揮發因子、信息量等因素採用自適應調節策略爲一種基本改進思路的蟻羣算法。

自適應蟻羣算法中兩個最經典的方法:蟻羣系統(AntColony System, ACS)和最大-最小蟻羣系統(MAX-MINAnt System, MMAS)。

  • 蟻周算法

    信息量的增加與本次搜索的整體線路有關,屬於全局信息更新(所有螞蟻都走完一次後纔會更新

    若螞蟻經過(i,j)則:
    τij(t+n)=1ρτij(t)+Δτij \tau_{ij}(t+n) = (1-\rho)\cdot\tau_{ij}(t)+\Delta\tau_{ij}

    • τ(ij)爲城市i,j的信息素濃度
  • ρ是0-1之間的常數,(1-ρ)表示揮發因子

    • derta t(ij)表示在一次旅行後所有經過(i,j)的螞蟻留下的信息素總量。

    Δτij=k=1mΔτijk \Delta\tau_{ij}=\sum_{k=1}^m\Delta\tau_{ij}^k

    • Δτijk\Delta\tau_{ij}^k表示第k只螞蟻在本次迭代中在路徑(i,j)上留下的信息素量。

    Δτijk=Q/Lk \Delta\tau_{ij}^k=Q/L_k

    • Q爲常數,Lk表示螞蟻k已經走過的路徑總長度

    在信息素的作用下,螞蟻對每條路徑的選擇概率

    否則第k只螞蟻在(i,j)留下的信息素爲0

    img

    • ηij=1/dij\eta_{ij} = 1/d_{ij}是一個啓發式因子

    ηij=1/dij \eta_{ij} = 1/d_{ij}

    ​ d(i,j)爲城市(i,j)之間的距離

    • alpha,信息素重要程度因子;beta啓發函數重要程度因子
    • img

實現

  1. 變量初始化

  2. 計算城市間距離

  3. 迭代尋找最佳路徑

    • 隨機產生個螞蟻起點
    • 遍歷城市
    • 記錄迭代最佳城市
    • 更新信息表

說明:

  1. 城市距離矩陣不能爲零,後邊需要取倒數(初始化時可直接eps

  2. 螞蟻選擇下一城市採用輪盤賭法,可以增大拓展其他路徑選擇的機率

    使用輪盤賭法,使用cumsum的原因是,剛開始信息素未積累時,選擇路徑隨機,在信息素積累到一定程度,所選擇的下一個城市大概率是信息素最大的城市

  3. 初始時信息素濃度都爲1,故哪條路徑都相同

  4. 禁忌表的作用是,推出未訪問過的城市在選擇城市中用到。迭代過程中的最優路線記錄在禁忌表中

  5. 所有螞蟻都前進一個城市後禁忌表更新

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



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章