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 }

 

posted on 2013-05-19 22:45  郁郁思扬  阅读(4092)  评论(0编辑  收藏  举报

导航