人工鱼群算法 AFSA
寻优还可以,速度跟不上.. 国产的支持一把
1 -- 人工鱼群算法 AFSA 2 3 -- lua 相关简易操作 4 sin = math.sin 5 cos = math.cos 6 sqrt = math.sqrt 7 pi = math.pi 8 random = math.random 9 exp = math.exp 10 int = math.floor 11 12 -- 获得不同的随机序列 13 math.randomseed(os.time()) 14 15 -- ==============================求解函数============================== 16 dim = 2 -- 解的维数 17 18 domx = { -- 定义域 19 { { -1, 2 }, { -1, 2 } }, 20 { { 2, 4 }, { -1, 1 } }, 21 { { 0, 4 }, { 0, 4 } }, 22 } 23 24 maxfun = { -- 求解函数 25 function(x) return 4 - (x[1] * sin( 4 * pi * x[1]) - x[2] * sin(4 * pi * x[2] + pi + 1)) end , 26 function(x) return exp(x[1] - x[2] * x[2]) / (x[1] * x[1] - x[2]) + (x[1] - 3) ^ 2 end , 27 function(x) return 2 + (x[1] * x[1] + x[2] * x[2]) / 10 - (cos(2 * pi * x[1]) + cos(2 * pi * x[2])) end , 28 } 29 30 funidx = 1 31 -- ==================================================================== 32 33 -- ================================定义================================ 34 fishnum = 60 -- 鱼群大小 35 fishes = {} -- 鱼群 36 visual = 0.1 -- 可视范围 37 delta = 0.05 -- 拥挤因子 38 step = 0.01 -- 步长 39 trynum = 50 -- 尝试次数 40 gbest = {} -- 全局最优 41 neighbour = {} -- 邻居 中间变量 42 itermax = 120 -- 迭代次数 43 -- ==================================================================== 44 45 46 -- ==============================工具函数============================== 47 48 -- 求2范数 维数相关 49 function norm(xi, xj) 50 return sqrt((xi[1] - xj[1]) ^ 2 + (xi[2] - xj[2]) ^ 2) 51 end 52 53 -- 修正范围 54 function fixx(x) 55 dx = domx[funidx] 56 for i = 1, dim do 57 if x[i] < dx[i][1] then 58 x[i] = dx[i][1] 59 elseif x[i] > dx[i][2] then 60 x[i] = dx[i][2] 61 end 62 end 63 end 64 65 -- 鱼群初始化 66 function fishinit() 67 -- 初始化 68 for i = 1, fishnum do 69 fishes[i] = { v = {} } 70 for j = 1, dim do 71 fishes[i][j] = domx[funidx][j][1] + (domx[funidx][j][2] - domx[funidx][j][1]) * random() 72 fishes[i].v[j] = fishes[i][j] 73 end 74 fishes[i].y = maxfun[funidx](fishes[i]) 75 fishes[i].v.y = fishes[i].y 76 end 77 78 visual = domx[funidx][1][2] - domx[funidx][1][1] 79 for j = 2, dim do 80 dist = domx[funidx][j][2] - domx[funidx][j][1] 81 if dist < visual then visual = dist end 82 end 83 84 visual = visual / 8 85 end 86 87 -- 觅食 88 function fishfeed(idx) 89 sign = 0 90 tmppos = {} 91 fish = {} 92 for i = 1, trynum do 93 for j = 1, dim do tmppos[j] = fishes[idx][j] + random() * step * visual end 94 if fishes[idx].y < maxfun[funidx](tmppos) then 95 sign = 1 96 dist = norm(fishes[idx], tmppos) 97 for j = 1, dim do fish[j] = fishes[idx][j] + random() * step * (tmppos[j] - fishes[idx][j]) / dist end 98 break 99 end 100 end 101 102 if sign == 0 then 103 for j = 1, dim do fish[j] = fishes[idx][j] + random() * step end 104 end 105 106 return fish 107 end 108 109 -- 聚集 110 function assemblefish(idx) 111 nfish = 0 112 center = {} 113 neighbour = {} 114 for j = 1, dim do center[j] = 0 end 115 for i = 1, fishnum do 116 if norm(fishes[i], fishes[idx]) < visual then 117 if i ~= idx then table.insert(neighbour, i) end 118 for j = 1, dim do center[j] = center[j] + fishes[i][j] end 119 nfish = nfish + 1 120 end 121 end 122 123 for j = 1, dim do center[j] = center[j] / nfish end 124 center.y = maxfun[funidx](center) 125 126 fish = {} 127 if fishes[idx].y < center.y then 128 dist = norm(fishes[idx], center) 129 for j = 1, dim do fish[j] = fishes[idx][j] + random() * step * (center[j] - fishes[idx][j]) / dist end 130 return fish 131 end 132 133 return fishfeed(idx) 134 end 135 136 -- 追尾 137 function followfish(idx) 138 139 if #neighbour == 0 then return fishfeed(idx) end 140 141 idx1 = neighbour[1] 142 for i = 2, #neighbour do 143 if fishes[neighbour[i]].y > fishes[idx1].y then idx1 = neighbour[i] end 144 end 145 146 if fishes[idx1].y < fishes[idx].y then return fishfeed(idx) end 147 148 fish = {} 149 if fishes[idx1].y / #neighbour > delta * fishes[idx].y then 150 dist = norm(fishes[idx], fishes[idx1]) 151 for j = 1, dim do fish[j] = fishes[idx][j] + random() * step * (fishes[idx1][j] - fishes[idx][j]) / dist end 152 return fish 153 end 154 155 return fishfeed(idx) 156 end 157 158 -- ==================================================================== 159 160 161 162 -- ===============================主函数=============================== 163 function main(idx) 164 -- 功能选择 165 funidx = idx 166 -- 系统初始化 167 fishinit() 168 169 -- 开始迭代 170 for iter = 1, itermax do 171 for i = 1, fishnum do 172 next1 = assemblefish(i) 173 fixx(next1) 174 next1.y = maxfun[funidx](next1) 175 176 next2 = followfish(i) 177 fixx(next2) 178 next2.y = maxfun[funidx](next2) 179 180 if next2.y > next1.y then 181 next1, next2 = next2, next1 182 end 183 184 if next1.y > fishes[i].y then 185 for j = 1, dim do fishes[i][j] = next1[j] end 186 fishes[i].y = next1.y 187 if fishes[i].y > fishes[i].v.y then 188 for j = 1, dim do fishes[i].v[j] = fishes[i][j] end 189 fishes[i].v.y = fishes[i].y 190 end 191 end 192 end 193 end 194 195 maxy = 1 196 for i = 2, fishnum do 197 if fishes[i].y > fishes[maxy].y then maxy = i end 198 end 199 200 gbest = fishes[maxy] 201 202 end 203 204 -- ===============================主函数=============================== 205 206 t1 = os.clock() 207 208 main(1) 209 print(string.format("函数值为: %.8f \t解为: (%.3f, %.3f)", gbest.v.y, gbest.v[1], gbest.v[2])) 210 main(2) 211 print(string.format("函数值为: %.8f \t解为: (%.3f, %.3f)", gbest.v.y, gbest.v[1], gbest.v[2])) 212 main(3) 213 print(string.format("函数值为: %.8f \t解为: (%.3f, %.3f)", gbest.v.y, gbest.v[1], gbest.v[2])) 214 215 t2 = os.clock() 216 217 print("times: ", 1000 * (t2 - t1)) 218 --]]