蚁群算法:寻食路径选择 (matlab实现)

转载请注明出处:http://blog.csdn.net/microlyc

由 http://blog.csdn.net/ibelievefly/article/details/47955473   旅行商问题改写;

function ant()
Q=400;%Q表示信息素增强的系数
%nc_now表示当前的迭代次数
nc_max=9999; %nc_max表示自主设置的最大迭代时间 表示终止条件
%first_address表示测试数据中的城市坐标
%RouteOfBest表示各代的最佳路线
%LengthOfBest表示每次迭代的最佳路线的长度
a = 3;%a=0.7表示启发因子,表示信息素的相对重要程度!!!!!!!!!!!很重要
p = 0.1;%p表示信息素的蒸发系数,(1-p)表示信息素持久性系数


%%第一步:变量初始化
SumOfant=30;%SumOfant表示蚂蚁数量
first_address = [%第一个为家,最后一个是食物源
    0 3
    0 2
    -10 0    
    1 0
    6 0
    0 -2
    0 -3
    ];%first_address表示测试数据中的城市坐标
target = [1,length(first_address)];
SumOfCity = size(first_address,1);
length_address =inf.*ones(SumOfCity,SumOfCity);%length_address表示两两城市间的距离
length_address(1,2)= Calculation_length(first_address,1,2);
length_address(2,3)= Calculation_length(first_address,2,3);
length_address(3,6)= Calculation_length(first_address,3,6);
length_address(6,7)= Calculation_length(first_address,6,7);
length_address(4,6)= Calculation_length(first_address,4,6);
length_address(2,4)= Calculation_length(first_address,2,4);
length_address(5,6)= Calculation_length(first_address,5,6);
length_address(2,5)= Calculation_length(first_address,2,5);
for   n=1:size(first_address)
    for m=1:size(first_address)
        if length_address(n,m)~=inf
            length_address(m,n)=length_address(n,m);   %对称矩阵
        end
    end
end
info_pre=ones(SumOfCity,SumOfCity);         %info_pre为信息素矩阵,可以理解为在蚂蚁还没有被放入城市前,每条道路上就已经存在了一定含量的信息素(只是为了方便计算)
EachOfRoute=zeros(SumOfant,SumOfCity);      %存储并记录每次迭代时每只蚂蚁经历的路径生成;
nc_now=1;                                   %迭代计数器,记录迭代次数

target_i=target(2).*ones(1,SumOfant);           %每只蚂蚁的目标城市_变化
time_i=zeros(1,SumOfant);
temp_path = zeros(SumOfant,2);%记录每只蚂蚁此刻走的路线
temp_path(:,1)= 1;

while nc_now<=nc_max
    nc_now = nc_now+1;
    flag = zeros(SumOfCity,SumOfCity);%用于这一分钟需要增加信息素的路径
    for i=1:SumOfant
        temp_i = temp_path(i,1);
        temp_j = temp_path(i,2);
        flag_target = 0;
        if time_i(1,i)<=0           
            %记录路径
            if temp_i ==  target(1,1) || temp_i ==  target(1,2)
                EachOfRoute(i,:)=0;%清零
                EachOfRoute(i,1)=temp_i;
            end            
            t =  find(EachOfRoute(i,:)~=0);            
            EachOfRoute(i,length(t)+1)=temp_j;
            
            %到达此程的目标,返程
            if temp_j == target_i(1,i)
                if target_i(1,i) == target(1,1)
                    target_i(1,i) = target(1,2);
                else
                    target_i(1,i) = target(1,1);
                end
                flag_target = 1;
            end
            %记录此时出发城市temp_path(i,1)
            if temp_j ~= 0
                temp_path(i,1)=temp_j;
            end
            
            %选择下一步要到达的城市temp_path(i,2)
            temp_length = length_address(temp_path(i,1),:);%temp_length此城市邻接城市距离
            if flag_target == 0     %如果不在目标处,刚刚的来处设为不可达
                temp_length(1,temp_i) = inf;
            end
            if temp_length(1,target_i(1,i))~= inf;%能直达目标,选择目标
                temp_path(i,2)=target_i(1,i);
            else
                optional_city = find(temp_length(1,:)~= inf);%optional_city此刻可选城市
                if length(optional_city) == 1 %只有一个城市可达
                    temp_path(i,2) = optional_city(1,1);
                else
                    P=optional_city;                      %待访问城市的选择概率分布,用P表示
                    for k=1:length(optional_city)%对每只蚂蚁还没有访问的城市依次计算概率
                        P(k)=(info_pre(temp_path(i,1),optional_city(k)))^a; %a信息素重要程度        %*(sight(temp_path(i,1),optional_city(k))^b);
                    end
                    P=P/(sum(P));
                    %end of 计算待选城市的概率分布
                    
                    %按概率原则选取下一个城市
                    Pcum=cumsum(P);     %cumsum,元素累加即求和         如果A是一个矩阵, cumsum(A) 返回一个和A同行同列的矩阵,矩阵中第m行第n列元素是A中第1行到第m行的所有第n列元素的累加和;
                    Select=find(Pcum>=rand); %若计算的概率大于原来的就选择这条路线
                    temp_path(i,2)=optional_city(Select(1));
                end                
            end
            %选择好的路线i-->j信息素应增加,设标记
            flag(temp_path(i,1),temp_path(i,2))=flag(temp_path(i,1),temp_path(i,2))+1;
            %装载 路线长度
            time_i(1,i)=length_address(temp_path(i,1),temp_path(i,2))-1;
        else%如果还在路线上,未到达城市
            time_i(1,i) = time_i(1,i) -1;
            if time_i(1,i)<=0%经过此刻后到达城市,路线j-->i的信息素应增加,设标记
                flag(temp_j,temp_i)=flag(temp_j,temp_i)+1;
            end
        end
    end%所有蚂蚁路线选择完毕
    %更新这一单位时间的信息素
        info_pre=(1-p).*info_pre+(Q.*flag); %考虑信息素挥发,更新后的信息素
        if nc_now==3%记录第一次到达岔路口时,随机选择结果
            recond=flag;
        end
end%完成所有时间的迭代


subplot(1,2,1)                  %绘制第一个子图形
DrawRoute(first_address,length_address)     %画路地图
hold on
Drawinfo_pre(first_address,info_pre)     %画路信息素
hold on
title('信息素分布')

subplot(1,2,2)                  %绘制第二个子图形
DrawRoute(first_address,length_address)     %画路地图
hold on
for i = 1:SumOfant
    draw_length=length(find(EachOfRoute(i,:)));
    if draw_length>=2
        draw=EachOfRoute(i,1:draw_length);
        Drawpath(first_address,draw)     %画路线图的子函数
        hold on
    end
end
title('蚂蚁分布 ')
recond=1;

function DrawRoute(C,LL)%画地图函数
scatter(C(:,1),C(:,2));
hold on

for   m=1:size(C)
    for n=1:size(C)
        if LL(m,n)~=inf
            plot([C(m,1),C(n,1)],[C(m,2),C(n,2)],'g');
        end
    end
end
hold on
function Drawpath(C,R)%画路线函数
N=length(R);
for ii=2:N
    plot([C(R(ii-1),1),C(R(ii),1)],[C(R(ii-1),2),C(R(ii),2)],'r')
    hold on
end


function Drawinfo_pre(C,LL)%画信息素函数
scatter(C(:,1),C(:,2));
hold on
inf_min=10;%inf_min信息素最小有效值
for   m=1:size(C)
    for n=1:size(C)
        if LL(m,n)>inf_min
            plot([C(m,1),C(n,1)],[C(m,2),C(n,2)],'r');
        end
    end
end
hold on
function [l]= Calculation_length(point,n,m)
l=((point(n,1)-point(m,1))^2+(point(n,2)-point(m,2))^2)^0.5;

    原文作者:蚁群算法
    原文地址: https://blog.csdn.net/microlyc/article/details/78368703
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞