蚁群算法
参考段海滨的代码.. 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 }