最大最小螞蟻的TSP問題的實現

最近,人工智能課的作業,詳細文檔就不寫了,感興趣可以聯繫我,旨在交流。

  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <string.h>  
  4. #include <time.h>  
  5. #include <math.h>  
  6. #define A 2  
  7. #define B 3  
  8. #define Q 1  
  9. #define N 16  
  10.  
  11. int main()  
  12. {  
  13.     int i,j,k,m,n,q,path[N],sign[N],d[N][N];  
  14.     double l=0.2,min=65535,sum,temp,P,p[N],message[N][N];  
  15.     printf("m=");  
  16.     scanf("%d",&m);//進行m輪運算  
  17.     printf("n=");  
  18.     scanf("%d",&n);//城市個數n  
  19.     for ( i = 0; i < n; i++)//城市距離矩陣d[i][j]  
  20.     {  
  21.         for ( j = 0; j < n; j++)  
  22.         {  
  23.             scanf("%d",&d[i][j]);  
  24.             message[i][j]=1;//初始化信息素矩陣message  
  25.         }  
  26.     }  
  27.     memset(p,0,sizeof(p));  
  28.     srand((unsigned)time(NULL));//初始化隨機數  
  29.  
  30.     for ( i = 0; i < m; i++)//每隻螞蟻的運動  
  31.     {  
  32.         for ( q = 0; q < n; q++)  
  33.         {  
  34.             memset(sign,0,sizeof(sign));//標記螞蟻到過的城市,保證不重複  
  35.             for ( j = 0; j < n; j++)//第j次選擇城市  
  36.             {  
  37.                 if (j == 0)  
  38.                 {  
  39.                     path[0]=q;//螞蟻的出發城市  
  40.                     sign[path[0]]=1;  
  41.                     continue;  
  42.                 }  
  43.  
  44.                 sum=0;  
  45.                 for ( k = 0; k < n; k++)//計算sum  
  46.                 {  
  47.                     if (sign[k] == 0)//沒去過該城市,該城市變爲候選城市  
  48.                     {  
  49.                         sum+=pow(message[path[j-1]][k],A)*pow(1/(double)d[path[j-1]][k],B);  
  50.                     }  
  51.                 }  
  52.                   
  53.                 P=0;//總的概率係數  
  54.                 for ( k = 0; k < n; k++)//計算每個候選城市的概率  
  55.                 {  
  56.                     if (sign[k] == 0)//如果沒去過,則計算  
  57.                     {  
  58.                         p[k]=pow(message[path[j-1]][k],A)*pow(1/(double)d[path[j-1]][k],B)/sum;  
  59.                         P+=p[k];  
  60.                     }  
  61.                     else//如果去過,概率是0  
  62.                     {  
  63.                         p[k]=0;  
  64.                     }  
  65.                 }  
  66.                 if (P < 1)  
  67.                 {  
  68.                     temp=0;  
  69.                 }  
  70.                 else 
  71.                 {  
  72.                     temp=rand()%(int)P;//螞蟻的出發城市隨機生成  
  73.                 }  
  74.                 for ( k = 0; k < n; k++)//輪盤賭法,根據每個城市的概率大小,選擇下一個城市  
  75.                 {  
  76.                     temp-=p[k];  
  77.                     if (temp <= 0&&sign[k] == 0)  
  78.                     {  
  79.                         break;//循環結束時k即爲下一個要去的城市  
  80.                     }  
  81.                 }  
  82.                 path[j]=k;  
  83.                 sign[path[j]]=1;  
  84.             }  
  85.             path[n]=path[0];  
  86.  
  87.             sum=0;  
  88.             for ( k = 0; k < n; k++)  
  89.             {  
  90.                 sum+=d[path[k]][path[k+1]];  
  91.             }  
  92.               
  93.             if (min >= sum)//只允許在當前一直髮生的所有循環中找到最優路徑的螞蟻釋放信息素  
  94.             {  
  95.                 min=sum;  
  96.                 for ( k = 0; k < n; k++)  
  97.                 {  
  98.                     message[path[k]][path[k+1]]=(1-l)*message[path[k]][path[k+1]]+Q/sum;//更新信息素  
  99.                     if (message[path[k]][path[k+1]] > 1)//最大最小螞蟻系統中限定上界下界  
  100.                     {  
  101.                         message[path[k]][path[k+1]]=1;  
  102.                     }  
  103.                     else if (message[path[k]][path[k+1]] < 0.3)  
  104.                     {  
  105.                         message[path[k]][path[k+1]]=0.3;  
  106.                     }  
  107.                 }  
  108.             }  
  109.             for ( k = 0; k < n+1; k++)  
  110.             {  
  111.                 printf("%d ",path[k]);  
  112.             }  
  113.             printf("%lf",sum);  
  114.             printf("\n");  
  115.         }  
  116.     }  
  117.       
  118.     memset(sign,0,sizeof(sign));//標記螞蟻到過的城市,保證不重複  
  119.     for ( i = 0; i < n; i++)//第j次選擇城市  
  120.     {  
  121.         if (i == 0)  
  122.         {  
  123.             path[0]=0;//螞蟻的出發城市  
  124.             sign[path[0]]=1;  
  125.             continue;  
  126.         }  
  127.           
  128.         k=i;  
  129.         for ( j = 0; j < n; j++)  
  130.         {  
  131.             if (message[path[i-1]][j] < message[path[i-1]][k]&&sign[j] == 0)//找到信息素濃度最小的城市  
  132.             {  
  133.                 k=j;  
  134.             }  
  135.         }  
  136.  
  137.         path[i]=k;  
  138.         sign[path[i]]=1;  
  139.     }  
  140.     path[n]=path[0];  
  141.  
  142.     sum=0;  
  143.     for ( k = 0; k < n; k++)  
  144.     {  
  145.         sum+=d[path[k]][path[k+1]];//記錄最優路徑長度  
  146.     }  
  147.     printf("one of the best path:\n");  
  148.     for ( k = 0; k < n; k++)//打印其中一條最優路徑  
  149.     {  
  150.         printf("%d > ",path[k]);  
  151.     }  
  152.     printf("%d ",path[n]);  
  153.     printf("%lf",sum);  
  154.     printf("\n");  
  155.  
  156.     for ( i = 0; i < n; i++)//打印最終的信息素濃度  
  157.     {  
  158.         for ( j = 0; j < n; j++)  
  159.         {  
  160.             printf("%lf ",message[i][j]);  
  161.         }  
  162.         printf("\n");  
  163.     }  
  164.     system("PAUSE");  
  165.     return 0;  

 

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