下面举例来说明遗传算法用以求函数最大值
函数为y = -x2+ 5的最大值,-32<=x<=31
一、编码以及初始种群的产生 编码采用二进制编码,初始种群采用矩阵的形式,每一行表示一个染色体,每一个染色体由若干个基因位组成。关于染色体的长度(即基因位的个数)可根据具体情况而定。比如说根据要求极值的函数的情况,本文-32<=X<=31,该范围内的整数有64个,所以可以取染色体长度为6,(26=64)。综上所述,取染色体长度为6,前5个二进制构成该染色体的值(十进制),第6个表示该染色体的适应度值。若是所取得染色体长度越长,表示解空间搜索范围越大,对应的是待搜索的X范围越大。关于如何将二进制转换为十进制,文后的C代码中函数x即为转换函数。 该初始种群共有4个染色体,第1列表示各个染色体的编号,第2列表示该染色体值的正负号,0表示正,1表示负。第3列到第7列为二进制编码,第8列表示各个染色体的适应度值。第2列到第7列的0-1值都是随机产生的。
二、适应度函数 一般情况下,染色体(也叫个体,或一个解)的适应度函数为目标函数的线性组合。本文直接以目标函数作为适应度函数。即每个染色体的适应度值就是它的目标函数值,f(x)=-x^2+ 5。
三、选择算子 初始种群产生后,要从种群中选出若干个体进行交叉、变异,那么如何选择这些个体呢?选择方法就叫做选择算子。一般有轮盘赌选择法、锦标赛选择法、排序法等。本文采用轮盘赌选择法来选择。
四、交叉算子 那么接下来就要对新种群中选出的两个个体进行交叉操作,一般的交叉方法有单点交叉、两点交叉、多点交叉、均匀交叉、融合交叉。方法不同,效果不同。本文采用最简单的单点交叉。交叉点随机产生。但是交叉操作要在一定的概率下进行,这个概率称为交叉率,一般设置为0.5~0.95之间。通过交叉操作,衍生出子代,以补充被淘汰掉的个体。
五、变异 变异就是对染色体的基因进行变异,使其改变原来的结构(适应值也就改变),达到突变进化的目的。变异操作也要遵从一定的概率来进行,一般设置为0.0001~0.1之间,即以小概率进行基因突变。这符合自然规律。本文的变异方法直接采取基因位反转变异法,即0变为1,1变为0。要进行变异的基因位的选取也是随机的。
六、终止规则 遗传算法是要一代一代更替的,那么什么时候停止迭代呢?这个规则就叫终止规则。一般常用的终止规则有:若干代后终止,得到的解达到一定目标后终止,计算时间达到一定限度后终止等方法。本文采用迭代数来限制。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 #include <stdio.h> #include <conio.h> #include <stdlib.h> #include <time.h> #include <iostream> using namespace std ;const int Population_size = 100 ; const int Chromosome_length = 6 ; double rate_crossover = 0.5 ; double rate_mutation = 0.001 ; int iteration_num = 50 ; typedef struct Chromosome { short int bit[Chromosome_length]; double value; double fitness; double rate_fit; double cumu_fit; }chromosome; void population_initialize(chromosome (&population_current)[Population_size]); void decode (chromosome &population_current) ; double objective_function (double x) ;void fresh_property(chromosome(&population_current)[Population_size]); void seletc_prw(chromosome(&population_current)[Population_size], chromosome(&population_next_generation)[Population_size], chromosome &best_individual); void crossover(chromosome (&population_next_generation)[Population_size]); void mutation(chromosome (&population_next_generation)[Population_size]); void main () { clock_t start, end; start = clock(); chromosome population_current[Population_size]; chromosome population_next_generation[Population_size]; chromosome best_individual; chromosome zeros_chromosome; int i = 0 ,j = 0 ; for (i = 0 ; i < Chromosome_length; i++) zeros_chromosome.bit[i] = 0 ; zeros_chromosome.fitness = 0.0 ; zeros_chromosome.value = 0.0 ; zeros_chromosome.rate_fit = 0.0 ; zeros_chromosome.cumu_fit = 0.0 ; best_individual = zeros_chromosome; for (i = 0 ; i < Population_size; i++) { population_current[i] = zeros_chromosome; population_next_generation[i] = zeros_chromosome; } printf ("\nWelcome to the Genetic Algorithm!\n" ); printf ("The Algorithm is based on the function y = -x^2 + 5 to find the maximum value of the function.\n" ); enter:printf ("\nPlease enter the no. of iterations\n请输入您要设定的迭代数 : " ); scanf_s("%d" , &iteration_num); if (iteration_num <1 ) goto enter; population_initialize(population_current); fresh_property(population_current); for (i = 0 ; i< iteration_num; i++) { seletc_prw(population_current,population_next_generation,best_individual); crossover(population_next_generation); mutation(population_next_generation); fresh_property(population_next_generation); for (i = 0 ; i < Population_size; i++) { population_current[i] = population_next_generation[i]; population_next_generation[i] = zeros_chromosome; } end = clock(); if (double (end - start) / CLK_TCK> 89 ) break ; } printf ("\n 迭代%d次所用时间为: %f\n" , iteration_num, double (end - start) / CLK_TCK); printf ("\n 函数得到最大值为: %f ,适应度为:%f \n" , best_individual.value, best_individual.fitness); for (i = 0 ; i<Population_size; i++) { printf (" population_current[%d]=" , i); for (j = 0 ; j < Chromosome_length; j++) printf (" %d" , population_current[i].bit[j]); printf (" value=%f fitness = %f\n" , population_current[i].value, population_current[i].fitness); } printf ("\nPress any key to end ! " ); system("pause" ); } void population_initialize(chromosome (&population_current)[Population_size]) { int i = 0 , j = 0 ; srand((unsigned )time(NULL )); for (j = 0 ; j<Population_size; j++) { for (i = 0 ; i<Chromosome_length; i++) { population_current[j].bit[i] = rand()% 2 ; } } } void decode (chromosome &population_current) { int i = 0 ; population_current.value = 0 ; for ( i = 0 ; i < Chromosome_length -1 ; i++ ) population_current.value += (double )pow (2 , i) * (double )population_current.bit[i]; if (population_current.bit[Chromosome_length - 1 ] == 1 ) population_current.value = 0 - population_current.value; } double objective_function (double x) { double y; y = -((x - 1 ) *(x - 1 )) + 5 ; return (y); } void fresh_property(chromosome (&population_current)[Population_size]) { int j = 0 ; double sum = 0 ; for (j = 0 ; j < Population_size; j++) { decode(population_current[j]); population_current[j].fitness = objective_function(population_current[j].value); sum = sum + population_current[j].fitness; } population_current[0 ].rate_fit = population_current[0 ].fitness / sum; population_current[0 ].cumu_fit = population_current[0 ].rate_fit; for (j = 1 ; j < Population_size; j++) { population_current[j].rate_fit = population_current[j].fitness / sum; population_current[j].cumu_fit = population_current[j].rate_fit + population_current[j-1 ].cumu_fit; } } void seletc_prw(chromosome (&population_current)[Population_size],chromosome (&population_next_generation)[Population_size],chromosome &best_individual) { int i = 0 , j = 0 ; double rate_rand = 0.0 ; best_individual = population_current[0 ]; srand((unsigned )time(NULL )); for (i = 0 ; i < Population_size; i++) { rate_rand = (float )rand() / (RAND_MAX); if (rate_rand < population_current[0 ].cumu_fit) population_next_generation[i] = population_current[0 ]; else { for (j = 0 ; j < Population_size; j++) { if (population_current[j].cumu_fit <= rate_rand && rate_rand < population_current[j + 1 ].cumu_fit) { population_next_generation[i] = population_current[j + 1 ]; break ; } } } if (population_current[i].fitness > best_individual.fitness) best_individual = population_current[i]; } } void crossover(chromosome (&population_next_generation)[Population_size]) { int i = 0 ,j = 0 ; double rate_rand = 0.0 ; short int bit_temp = 0 ; int num1_rand = 0 , num2_rand = 0 , position_rand = 0 ; srand((unsigned )time(NULL )); for (j = 0 ; j<Population_size; j++) { rate_rand = (float )rand()/(RAND_MAX); if (rate_rand <= rate_crossover) { num1_rand = (int )rand()%(Population_size); num2_rand = (int )rand()%(Population_size); position_rand = (int )rand()%(Chromosome_length - 1 ); for (i = position_rand; i<Chromosome_length; i++) { bit_temp = population_next_generation[num1_rand].bit[i]; population_next_generation[num1_rand].bit[i] = population_next_generation[num2_rand].bit[i]; population_next_generation[num2_rand].bit[i] = bit_temp; } } } } void mutation(chromosome (&population_next_generation)[Population_size]) { int position_rand = 0 ; int i = 0 ; double rate_rand = 0.0 ; srand((unsigned )time(NULL )); for (i = 0 ; i<Population_size; i++) { rate_rand = (float )rand()/(RAND_MAX); if (rate_rand <= rate_mutation) { position_rand = (int )rand()%(Chromosome_length); if (population_next_generation[i].bit[position_rand] == 0 ) population_next_generation[i].bit[position_rand] = 1 ; else population_next_generation[i].bit[position_rand] = 0 ; } } }