蚁群算法

参考段海滨的代码.. TSP 31cities

 

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <string.h>
  4 #include <math.h>
  5 #include <time.h>
  6 
  7 #define DIST_2_CITY(a, b) sqrt((float)((a)[0]-(b)[0])*((a)[0]-(b)[0])+((a)[1]-(b)[1])*((a)[1]-(b)[1]))
  8 
  9 
 10 const int CityNum = 31;                     /* 城市数量 */
 11 const int AntNum = 50;                      /* 蚂蚁数量 */
 12 const int CityCoor[CityNum][2] =            /* 城市坐标 */
 13 {
 14     {1304, 2312}, {3639, 1315}, {4177, 2244}, {3712, 1399}, {3488, 1535},
 15     {3326, 1556}, {3238, 1229}, {4196, 1004}, {4312, 790 }, {4386, 570 },
 16     {3007, 1970}, {2562, 1756}, {2788, 1491}, {2381, 1676}, {1332, 695 },
 17     {3715, 1678}, {3918, 2179}, {4061, 2370}, {3780, 2212}, {3676, 2578},
 18     {4029, 2838}, {4263, 2931}, {3429, 1908}, {3507, 2367}, {3394, 2643},
 19     {3439, 3201}, {2935, 3240}, {3140, 3550}, {2545, 2357}, {2778, 2826},
 20     {2370, 2975}
 21 };
 22 
 23 
 24 const float inittau = 1.0f;                 /* 初始信息量 */
 25 float tau[CityNum][CityNum];                /* τ, 每条路径上的信息量 */
 26 float deltatau[CityNum][CityNum];           /* Δτ, 代表相应路径上的信息素增量 */
 27 float DistMatrix[CityNum][CityNum];         /* 城市距离矩阵 */
 28 float eta[CityNum][CityNum];                /* η, 启发函数,其值eta[i][j] = 1 / DistMatrix[i][j] */
 29 int tabu[AntNum][CityNum];                  /* 禁忌表,tabu[i][j]=1表示蚂蚁i已经走过了j城市 */
 30 int route[AntNum][CityNum];                 /* 保存蚂蚁k的路径的数组为route[k][CityNum] */
 31 
 32 /* 最优解 */
 33 float solution[AntNum];
 34 int BestRoute[CityNum];
 35 float BestSolution;
 36 
 37 
 38 float alpha;                                /* α, 信息启发因子 */
 39 float beta;                                 /* β, 期望启发因子 */
 40 float rho;                                  /* ρ, 信息残留因子 */
 41 float Q;                                    /* 信息素强度 */
 42 
 43 
 44 
 45 
 46 int MaxIter;                                /* 最大迭代次数 */
 47 
 48 
 49 /* 计算适应度(长度) */
 50 float GetFitness( int citypos[] )
 51 {
 52     register int i;
 53     register float sum;
 54 
 55     sum = 0.0f;
 56     for ( i = CityNum - 1; i > 0; i -- )
 57     {
 58         sum += DistMatrix[citypos[i]][citypos[i - 1]];
 59     }
 60     sum += DistMatrix[citypos[0]][citypos[CityNum - 1]];
 61 
 62     return sum;
 63 }
 64 
 65 int main( )
 66 {
 67     register int i, j, k;
 68     int iter, step;
 69     float drand;
 70     float sum, partsum[CityNum];
 71     float tmpq;
 72 
 73     srand( ( unsigned int )time( NULL ) );
 74 
 75     /* 初始化全局参数 */
 76     alpha = 1.0f;
 77     beta = 5.0f;
 78     rho = 0.95f;
 79     Q = 100.0f;
 80     MaxIter = 200;
 81 
 82     /* 获取距离矩阵 */
 83     for ( i = 0; i < CityNum; i ++ )
 84     {
 85         DistMatrix[i][i] = 0.0f;
 86         for ( j = i + 1; j < CityNum; j ++ )
 87         {
 88             DistMatrix[j][i] = DistMatrix[i][j] = DIST_2_CITY( CityCoor[i], CityCoor[j] );
 89         }
 90     }
 91 
 92     /* 初始化启发因子 */
 93     for ( i = 0; i < CityNum; i++ )
 94     {
 95         for ( j = 0; j < CityNum; j++ )
 96         {
 97             tau[i][j] = inittau;
 98             if ( j > i )
 99             {
100                 eta[j][i] = eta[i][j] = 1.0f / DistMatrix[i][j];
101             }
102         }
103     }
104 
105     for ( iter = 0; iter < MaxIter; iter ++ )
106     {
107         /* 初始化蚂蚁 */
108         memset( tabu, 0, sizeof( tabu ) );
109         for ( k = 0; k < AntNum; k++ )
110         {
111             route[k][0] = rand() % CityNum;     /* 设置第k个蚂蚁的起始城市 */
112             tabu[k][route[k][0]] = 1;           /* 填充禁忌表 */
113         }
114 
115         /* 为每只蚂蚁生成完整路径 */
116         for ( k = 0; k < AntNum; k++ )
117         {
118             /* 步进 */
119             for ( step = 1; step < CityNum; step ++ )
120             {
121                 /* 轮盘赌 */
122                 i = 0;
123                 sum = 0.0f;
124 
125                 for ( j = 0; j < CityNum; j ++ )
126                 {
127                     if ( tabu[k][j] == 0 )
128                     {
129                         partsum[i] = pow( tau[route[k][step - 1]][j], alpha ) * pow( eta[route[k][step - 1]][j], beta );
130                         sum += partsum[i];
131                         i ++;
132                     }
133                 }
134 
135                 partsum[0] /= sum;
136                 for ( j = 1; j < i; j ++ )
137                 {
138                     partsum[j] = partsum[j] / sum + partsum[j - 1];
139                 }
140                 partsum[i - 1] = 1.1f;
141 
142                 drand = rand() / ( RAND_MAX + 1.0f );
143                 i = 0;
144                 for ( j = 0; j < CityNum; j ++ )
145                 {
146                     if ( tabu[k][j] == 0 && drand < partsum[i ++] )
147                     {
148                         break;
149                     }
150                 }
151 
152                 tabu[k][j] = 1;         /* 禁忌表置访问标志 */
153                 route[k][step] = j;     /* 保存蚂蚁k的第step步经过的城市 */
154             }
155         }
156 
157 
158         /* 查询最优,并保存 */
159         j = 0;
160         BestSolution = solution[0] = GetFitness( route[0] );
161         for ( k = 1; k < AntNum; k ++ )
162         {
163             solution[k] = GetFitness( route[k] );
164             if ( solution[k] < BestSolution )
165             {
166                 j = k;
167                 BestSolution = solution[k];
168             }
169         }
170         memcpy( BestRoute, route[j], sizeof( BestRoute ) );
171 
172         /* 计算各个路径上的信息素增量 */
173         memset( deltatau, 0, sizeof( deltatau ) );
174         for ( k = 0; k < AntNum; k ++ )
175         {
176             tmpq = Q / solution[k];
177 
178             for ( step = 1; step < CityNum; step ++ )
179             {
180                 deltatau[route[k][step - 1]][route[k][step]] += tmpq;
181                 deltatau[route[k][step]][route[k][step - 1]] += tmpq;
182             }
183             deltatau[route[k][CityNum - 1]][route[k][0]] += tmpq;
184             deltatau[route[k][0]][route[k][CityNum - 1]] += tmpq;
185         }
186 
187         /* 更新路径上的信息素 */
188         for ( i = 0; i < CityNum; i ++ )
189         {
190             for ( j = i + 1; j < CityNum; j ++ )
191             {
192                 tau[i][j] = rho * tau[i][j] + deltatau[i][j];
193 
194                 /* 避免启发信息被路径信息淹没 */
195                 if ( tau[i][j] < 0.00001f ) tau[i][j] = 0.00001f;
196                 else if ( tau[i][j] > 20.0f ) tau[i][j] = 20.0f;
197 
198                 tau[j][i] = tau[i][j];
199             }
200         }
201     }
202 
203 
204     printf( "*-------------------------------------------------------------------------*\n" );
205     printf( "the initialized parameters of ACA are as follows:\n" );
206     printf( "alpha = %f, beta = %f, rho = %f, Q = %f\n", alpha, beta, rho, Q );
207     printf( "the maximum iteration number of ACA is: %d\n", MaxIter );
208     printf( "the shortest length of the path is: %f\n", BestSolution );
209     printf( "the best route is:\n" );
210     for ( i = 0; i < CityNum; i ++ )
211     {
212         printf( "%d ", BestRoute[i] );
213     }
214     printf( "\n" );
215     printf( "*-------------------------------------------------------------------------*\n" );
216 
217 
218     return 0;
219 }

 

posted on 2013-06-28 22:13  郁郁思扬  阅读(796)  评论(0编辑  收藏  举报

导航