蚁群算法

落花浮王杯 提交于 2019-11-26 16:58:32

原理==书上有==懒的写了_(:з」∠)_

 

写了TSP问题,用的数据还是几天前写遗传算法 模拟退火算法解TSP问题的数据,算出来的结果比前面几个算法好多了

x=[41 94;37 84;54 67;25 62;7 64;2 99;68 58;71 44;54 62;83 69;64 60;18 54;22 60;
  83 46;91 38;25 38;24 42;58 69;71 71;74 78;87 76;18 40;13 40;82 7;62 32;58 35;45 21;41 26;44 35;4 50];
n=size(x,1);
d=zeros(n,n);
for i=1:n
    for j=1:n
    if i>j
      d(i,j)=(sum((x(i,:)-x(j,:)).^2)).^0.5;
      d(j,i)=d(i,j);
      if i==j
          d(i,j)=1e-4;
      end
    end
    end
end
%初始参数
m=50; %蚂蚁数量
alpha=1; %信息素重要程度因子
beta=5; %启发函数重要程度因子
rho=0.1; %信息素挥发因子
Q=1; %常系数
Eta=1./d; %启发函数 距离的倒数
Tau=ones(n,n); %信息素矩阵
table=zeros(m,n); %路径记录表
iter=1; %迭代次数初值
iter_max=200; %最大迭代次数
route_best=zeros(iter_max,n); %各代最佳路径
length_best=zeros(iter_max,1); %各代最佳路径的长度
length_ave=zeros(iter_max,1); %各代路径的平均长度

%迭代寻找最佳路径
while iter<=iter_max
%随机产生各个蚂蚁的起点城市
start=zeros(m,1);
for i=1:m
    temp=randperm(n);
    start(i)=temp(1);
end
table(:,1)=start;
citys=1:n;
%m个蚂蚁路径选择
for i=1:m
    %n个城市路径选择
    for j=2:n
        %vis已访问过的城市
        vis=table(i,1:(j-1));
        allow_index=~ismember(citys,vis);
        allows=citys(allow_index); %待访问的城市集合
       p=allows;
       %计算当前访问的最后一个城市与未访问城市间的转移概率
        for k=1:size(allows,2)
        p(k)=Tau(vis(end),allows(k))^alpha*Eta(vis(end),allows(k))^beta;
        end
        p=p/sum(p);
        %轮盘赌选择下一个城市 避免局部最优
        %计算累加转移概率
        pc=cumsum(p);
        index=find(pc>=rand);
        targetcity=allows(index(1));
        table(i,j)=targetcity;
    end
end
        %计算每个蚂蚁路径
        length=zeros(m,1);
        for i=1:m
            route=table(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);
        %m个蚂蚁计算
        for  i=1:m
            %n个城市计算
          for j=1:(n-1)
         %ant cycle system模型
         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;
end
   %显示信息     
   disp(['最短路径:' num2str(route_best(end,:))]);
   disp(['最短距离' num2str(length_best(end,:))]);
   %绘图
   route=route_best(end,:);
   figure
   plot([x(route,1);x(route(1),1)],[x(route,2);x(route(1),2)]);
   grid on;
   for i=1:n
        text(x(i,1),x(i,2),['  ' num2str(i)]);
   end
   text(x(route(1),1),x(route(1),2),'  start');
   text(x(route(end),1),x(route(end),2),'  end');
   xlabel('城市横坐标');
   ylabel('城市纵坐标');
   title(['蚁群算法优化路径 最短距离:',num2str(length_best(end,:))]);
   figure
   plot(1:iter_max,length_best,'b',1:iter_max,length_ave,'r:');
   legend('最短距离','平均距离');
   xlabel('迭代次数');
   ylabel('距离');
   title('各代最短距离和平均距离对比');

 最短路径:1   2   9   3  18  19  20  21  10  11   7   8  14  15  24  25  26  29  28  27  16  17  22  23  30  12  13   4   5   6
最短距离425.8201

 

 

 

 用DFS写了个暴力,可能它这辈子都运算不出来了

30!是1e32级别的,1秒大概1e8次运算,1e32/1e8=1e24 1e24/3600/24/356=3.25e+16年

虽然剪了点枝比30!会小点

#include<iostream>
#include<bits/stdc++.h>
using namespace std;
int c[60]={41 ,94 ,37 ,84 ,54 ,67 ,25 ,62, 7, 64 ,2 ,99 ,68 ,58 ,71 ,44 ,54 ,62 ,83 ,69 ,64 ,60 ,18 ,54 ,22, 60 ,83 ,46, 91 ,38 ,25 ,38 ,24 ,42 ,58 ,69 ,71 ,71, 74 ,78 ,87 ,76 ,18 ,40 ,13 ,40 ,82 ,7 ,62 ,32 ,58 ,35 ,45 ,21 ,41 ,26 ,44 ,35, 4 ,50};
int x[30],y[30],vis[30],route[30],r[30];
double dis[30][30];
double sum=1e7;
void dfs(double all,int n){
if(n==30){

    if(all<sum)
        {sum=all;
        for(int i=0;i<30;i++)
            r[i]=route[i]+1,cout<<r[i]<<" ";
            cout<<"    "<<sum;
        cout<<endl;
        }
        return;
}
if(all>sum)
return;
for(int i=0;i<30;i++)
{
if(!vis[i]){
    vis[i]=1;
    route[n]=i;
    if(n==0)
        dfs(all,n+1);
    if(n>=1&&n!=29)
        dfs(all+dis[i][route[n-1]],n+1);
    if(n==29)
       dfs(all+dis[i][route[n-1]]+dis[route[0]][route[29]],n+1);
    vis[i]=0;
}
}

}
int main()
{
   for(int i=0;i<60;i++){
    if(i%2)
       y[i/2]=c[i];
        else
        x[i/2]=c[i];
   }
    for(int i=0;i<30;i++)
       for(int j=0;j<30;j++){
        if(i>j){
            dis[i][j]=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
        dis[j][i]=dis[i][j];
        }
       }
       dfs(0,0);
       cout<<endl<<endl;
       for(int i=0;i<30;i++)
        cout<<r[i]<<" ";
    return 0;
}

跑了3小时的结果

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!