• 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 }
  • 相关阅读:
    1093. Count PAT's (25)
    1092. To Buy or Not to Buy (20)
    机器学习实战——k-邻近算法:约会网站
    1057. Stack (30)
    1017. Queueing at Bank (25)
    strcpy、strncpy和memcpy的用法比较
    华为笔试题--蛇形矩阵
    对于内核执行过程的理解
    pom.xml格式问题
    Json反序列化遇到的问题
  • 原文地址:https://www.cnblogs.com/javado/p/3087765.html
Copyright © 2020-2023  润新知