AGSO 萤火虫算法
-- 今天用LUA写了一个萤火虫算法..发现很差....可能写的不对..改天再改一下
1 --算法说明:荧火虫算法 2 3 4 -- ================================初始化开始================================ 5 domx = { { -1, 2 }, { -1, 2 } }; -- 定义域 6 rho = 0.4 --荧光素挥发因子 7 gamma = 0.6 -- 适应度提取比例 8 beta = 0.08 -- 邻域变化率 9 nt = 5 -- 邻域阀值(邻域荧火虫数) 10 s = 0.3 -- 步长 11 s1 = 0.03 -- 局部最优扰动 12 iot0 = 5 -- 荧光素浓度 13 rs = 1.5 -- 感知半径 14 r0 = 1.5 -- 决策半径 15 -- ================================初始化结束================================ 16 17 -- ===============================分配空间开始=============================== 18 m = 2 -- 解空间维数 19 n = 30 -- 群规模 20 gaddress = {} -- 分配荧火虫地址空间 21 gvalue = {} -- 分配适应度存放空间 22 ioti = {} -- 分配荧光素存放空间 23 rdi = {} -- 分配荧火虫决策半径存放空间 24 -- ===============================分配空间结束=============================== 25 26 27 -- ===================================函数=================================== 28 sin = math.sin 29 sqrt = math.sqrt 30 pi = math.pi 31 random = math.random 32 33 -- 求解函数 34 function maxfun(x) 35 return 4 - (x[1] * sin( 4 * pi * x[1]) - x[2] * sin(4 * pi * x[2] + pi + 1)) 36 end 37 38 -- 求2范数 维数相关 39 function norm(xi, xj) 40 return sqrt((xi[1] - xj[1]) ^ 2 + (xi[2] - xj[2]) ^ 2) 41 end 42 43 print(maxfun({1.88, 1.81})) 44 print(maxfun({1.8506610777502, 1.8685277417146})) -- 6.8987454465589 45 46 47 -- ===========================荧火虫常量初始化开始============================ 48 math.randomseed(os.time()) 49 50 -- 初始化个体 51 for i = 1, n do 52 gaddress[i] = {} 53 for j = 1, m do 54 gaddress[i][j] = domx[j][1] + (domx[j][2] - domx[j][1]) * random() 55 end 56 end 57 58 -- 初始化荧光素 59 for i = 1, n do 60 ioti[i] = iot0 61 end 62 63 64 -- 初始化决策半径 65 for i = 1, n do 66 rdi[i] = r0 67 end 68 -- ===========================荧火虫常量初始化结束============================ 69 70 71 -- =============================iter_max迭代开始============================= 72 73 -- 最大迭代次数 74 iter_max = 20 75 76 for iter = 1, iter_max do 77 78 -- 下面我加了一个变异操作 79 j = 1 80 for i = 1, n do 81 gvalue[i] = maxfun(gaddress[i]) 82 if gvalue[j] > gvalue[i] then 83 j = i 84 end 85 end 86 87 for k = 1, m do 88 gaddress[j][k] = domx[k][1] + (domx[k][2] - domx[k][1]) * random() 89 end 90 gvalue[j] = maxfun(gaddress[j]) 91 92 93 -- 更新荧光素 94 for i = 1, n do 95 ioti[i] = (1 - rho) * ioti[i] + gamma * gvalue[i] 96 end 97 98 -- 各荧火虫移动过程开始 99 for i = 1, n do 100 -- 决策半径内找更优点 101 Nit = {} -- 存放荧火虫序号 102 for j = 1, n do 103 if j ~= i and ioti[i] < ioti[j] and norm(gaddress[j], gaddress[i]) < rdi[i] then 104 table.insert(Nit, j) 105 end 106 end 107 108 -- 找下一步移动的点开始 109 Nitnum = #Nit 110 if Nitnum > 0 then 111 112 -- 选出Nit荧光素之差及差的总和 113 Nitioti = {} 114 Denominator = 0 115 for k = 1, Nitnum do 116 Nitioti[k] = ioti[Nit[k]] - ioti[i] 117 Denominator = Denominator + Nitioti[k] 118 end 119 120 -- 求出各个选择概率 121 Nitioti[1] = Nitioti[1] / Denominator 122 for k = 2, Nitnum do 123 Nitioti[k] = Nitioti[k] / Denominator + Nitioti[k - 1] 124 end 125 126 -- 轮盘赌 127 rand = random() 128 idx = 1 129 for k = 1, Nitnum do 130 if rand < Nitioti[k] then 131 idx = Nit[k] 132 break 133 end 134 end 135 136 -- 移动 137 dist = norm(gaddress[idx], gaddress[i]) 138 for k = 1, m do 139 gaddress[i][k] = gaddress[i][k] + s * (gaddress[idx][k] - gaddress[i][k]) / dist 140 if gaddress[i][k] < domx[k][1] then 141 gaddress[i][k] = domx[k][1] 142 elseif gaddress[i][k] > domx[k][2] then 143 gaddress[i][k] = domx[k][2] 144 end 145 end 146 147 -- 更新决策半径 148 rdi[i] = rdi[i] + beta * (nt - Nitnum) 149 if rdi[i] < 0 then 150 rdi[i] = 0 151 elseif rdi[i] > rs then 152 rdi[i] = rs 153 end 154 else 155 for k = 1, m do 156 gaddress[i][k] = gaddress[i][k] + s1 * (random() - 0.5) * (domx[k][2] - domx[k][1]) 157 if gaddress[i][k] < domx[k][1] then 158 gaddress[i][k] = domx[k][1] 159 elseif gaddress[i][k] > domx[k][2] then 160 gaddress[i][k] = domx[k][2] 161 end 162 end 163 end 164 end 165 end 166 167 -- =============================iter_max迭代结束============================= 168 169 170 171 -- =============================输出最优结果开始============================= 172 173 -- 求各个荧火虫的值 174 j = 1 175 for i = 1, m do 176 gvalue[i] = maxfun(gaddress[i]) 177 if gvalue[i] < gvalue[j] then 178 j = i 179 end 180 end 181 182 -- 最大值 183 BestAddress = gaddress[j] 184 print("(" .. BestAddress[1] .. ", " .. BestAddress[2] .. ")\t" .. gvalue[j]) 185 -- =============================输出最优结果结束=============================
C语言版
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <math.h> 5 #include <time.h> 6 7 8 #define RND ((float)rand()/(RAND_MAX + 1)) 9 #define PI (3.14159265359) 10 11 /* 问题相关 */ 12 const int X_DIM = 10; 13 14 15 //double domx[2] = { -30, 30 }; 16 //double get_y( double x[X_DIM] ) 17 //{ 18 // register int i, j; 19 // register double sum, sum1; 20 // 21 // sum = 0.0; 22 // j = X_DIM - 1; 23 // for ( i = 0; i < j; i ++ ) 24 // { 25 // sum1 = x[i + 1] - x[i] * x[i]; 26 // sum += 100 * sum1 * sum1; 27 // sum1 = x[i] - 1; 28 // sum += sum1 * sum1; 29 // } 30 // return sum; 31 //} 32 33 34 double domx[2] = { -100, 100 }; 35 double get_y( double x[X_DIM] ) 36 { 37 register int i; 38 register double sum; 39 40 sum = 0.0; 41 for ( i = 0; i < X_DIM; i ++ ) 42 { 43 sum += x[i] * x[i]; 44 } 45 return sum; 46 } 47 48 49 50 /* 萤火虫结构 */ 51 typedef struct tag_gso 52 { 53 double x[X_DIM]; 54 double l; 55 double rd; 56 double y; 57 } gso_t, *gso_ptr; 58 59 60 /* 参数 */ 61 const int gsonum = 100; /* 种群大小 */ 62 const double initl = 5.0; /* 初始萤光素值 */ 63 const double rho = 0.4; /* 萤光素挥发系数 */ 64 const double gamma = 0.6; /* 适应度影响因子 */ 65 const double beta = 0.08; /* 邻域变化率 */ 66 const double s = 0.8; /* 移动步长 */ 67 const int nt = 5; /* 邻域阀值 */ 68 const double initr = 400; /* 初始决策半径 */ 69 const double rs = 650; /* 最大决策半径 */ 70 71 72 /* 数据定义 */ 73 gso_t gsos[gsonum]; /* 种群 */ 74 gso_t optimum; /* 最优个体 */ 75 double gsodist[gsonum][gsonum]; /* 距离矩阵 */ 76 int tabu[gsonum]; /* 禁忌表 */ 77 int ninum[gsonum]; /* 邻域集 */ 78 int maxiter; /* 最大迭代次数 */ 79 80 81 82 83 double dist_gso( int idx1, int idx2 ) 84 { 85 register int i; 86 register double sum, sum1; 87 88 sum = 0.0; 89 for ( i = 0; i < X_DIM; i ++ ) 90 { 91 sum1 = gsos[idx1].x[i] - gsos[idx2].x[i]; 92 sum += sum1 * sum1; 93 } 94 95 return sqrt( sum ); 96 } 97 98 99 100 void init_single_gso( int idx ) 101 { 102 register int i; 103 104 for ( i = 0; i < X_DIM; i ++ ) 105 { 106 gsos[idx].x[i] = domx[0] + ( domx[1] - domx[0] ) * RND; 107 } 108 gsos[idx].y = get_y( gsos[idx].x ); 109 gsos[idx].l = initl; 110 gsos[idx].rd = initr; 111 112 if ( gsos[idx].y < optimum.y ) 113 { 114 memcpy( &optimum, gsos + idx, sizeof( gso_t ) ); 115 } 116 } 117 118 119 120 void init_gsos() 121 { 122 register int i; 123 124 for ( i = 0; i < gsonum; i ++ ) 125 { 126 init_single_gso( i ); 127 } 128 } 129 130 131 void move_gso( int idx1, int idx2 ) 132 { 133 register int i; 134 135 for ( i = 0; i < X_DIM; i ++ ) 136 { 137 gsos[idx1].x[i] += s * ( gsos[idx2].x[i] - gsos[idx1].x[i] ) / gsodist[idx1][idx2]; 138 139 if ( gsos[idx1].x[i] < domx[0] ) 140 { 141 gsos[idx1].x[i] = domx[0]; 142 } 143 else if ( gsos[idx1].x[i] > domx[1] ) 144 { 145 gsos[idx1].x[i] = domx[1]; 146 } 147 } 148 149 gsos[idx1].y = get_y( gsos[idx1].x ); 150 if ( gsos[idx1].y < optimum.y ) 151 { 152 memcpy( &optimum, gsos + idx1, sizeof( gso_t ) ); 153 } 154 } 155 156 157 158 int main() 159 { 160 int i, j, k; 161 int iter; 162 double sum, partsum[gsonum + 1]; 163 double rnd; 164 165 /* 初始化随机数发生器 */ 166 srand( ( unsigned int )time( NULL ) ); 167 168 /* 无穷大 */ 169 optimum.y = 1000000000000; 170 171 /* 初始化种群 */ 172 init_gsos(); 173 174 /* 置迭代次数 */ 175 maxiter = 5000; 176 177 178 /* 迭代 */ 179 for ( iter = 0; iter < maxiter; iter ++ ) 180 { 181 /* 更新荧光素 */ 182 for ( i = 0; i < gsonum; i ++ ) 183 { 184 gsos[i].l = ( 1 - rho ) * gsos[i].l + gamma / gsos[i].y; 185 } 186 187 /* 清ni集计数 */ 188 memset( ninum, 0, sizeof( ninum ) ); 189 190 for ( i = 0; i < gsonum; i ++ ) 191 { 192 /* 构建ni */ 193 memset( tabu, 0, sizeof( tabu ) ); 194 195 for ( j = 0; j < gsonum; j ++ ) 196 { 197 if ( i != j && gsos[i].l < gsos[j].l ) 198 { 199 gsodist[i][j] = dist_gso( i, j ); 200 if ( gsodist[i][j] < gsos[i].rd ) 201 { 202 tabu[j] = 1; 203 ninum[i] ++; 204 } 205 } 206 } 207 208 if ( ninum[i] > 0 ) 209 { 210 /* 轮盘赌 */ 211 sum = 0.0; 212 for ( j = 0; j < gsonum; j ++ ) 213 { 214 if ( tabu[j] == 1 ) 215 { 216 sum += gsos[j].l - gsos[i].l; 217 } 218 } 219 220 k = 1; 221 partsum[0] = 0.0; 222 for ( j = 0; j < gsonum; j ++ ) 223 { 224 if ( tabu[j] == 1 ) 225 { 226 partsum[k] = partsum[k - 1] + ( gsos[j].l - gsos[i].l ) / sum; 227 k ++; 228 } 229 } 230 partsum[k - 1] = 1.1; 231 232 rnd = RND; 233 k = 1; 234 for ( j = 0; j < gsonum; j ++ ) 235 { 236 if ( tabu[j] == 1 && rnd < partsum[k ++] ) 237 { 238 break; 239 } 240 } 241 242 /* 选出j移动位置 */ 243 move_gso( i, j ); 244 } 245 246 gsos[i].rd += beta * ( nt - ninum[i] ); 247 if ( gsos[i].rd < 0 ) 248 { 249 gsos[i].rd = 0; 250 } 251 else if ( gsos[i].rd > rs ) 252 { 253 gsos[i].rd = rs; 254 } 255 } 256 257 fprintf( stdout, "best=%.15f\n", optimum.y ); 258 } 259 260 return 0; 261 }