#pragma warning(disable: 4786)
#include <iostream> 
#include<fstream>
#include<set>
#include <string>
#include <list>
#include <vector>

#include <math.h> 
#include <time.h>
#include <conio.h> 
#include <stdlib.h> 
#include <stdio.h>
#include <stdlib.h>
#include <process.h>
#include <float.h>


using namespace std;

#define N 31 //城市数目 
#define M 31 //蚂蚁数目 

double inittao=1; 
double tao[N][N]; 
double detatao[N][N]; 
double city_distance[N][N]; 
double yita[N][N]; 
int tabu[M][N];  //每一只蚂蚁一行
int route[M][N]; 
double solution[M]; 
int BestRoute[N]; 
double BestSolution= DBL_MAX;  //赋值为double的最大值
double alfa,beta,rou,Q; 
int iteration_times; 

double EvalueSolution(int *a) 

 double dist=0; 
 for(int i=0;i<N-1;i++)dist+=city_distance[a[i]][a[i+1]];
 dist+=city_distance[a[i]][a[0]];
 return dist; 


void InCityXY( double x[], double y[], char *infile ) 

 fstream inxyfile(infile , ios::in   ); 
 if( !inxyfile ) 
 { 
  cout<<"不能打开文件 <"<<infile<<"> file!\n"; 
  exit(0);
 } 
 int i=0;
 while( !inxyfile.eof() )
 {
  inxyfile>>x[i]>>y[i];
  if( ++i >= N ) break;
 }

void initparameter(void)
{
 alfa=1;
 beta=5;
 rou=0.9;
 Q=100;
 iteration_times=300;
  
 double x[N]; 
 double y[N]; 
 InCityXY( x, y, "test.txt" ); 
 
 for(int i=0;i<N;i++) 
  for(int j=i+1;j<N;j++) 
  { 
   city_distance[j][i]=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])); 
   city_distance[i][j]=city_distance[j][i]; 
  } 
  
  // 初始化启发式参数
  for(i=0;i<N;i++) 
   for(int j=0;j<N;j++) 
   { 
    tao[i][j]=inittao; 
    if(j!=i) 
     yita[i][j]=100/city_distance[i][j];  //能见度为距离分之1
   } 
      
}
inline double RandFloat()  
{
 return (rand())/(RAND_MAX+1.0);
}

int roulette_wheel_selection(double A[],int n)
{

 double t=RandFloat();
 int i;
 double d=0.0;
 for(i=0;i<n;i++)
 {
  d+=A[i];
  if(d>t)return i;
 }
 return rand()%n;//这里出现的概率几乎为0,只有在精度丢失时才发生
}  

void initstate()
{
 int i,k;
 for( k=0;k<M;k++) 
  for(i=0;i<N;i++) 
  {
   tabu[k][i]=0;
   route[k][i]=-1;   
  }
  for(k=0;k<M;k++) 
  { 
   int whichcity=k%N;
   route[k][0]=whichcity;  //把蚂蚁放在城市上
   tabu[k][whichcity]=1; 
  }    
}

 

 

 


void main(void) 
{
 
 srand(time(NULL));
 initparameter(); 
 
 
 
 int i,k; 
 
 int times;
 for(times=0; times<iteration_times;times++)//迭代次数
 { 
  initstate();
  int s; 
 //每一只蚂蚁都去寻经
  for(k=0;k<M;k++) 
   for(s=1;s<N;s++)//重复执行直到禁忌表满为止   
   { 
    
    double partsum=0; 
    
    for(int j=0;j<N;j++) 
    { 
     if(tabu[k][j]==0)partsum+=pow(tao[route[k][s-1]][j],alfa)*pow(yita[route[k][s-1]][j],beta); 
    } 
    
    
    double nextpie[N];
    memset(nextpie,0,sizeof(double)*N);
    
    for(j=0;j<N;j++) 
    { 
     if(tabu[k][j]==0) 
      nextpie[j]+=pow(tao[route[k][s-1]][j],alfa)*pow(yita[route[k][s-1]][j],beta)/partsum; 
    } 
    
//赌盘轮循
    int nextcity=roulette_wheel_selection(nextpie,N);
    
    tabu[k][nextcity]=1; 
    route[k][s]=nextcity; 
   } 
   
   
   
   // 更新信息素
   for(i=0;i<N;i++) 
    for(int j=0;j<N;j++) 
     detatao[i][j]=0;
    
    
    for(k=0;k<M;k++) //每一只蚂蚁都有一个solution
    {
     solution[k]=EvalueSolution(route[k]); 
     if(solution[k]<BestSolution) 
     { 
      BestSolution=solution[k]; 
      for(s=0;s<N;s++) 
       BestRoute[s]=route[k][s]; 
     } 
    }
    
    //更新detatao矩阵
    for(k=0;k<M;k++) 
    { 
     for(s=0;s<N-1;s++) 
     {
      detatao[route[k][s]][route[k][s+1]]+=Q/solution[k]; // s->s+1,s=[0,N-1]
     }

     detatao[route[k][N-1]][route[k][0]]+=Q/solution[k];  //N-1->0,此处完成一个循环
    } 
    
    //更新tao矩阵
    for(i=0;i<N;i++) 
     for(int j=0;j<N;j++) 
     { 
      tao[i][j]=rou*tao[i][j]+detatao[i][j]; 
     } 
     
     
     
     
 } 
 
 
 //output the calculating results
 cout<<"*-------------------------------------------------------------------------*"<<endl; 
 cout<<"ACA参数配置如下:"; 
 cout<<"alfa="<<alfa<<", beta="<<beta<<", rou="<<rou<<", Q="<<Q<<endl; 
 cout<<"ACA最大迭代次数为:"<<iteration_times<<endl; 
 cout<<"最短路径为:"<<BestSolution<<endl; 
 cout<<"最优路由为:"<<endl;
 for(i=0;i<N;i++) 
  cout<<BestRoute[i]<<" ";
 
 cout<<endl; 
 cout<<"*-------------------------------------------------------------------------*"<<endl<<endl; 
 system("pause");

 

 

test.txt文件(答案:15601.9)

1304 2312 
3639 1315 
4177 2244 
3712 1399 
3488 1535 
3326 1556 
3238 1229 
4196 1004 
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 1908 
3507 2367 
3394 2643 
3439 3201 
2935 3240 
3140 3550 
2545 2357 
2778 2826 
2370 2975