保留精英, 选择函数可能有问题
1 -- 遗传算法 GA 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 -- 获得不同的随机序列 14 math.randomseed(os.time()) 15 16 17 -- ==============================求解函数============================== 18 dim = 2 -- 解的维数 19 20 domx = { -- 定义域 21 { { -1, 2 }, { -1, 2 } }, 22 { { 2, 4 }, { -1, 1 } }, 23 { { 0, 4 }, { 0, 4 } }, 24 } 25 26 maxfun = { -- 求解函数 27 function(x) return 4 - (x[1] * sin( 4 * pi * x[1]) - x[2] * sin(4 * pi * x[2] + pi + 1)) end , 28 function(x) return exp(x[1] - x[2] * x[2]) / (x[1] * x[1] - x[2]) + (x[1] - 3) ^ 2 end , 29 function(x) return 2 + (x[1] * x[1] + x[2] * x[2]) / 10 - (cos(2 * pi * x[1]) + cos(2 * pi * x[2])) end , 30 } 31 32 funidx = 0 33 -- ==================================================================== 34 35 -- ================================定义================================ 36 chromnum = 30 -- 染色体个数 37 chroms = {} -- 染色体 38 px = 0.7 -- 交叉概率 39 pm = 0.2 -- 变异概率 40 deltax = {} -- 编码最小单位 41 gbest = { v = {} } -- 全局最优 42 itermax = 80 -- 迭代次数 43 -- ==================================================================== 44 45 46 -- ==============================工具函数============================== 47 -- 评价函数 48 function getfitness(y) return y end 49 50 -- 染色体群初始化 51 function createchrom() 52 53 for j = 1, dim do 54 deltax[j] = (domx[funidx][j][2] - domx[funidx][j][1]) / 65536 55 end 56 57 for i = 1, chromnum do 58 chroms[i] = { v= {} } 59 for j = 1, dim do 60 chroms[i][j] = int(65536 * random()) 61 chroms[i].v[j] = chroms[i][j] * deltax[j] + domx[funidx][j][1] 62 end 63 chroms[i].y = maxfun[funidx](chroms[i].v) 64 chroms[i].fitness = getfitness(chroms[i].y) 65 end 66 67 maxidx = 1 68 for i = 2, chromnum do 69 if chroms[i].fitness > chroms[maxidx].fitness then 70 maxidx = i 71 end 72 end 73 74 gbest.y = chroms[maxidx].y 75 gbest.fitness = chroms[maxidx].fitness 76 for i = 1, dim do 77 gbest[i] = chroms[maxidx][i] 78 gbest.v[i] = chroms[maxidx].v[i] 79 end 80 81 end 82 83 84 -- 交叉 85 function crosschrom() 86 -- 存储要交叉的索引 87 idxlist = {} 88 for i = 1, chromnum do 89 if random() < px and i ~= gbest then 90 table.insert(idxlist, i) 91 end 92 end 93 94 if #idxlist < 3 then return end 95 96 -- 打乱顺序 97 cnt = #idxlist 98 for i = 1, cnt do 99 idx = int(random() * cnt) + 1 100 if idx ~= i then 101 idxlist[i], idxlist[idx] = idxlist[idx], idxlist[i] 102 end 103 end 104 105 -- 两两交叉 106 for i = 2, cnt, 2 do 107 c1 = chroms[idxlist[i - 1]] 108 c2 = chroms[idxlist[i]] 109 for j = 1, dim do 110 pos = int(random() * 14) + 1 -- 16位染色体,这样写居中一些 111 112 tmpa = bit32.extract(c1[j], 0, pos) 113 tmpb = bit32.extract(c2[j], 0, pos) 114 115 c1[j] = bit32.replace(c1[j], tmpb, 0, pos) 116 c1.v[j] = c1[j] * deltax[j] + domx[funidx][j][1] 117 118 c2[j] = bit32.replace(c2[j], tmpa, 0, pos) 119 c2.v[j] = c2[j] * deltax[j] + domx[funidx][j][1] 120 end 121 122 c1.y = maxfun[funidx](c1.v) 123 c1.fitness = getfitness(c1.y) 124 125 c2.y = maxfun[funidx](c2.v) 126 c2.fitness = getfitness(c2.y) 127 end 128 end 129 130 131 -- 变异 132 function mutatechrom() 133 for i = 1, chromnum do 134 if random() < pm then 135 c = chroms[i] 136 for j = 1, dim do 137 pos = int(random() * 16) 138 c[j] = bit32.bxor(c[j], 2 ^ pos) 139 c.v[j] = c[j] * deltax[j] + domx[funidx][j][1] 140 end 141 c.y = maxfun[funidx](c.v) 142 c.fitness = getfitness(c.y) 143 end 144 end 145 end 146 147 -- 选择 148 function selectchrom() 149 150 sum = 0 151 for i = 1, chromnum do 152 sum = sum + chroms[i].fitness 153 end 154 155 dist = {} 156 dist[1] = chroms[1].fitness / sum 157 for i = 2, chromnum do dist[i] = chroms[i].fitness / sum + dist[i - 1] end 158 dist[chromnum] = 1 159 160 chroms1 = {} 161 for cnt = 1, chromnum do 162 idx = 0 163 rnd = random() 164 for i = 1, chromnum do 165 if rnd < dist[i] then 166 idx = i 167 break 168 end 169 end 170 chroms1[cnt] = { v= {} } 171 for j = 1, dim do 172 chroms1[cnt][j] = chroms[idx][j] 173 chroms1[cnt].v[j] = chroms[idx].v[j] 174 end 175 chroms1[cnt].y = chroms[idx].y 176 chroms1[cnt].fitness = chroms[idx].fitness 177 end 178 179 chroms = chroms1 180 181 minidx = 1 182 maxidx = 1 183 for i = 2, chromnum do 184 if chroms[i].fitness < chroms[minidx].fitness then 185 minidx = i 186 elseif chroms[i].fitness > chroms[maxidx].fitness then 187 maxidx = i 188 end 189 end 190 191 if chroms[minidx].fitness < gbest.fitness then 192 chroms[minidx].fitness = gbest.fitness 193 chroms[minidx].y = gbest.y 194 for i = 1, dim do 195 chroms[minidx][i] = gbest[i] 196 chroms[minidx].v[i] = gbest.v[i] 197 end 198 end 199 200 if chroms[maxidx].fitness > gbest.fitness then 201 gbest.fitness = chroms[maxidx].fitness 202 gbest.y = chroms[maxidx].y 203 for i = 1, dim do 204 gbest[i] = chroms[maxidx][i] 205 gbest.v[i] = chroms[maxidx].v[i] 206 end 207 end 208 end 209 210 -- ==================================================================== 211 212 213 -- ===============================主函数=============================== 214 function main(idx) 215 -- 功能选择 216 funidx = idx 217 -- 系统初始化 218 createchrom() 219 220 -- 开始迭代 221 for iter = 1, itermax do 222 223 crosschrom() 224 225 mutatechrom() 226 227 selectchrom() 228 end 229 end 230 231 -- ===============================主函数=============================== 232 233 t1 = os.clock() 234 235 main(1) 236 print(string.format("函数值为: %.8f \t解为: (%.3f, %.3f)", gbest.y, gbest.v[1], gbest.v[2])) 237 main(2) 238 print(string.format("函数值为: %.8f \t解为: (%.3f, %.3f)", gbest.y, gbest.v[1], gbest.v[2])) 239 main(3) 240 print(string.format("函数值为: %.8f \t解为: (%.3f, %.3f)", gbest.y, gbest.v[1], gbest.v[2])) 241 242 t2 = os.clock() 243 244 print("times: ", 1000 * (t2 - t1))