1.算法描述蟻群算法是受到對真實螞蟻群覓食行為研究的啟發而提出。生物學研究表明:一群相互協作的螞蟻能夠找到食物和巢穴之間的最短路徑,而單只螞蟻則不能。生物學家經過大量細致觀察研究發現,螞蟻個體之間的行為是相互作用相互影響的。螞蟻在運動過程中,能夠在它所經過的路徑上留下一種稱之為信息素的物質蟻群算法 配時優化,而此物質恰恰是螞蟻個體之間信息傳遞交流的載體。螞蟻在運動時能夠感知這種物質蟻群算法 配時優化,并且習慣于追蹤此物質爬行,當然爬行過程中還會釋放信息素。一條路上的信息素蹤跡越濃,其它螞蟻將以越高的概率跟隨爬行此路徑,從而該路徑上的信息素蹤跡會被加強,因此,由大量螞蟻組成的蟻群的集體行為便表現出一種信息正反饋現象。某一路徑上走過的螞蟻越多,則后來者選擇該路徑的可能性就越大。螞蟻個體之間就是通過這種間接的通信機制實現協同搜索最短路徑的目標的。
蟻群算法是對自然界螞蟻的尋徑方式進行模擬而得出的一種仿生算法。螞蟻在運動過程中,能夠在它所經過的路徑上留下信息素進行信息傳遞,而且螞蟻在運動過程中能夠感知這種物質,并以此來指導自己的運動方向。因此,由大量螞蟻組成的蟻群的集體行為便表現出一種信息正反饋現象:某一路徑上走過的螞蟻越多,則后來者選擇該路徑的概率就越大。
2.仿真效果預覽仿真結果如下:
3.核心程序
%產生障礙物模型
[Obstacle1,Obstacle2] = func_obstacle();
%%
%蟻群算法初始化
Initial_matrix = size(Obstacle1,1);
%保留覓食活動中有殘留的信息素
Res_pher = 8*ones(Initial_matrix*Initial_matrix,Initial_matrix*Initial_matrix);
%迭代次數
Max_iter = 100;
%螞蟻個數
Number = 60;
%起點
Start_point = 1 ;
%終點
End_point = Initial_matrix*Initial_matrix;
%信息素重要性參數
Importance = 1;
%啟發式因子重要性參數
Importance2 = 4;
%螞蟻信息素揮發系數
Rho = 0.2;
%信息素增加強度系數
Enhance_Q = 1;
minkl = 1e50;
mink = 0;
minl = 0;
%障礙物搜搜
D = func_search(Obstacle1);
%障礙物大小
N = size(D,1);
%小方格象素的邊長
Lens = 1;
%終點坐標
Ex = Lens*(mod(End_point,Initial_matrix)-0.5);
if Ex == -0.5
Ex = Initial_matrix-0.5;
end
Ey = Lens*(Initial_matrix+0.5-ceil(End_point/Initial_matrix));
%蟻群算法構造初始化信息
Eta = func_Heuristic_matrix(Initial_matrix,Ex,Ey,End_point,N,Lens);
%爬行路線
Routes = cell(Max_iter,Number);
%每只螞蟻的爬行路線長度
RLen = zeros(Max_iter,Number);
%%
%開始算法
for i1=1:Max_iter
i1
for i2=1:Number
%初始化模糊控制器
%模糊控制器的輸入為蟻群算法的迭代誤差
if i1==1
error = 1;
else
error = mean(mean(Res_pher));
end
%將誤差輸入到模糊控制器
controller = func_fuzzy(error);
%狀態初始化
%初始為起始點
Wpoint = Start_point;
%路線初始化
Wpath = Start_point;
%長度初始化
Wlen = 0;
%禁忌表初始化
Wtl = ones(N);
%已經在初始點了,因此要排除
Wtl(Start_point) = 0;
%鄰接矩陣初始化
Nmatrix = D;
%螞蟻搜索行走
dworks = Nmatrix(Wpoint,:);
dworks1 = find(dworks);
for j=1:length(dworks1)
if Wtl(dworks1(j))==0
dworks(dworks1(j))=0;
end
end
%螞蟻行走過的節點
LJD = find(dworks);
Len_LJD = length(LJD);
%覓食條件
while(Wpoint ~= End_point && Len_LJD >= 1)
%轉輪賭法
PP=zeros(Len_LJD);
for i=1:Len_LJD
PP(i) = (Res_pher(Wpoint,LJD(i))^Importance)*((Eta(LJD(i)))^(Importance2+0.01/controller));
end
%概率分布
sumpp = sum(PP);
PP = PP/sumpp;
Pcum(1) = PP(1);
for i=2:Len_LJD
Pcum(i) = Pcum(i-1) + PP(i);
end
%產生模擬超聲波
%設備發送超聲波出去,產生超聲波脈沖
op_seq = pnseq(6,[1 0 1 1 0 0],[1 0 1 0 0 1]);
%發送超聲波脈沖
op_seq2 = 2*[rand(size(op_seq)),rand(size(op_seq)),rand(size(op_seq)),rand(size(op_seq)),rand(size(op_seq)),op_seq,rand(size(op_seq)),rand(size(op_seq))]-1;
%如果感知前方沒有障礙物,則進行下一個點運動,Pcum用來模擬傳感器的接收信號
%根據接收到的信號分析是否前方有障礙物
op_seq3 = awgn(op_seq2,10+20*randn,'measured');
%根據接收到的超聲波反射信號計算峰值
dout = func_peak(op_seq3,op_seq);
%根據接收到的信號獲得方向,即select。
%判斷是否有回收信號峰值
flag = 0;
[Vmax,Imax] = max(dout);
if Vmax > mean(abs(dout));
flag = 1;%說明檢測到回聲波,則說明有障礙物,則調整角度
end
if flag == 1
Select = find(Pcum>=rand);
%需要調整角度
to_visit = LJD(Select(1));
else
to_visit = LJD(1);
end
%狀態更新和記錄
%路徑增加
Wpath =[Wpath,to_visit];
%路徑長度增加
Wlen = Wlen+Nmatrix(Wpoint,to_visit);
%螞蟻移到下一個節點
Wpoint = to_visit;
for kk=1:N
if Wtl(kk)==0
Nmatrix(Wpoint,kk) = 0;
Nmatrix(kk,Wpoint) = 0;
end
end
%已訪問過的節點從禁忌表中刪除
Wtl(Wpoint) = 0;
dworks = Nmatrix(Wpoint,:);
dworks1 = find(dworks);
for j=1:length(dworks1)
if Wtl(dworks1(j))==0
dworks(j)=0;
end
end
LJD = find(dworks);
%可選節點的個數
Len_LJD = length(LJD);
end
%記下每代每只螞蟻的覓食路線和路線長度
Routes{i1,i2} = Wpath;
if Wpath(end)==End_point
RLen(i1,i2)=Wlen;
if Wlen < minkl
mink = i1;
minl = i2;
minkl= Wlen;
end
else
RLen(i1,i2)=0;
end
end
%第六步:更新信息素
Delta_Tau = zeros(N,N);%更新量初始化
for i2 = 1:Number
if RLen(i1,i2)
ROUT = Routes{i1,i2};
TS = length(ROUT)-1;%跳數
PL_km = RLen(i1,i2);
for s=1:TS
x = ROUT(s);
y = ROUT(s+1);
Delta_Tau(x,y) = Delta_Tau(x,y)+Enhance_Q/PL_km;
Delta_Tau(y,x) = Delta_Tau(y,x)+Enhance_Q/PL_km;
end
end
end
%改進算法,Delta_Tau計算方法的改進。
if sum(sum(Delta_Tau)) > 10;
Res_pher =(1-Rho).*Res_pher+Rho*Delta_Tau;%信息素揮發一部分,新增加一部分
else
Res_pher =(1-Rho).*Res_pher;%信息素揮發一部分,新增加一部分
end
PLK = RLen(i1,:);
minPL(i1)= mean(PLK(find(PLK)))-1;
end
figure
plot(minPL);
grid on
title('收斂曲線');
xlabel('迭代次數');
ylabel('路徑長度');
%繪爬行圖
figure
func_lines(Obstacle2,Routes,Initial_matrix,mink,minl,Lens);
axis([0,20,0,20]);
%顯示模糊規則表
fuzzy;
02_030m