-- 今天用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 }
来源:http://www.cnblogs.com/javado/archive/2013/05/19/3087765.html