八皇后问题遗传算法实现(C语言)
八皇后问题的遗传算法实现过程详解
1、八皇后问题描述
19 世纪著名的数学家Gauss 在1850 年提出八皇后问题后, 该问题成为各类语言程序设计的经典题目。八皇后问题要求在8×8 格的国际象棋上摆放八个皇后,使横、竖、斜方向上都不能有两个及两个以上皇后在同一条直线上, 问题也可以推广到N 个皇后。穷举法在问题规模不大的情况下还可适用,回溯法是求解此问题的经典算法。但N 皇后问题是个NP 难问题, 随着皇后数目的增多, 求解复杂度激增, 就需利用非常规的技术求
解。遗传算法在求解一些NP 完全问题上得到了广泛地应用,本文用遗传算法求解八皇后问题,给出详细的实现过程。
2、基本遗传算法求解过程
基本遗传以初始种群为基点, 经过选择、交叉、变异操作生成新的种群,如此更新种群直到满足终止条件。其计算步骤如下:
(1) 将问题空间转换为遗传空间, 也就是编
码;
(2)随机生成P 个染色体作为初始种群;
(3)染色体评价,也就是按确定的适应度函数
计算各个染色体的适应度;
(4)根据染色体适应度,按选择算子进行染色
体的选择;
(5)按交叉概率进行交叉操作;
(6)按变异概率进行变异操作;
(7)返回(4)形成新的种群,继续迭代,直到满足终止条件。
基本遗传算法给出了基本框架, 针对求解的问题不同, 遗传算法在相应的计算步骤中有不同的设计。本文针对八皇后问题, 设计了相应的编码,适应度计算方法,交叉和变异操作。
3、用遗传算法求解八皇后问题实现过程详解
3.1 编码
遗传算法中传统的编码是二进制编码, 本文采用多值编码。染色体长度取决于皇后的个数。染色体中每个基因所处的位置表示其在棋谱中所在的行数, 基因值表示其所在的列数。如染色体40752613 表示:从0 开始数,第0 个4 表示在第零行的皇后在第4 列, 第1 个0 表示第一行的皇后在第0 列,以此类推。八皇后问题中皇后不能处于同行同列, 意味着染色体中0~7 的基因取值不能出现重复。
3.2 个体评价
染色体通常表示了问题的可行解, 对可行解进行遗传操作寻找最优解。但在八皇后问题中,染色体仅仅体现同行同列中未出现互攻, 在对角线上是否出现互攻还未做考虑。在对皇后的位置做比较的时候, 可以对两个棋子的行数差与列数差进行对比, 实现了互攻次数的统计。公式为:|绝对值((y2-y1)/(x2-x1)) |=1。公式中(x1,y1),(x2,y2)分别表示两个皇后所在的位置,即所在的行数和列数。当两个皇后的行数差与列数差比值的绝对值为1 的时候,两皇后在同一对角线上,即出现了互攻。每个染色体内的互攻次数为Value,初始值设为0;第0 行与1~7 行进行比较, 每出现一次互攻则Value 的值增加1;第1 行与2~7 行进行比较,以此类推来计算Value 值。当Value 为0 表示没有发生互攻,此染色体就是其中的一个可行解。当Value 不为0则进行适应度的计算。一般来说, 适应度越大越
好,而互攻次数为越小越好,所以可以将适应度的计算函数设置为:F=28-Value。
3.3 选择
选择使用的是经典的赌轮选择方法, 与基本遗传算法的实现无特别之处,此处不赘述。
3.4 交叉
经典的单点, 多点等交叉因染色体中不能出现重复的基因值,在该问题中不适用。本文使用部分匹配交叉,具体操作如下:
1)在染色体中随机选取两个点标记为y,
如:染色体a:01y24y3675;
染色体b:12y30y4576;
两个y 之间的基因段称为中间段, 记录其对应关系2-3,4-0;
2)对染色体a,b 的中间段进行交换,
形成染色体a':01y30y3675;染色体b': 12y24y4576;
3) 利用对应关系,对染色体a', b' 中间段外的基因进行交换,
形成 染色体a'': 41y30y2675;
染色体b'': 13y24y0576;
交叉完成。
3.5 变异
采用多值编码后, 变异操作并不能通过简单的0,1 反转实现。
本文采取随机地选取染色体内的两个基因进行交换来实现。
例如随机选取的是
6 和1 两个基因,那么
变异前染色体: 7 (6) 5 4 3 2 (1) 0
变异后染色体: 7 (1) 5 4 3 2 (6) 0
3.6 终止策略
本文采用的终止策略为: 当群体中出现染色体的适应值为0 时, 即表示算法搜索到了一个可行解,终止算法。若算法运行设置的代数还未找到可行解,同样终止程序运行。
4、总结
本文详细介绍了用遗传算法求解八皇后问题的求解过程, 但要注意的是这只是其中的一种编码,交叉,变异等操作设计方法,还有许多其他的方法可以选择。对于各操作采取不同设计方案的遗传算法,其算法性能值得比较讨论。
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <time.h> 4 #include <stdbool.h> 5 #include <math.h> 6 7 // 8 // 编程题 9 // 遗传算法(八皇后问题) 10 // 11 12 13 #define N 8 //皇后数 14 #define Cluster_size 12//默认种群大小 15 #define LASTG 100 /*终止后代*/ 16 #define MRATE 0.8 /*突变的概率*/ 17 int array[Cluster_size][N];//染色体集合 18 int copyarray[Cluster_size][N];;//array的副本 19 int narray[Cluster_size * 2][N];//下一代染色体集合 20 int values[Cluster_size];//评估数组 21 int max_array[N];//保存最佳数组 22 int generation = 0; //记录代数 23 int signal = -1;//信号 24 int max=-1;//记录当前最优值 25 int max_generation;//记录当前最优值代数 26 27 28 struct MyStruct 29 { 30 int key[Cluster_size]; 31 int values[Cluster_size]; 32 } rember; //交叉时记录对应关系 33 34 35 /* 36 1、八皇后问题描述 37 19 世纪著名的数学家Gauss 在1850 年提出 38 八皇后问题后, 该问题成为各类语言程序设计的 39 经典题目。八皇后问题要求在8×8 格的国际象棋 40 上摆放八个皇后,使横、竖、斜方向上都不能有两 41 个及两个以上皇后在同一条直线上, 问题也可以 42 推广到N 个皇后。穷举法在问题规模不大的情况 43 下还可适用,回溯法是求解此问题的经典算法。但 44 N 皇后问题是个NP 难问题, 随着皇后数目的增 45 多, 求解复杂度激增, 就需利用非常规的技术求 46 解。遗传算法在求解一些NP 完全问题上得到了 47 广泛地应用,本文用遗传算法求解八皇后问题,给 48 出详细的实现过程。 49 */ 50 51 52 /* 基本遗传算法求解过程 53 基本遗传以初始种群为基点, 经过选择、交 54 叉、变异操作生成新的种群,如此更新种群直到满 55 足终止条件。其计算步骤如下: 56 (1) 将问题空间转换为遗传空间, 也就是编 57 码; 58 (2)随机生成P 个染色体作为初始种群; 59 (3)染色体评价,也就是按确定的适应度函数 60 计算各个染色体的适应度; 61 (4)根据染色体适应度,按选择算子进行染色 62 体的选择; 63 (5)按交叉概率进行交叉操作; 64 (6)按变异概率进行变异操作; 65 (7)返回(4)形成新的种群,继续迭代,直到满 66 足终止条件。*/ 67 68 //用遗传算法求解八皇后问题实现过程详解 69 70 71 /*1 编码 72 遗传算法中传统的编码是二进制编码, 本文 73 采用多值编码。染色体长度取决于皇后的个数。染 74 色体中每个基因所处的位置表示其在棋谱中所在 75 的行数, 基因值表示其所在的列数。如染色体 76 40752613 表示:从0 开始数,第0 个4 表示在第 77 零行的皇后在第4 列, 第1 个0 表示第一行的皇 78 后在第0 列,以此类推。八皇后问题中皇后不能处 79 于同行同列, 意味着染色体中0~7 的基因取值不 80 能出现重复*/ 81 82 83 /*2 个体评价 84 染色体通常表示了问题的可行解, 对可行解 85 进行遗传操作寻找最优解。但在八皇后问题中,染 86 色体仅仅体现同行同列中未出现互攻, 在对角线 87 上是否出现互攻还未做考虑。在对皇后的位置做 88 比较的时候, 可以对两个棋子的行数差与列数差 89 进行对比, 实现了互攻次数的统计。公式为: 90 |(y2-y1)/(x2-x1)|=1。公式中(x1,y1),(x2,y2)分别表示两个 91 皇后所在的位置,即所在的行数和列数。当两个皇 92 后的行数差与列数差比值的绝对值为1 的时候, 93 两皇后在同一对角线上,即出现了互攻。每个染色 94 体内的互攻次数为Value,初始值设为0;第0 行 95 与1~7 行进行比较, 每出现一次互攻则Value 的 96 值增加1;第1 行与2~7 行进行比较,以此类推来 97 计算Value 值。当Value 为0 表示没有发生互攻, 98 此染色体就是其中的一个可行解。当Value 不为0 99 则进行适应度的计算。一般来说, 适应度越大越 100 好,而互攻次数为越小越好,所以可以将适应度的 101 计算函数设置为:F=1/Value。*/ 102 103 104 105 106 107 /*编码方案 108 遗传算法的常用编码方案有排列编码、二进制编码、实值编码等,考虑到编码方案需要较好地对应一种棋盘皇后排列顺序, 109 同时八皇后问题需要解决的是实体目标(即皇后)的排列问题,不涉及到浮点数层面的逼近问题,本程序采用排列编码作为编码方案,具体描述如下: 110 用一维n元数组x0,1…,n-1来表示一个个体,其中x[i]∈{0,1…,n-1},x[i]表示皇后i放在棋盘的第i行第x[i]列,即第i行第x[i]列放置一个皇后。 111 例如,x[0]=0表示棋盘的第0行第0列放一个皇后。数组第i个元素表示第i行的放置情况,可以看作一个基因。 112 这种编码可以自然的解决了某一行只能放一个皇后的约束,如果数组的每一个元素x[i]都不重复,可以看成0 — 7的一种排列,就自然保证每一列只能放一个皇后。 113 在编码方案实现过程中,我们对染色体编码是否可重复问题进行了讨论,经实验发现不允许染色体编码重复的方案, 114 即每一个编码必须为0-7排列的编码方案的搜索空间为8!种,而允许编码出现重复的方案搜索空间为8^8种, 115 在实验运行过程中第一种编码方案运行所需代数平均值比第二种方案要小一个数量级,因此最终决定采用了不允许染色体编码重复的方案, 116 n元数组x[0,1…,n-1]中,每一个x[i]不允许重复,在程序运行过程中,无论是初始种群生成,选择,交叉,变异阶段都会维护这一编码准则。 117 */ 118 119 120 /*初始种群 121 初始化种群的主要工作为:确定种群的大小及产生初始种群.种群的大小能够对遗传算法的收敛性产生很大的影响, 122 种群较小算法收敛速度较快,但它的搜索面不够广,容易导致局部收敛;而种群较大算法收敛全局最优的概率也大, 123 但是算法的收敛速度较慢。根据N皇后问题的特点,默认初始种群大小一般为N ~ 2N (N为皇后数)。经多次实验, 124 初始种群大小的设置从8、12、16、24没有较大区别,对遗传代数没有突出影响,因此将默认初始种群大小设为12,界面中提供了用户自行设定初始种群大小的方法。 125 除此之外,程序提供了两种初始种群的生成方法,第一种是随机生成,程序将自动生成用户设定数量的随机个体作为初始种群, 126 第二种是用户输入,程序初始种群一栏提供了用户自行输入每一个个体基因编码的接口。值得注意的是,以上无论哪种方法, 127 生成的都是0-7不含重复的8位随机排列。系统不会接受任何编码出现重复的非法个体。 128 */ 129 130 131 132 int rndn(int l) 133 { 134 int rndno; 135 rndno = rand()%l; 136 return rndno; 137 138 } 139 140 141 void output_copy_array() 142 { 143 for (int i = 0; i < Cluster_size; i++) 144 { 145 for (int j = 0; j < N; j++) 146 printf("%d", copyarray[i][j]); 147 printf("\n"); 148 } 149 } 150 151 152 153 void output_maxarray() 154 { 155 for (int i = 0; i < N; i++) 156 printf("%d", max_array[i]); 157 } 158 159 160 161 162 163 164 //判断是否有最优解 165 int the_answer(int* values, int size) 166 { 167 for (int i = 0; i < size; i++) 168 if (values[i] == 28) 169 return i; 170 return -1; 171 } 172 173 174 175 int judge(int a[], int n) 176 { 177 int i, j; 178 int value = -1; 179 for (i = 0; i < n; i++) { 180 value = a[i]; 181 for (j = i + 1; j < n; j++) { 182 if ((value == a[j])) { 183 return 0; 184 } 185 } 186 } 187 return 1; 188 189 } 190 191 192 193 194 195 //计算初始适应度值 196 void count_collidecount() //适应度函数设置为:value[i]=28-value 197 { 198 199 int i, j, x1, x2, y1, y2, m, value = 0; 200 for (i = 0; i < Cluster_size; i++) { 201 202 for (j = 0; j < N; j++) 203 { 204 x1 = j; 205 y1 = array[i][j]; 206 for (m = j + 1; m < N; m++) 207 { 208 x2 = m; 209 y2 = array[i][m]; 210 if (abs((y2 - y1) / (x2 - x1))==1) 211 value++; 212 } 213 214 } 215 values[i] = 28 - value; 216 value = 0; 217 } 218 219 signal = the_answer(values, Cluster_size); 220 221 } 222 223 224 //计算子代适应度值 225 void count_generation_collidecount(int* values, int cluster_size) 226 { 227 228 int i, j, x1, x2, y1, y2, m, value = 0; 229 for (i = 0; i < cluster_size; i++) { 230 231 for (j = 0; j < N; j++) 232 { 233 x1 = j; 234 y1 = narray[i][j]; 235 for (m = j + 1; m < N; m++) 236 { 237 x2 = m; 238 y2 = narray[i][m]; 239 if (abs((y2 - y1) / (x2 - x1))==1) 240 value++; 241 } 242 243 } 244 values[i] = 28 - value; 245 value = 0; 246 } 247 248 249 } 250 251 252 253 254 255 /************************/ 256 /* selectp()函数 */ 257 /* 父代的选择 */ 258 /************************/ 259 int selectp(int roulette[], int totalfitness) 260 { 261 int i;/* 循环的控制变量 */ 262 int ball;/* 球(选择位置的数值)*/ 263 int acc = 0;/*评价值的累积值*/ 264 265 ball = rndn(totalfitness); 266 for (i = 0; i < Cluster_size; i++) { 267 acc += roulette[i];/*评价值的累积*/ 268 if (acc > ball) break;/*对应的基因*/ 269 } 270 return i; 271 } 272 273 274 275 276 277 278 bool takeoutrepeat(int position)//去除有重复元素的数组,并添加无重复值的数组(染色体) 279 { 280 281 int i; 282 int value; 283 bool signal = true; 284 285 286 for (i = 0; i < N; i++) 287 { 288 value = narray[position*2][i]; 289 for (int j = i + 1; j < N; j++) 290 if (narray[position*2][j] == value) 291 { 292 printf("there have reapt number: %d\n", (position*2)); 293 signal = false; 294 } 295 296 } 297 298 for (i = 0; i < N; i++) 299 { 300 value = narray[position * 2+1][i]; 301 for (int j = i + 1; j < N; j++) 302 if (narray[position * 2+1][j] == value) 303 { 304 printf("there have reapt number: %d\n", (position*2+1)); 305 signal = false; 306 } 307 } 308 309 return signal; 310 311 312 } 313 314 315 //判断两个数组是否相等 316 bool judge_reapt(int c,int cluster) 317 { 318 319 int i,j; 320 int value=0; 321 bool arraysEqual = true; 322 323 for (i=0,j = 0; j < cluster; j++) 324 { 325 while (arraysEqual && i < N) 326 { 327 if (narray[c][i] != copyarray[j][i]) 328 arraysEqual = false; 329 i++; 330 } 331 //显示合适的消息 332 if (arraysEqual) 333 value++; 334 else 335 arraysEqual = true; 336 337 i = 0;//i置0 338 } 339 340 if (value > 0) 341 return false; 342 else 343 return true; 344 345 } 346 347 348 /************************/ 349 /* selection()函数 */ 350 /* 选择下一代 */ 351 /************************/ 352 void selection() 353 { 354 int i, j, c;/* 循环控制参数 */ 355 int totalfitness = 0;/*适应度的总计值*/ 356 int roulette[Cluster_size * 2];/*存放适应度*/ 357 int ball;/* 球(选择位置的数值)*/ 358 int acc = 0;/*适应度的累积值*/ 359 bool judge; 360 361 /*循环进行选择*/ 362 for (i = 0; i < Cluster_size; i++) { 363 /* 生成轮盘 */ 364 totalfitness = 0; 365 count_generation_collidecount(roulette, Cluster_size * 2); 366 367 for (c = 0; c < Cluster_size * 2; ++c) { 368 /*计算适应度的总计值*/ 369 totalfitness += roulette[c]; 370 } 371 signal = the_answer(roulette, Cluster_size * 2);//判断是否有最优解 372 373 do 374 { 375 /*选择一个染色体*/ 376 ball = rndn(totalfitness); 377 acc = 0; 378 for (c = 0; c < Cluster_size * 2; ++c) { 379 acc += roulette[c];/*累积评价值*/ 380 if (acc > ball) break;/*对应的基因*/ 381 } 382 judge= judge_reapt(c, Cluster_size ); 383 384 } while (judge==false); 385 386 387 /*染色体的复制*/ 388 for (j = 0; j < N; ++j) { 389 array[i][j] = narray[c][j]; 390 } 391 } 392 393 for (int q = 0; q< Cluster_size *2; q++) 394 { 395 if (roulette[q] > max) 396 { 397 max = roulette[q]; 398 max_generation = generation; 399 for (int i = 0; i < N; i++) 400 max_array[i] = narray[q][i]; 401 } 402 printf("%3.1d", roulette[q]); 403 404 } 405 printf("\n"); 406 407 } 408 409 410 int judgein(int m, int location1, int location2) 411 { 412 for (int i = location1; i <= location2; i++) 413 if ((m == rember.key[i]) | (m == rember.values[i])) 414 return i; 415 return -1; 416 } 417 418 419 420 421 /************************/ 422 /* crossing()函数 */ 423 /* 特定2染色体的交叉 */ 424 /************************/ 425 void crossing(int mama, int papa, int position) 426 { 427 bool signal; 428 int cp1;/*交叉的点*/ 429 int cp2;/*交叉的点*/ 430 int location1; 431 int location2; 432 printf("mama=%d,papa=%d\n", mama, papa); 433 434 do{ 435 436 /*确定交叉点*/ 437 do 438 { 439 cp1 = rndn(N); 440 cp2 = rndn(N); 441 // m = abs((cp2 - cp1)); 442 } while (cp1 == cp2); 443 //printf("%d,%d\n", cp1, cp2); 444 if (cp1 < cp2) 445 { 446 location1 = cp1; 447 location2 = cp2; 448 } 449 else 450 { 451 location1 = cp2; 452 location2 = cp1; 453 } 454 455 456 for (int i = location1; i <= location2; i++) 457 { 458 rember.key[i] = array[mama][i]; 459 rember.values[i] = array[papa][i]; 460 //交换中间段 461 narray[position * 2][i] = array[papa][i]; 462 narray[position * 2 + 1][i] = array[mama][i]; 463 } 464 //利用对应关系,对染色体mama和papa, 中间段外的基因进行交换 465 /*交换前半部分*/ 466 for (int j = 0; j < location1; j++) 467 { 468 int weizhi = judgein(array[mama][j], location1, location2); 469 // printf("weizhi=%d\n", weizhi); 470 if (weizhi == -1) 471 { 472 narray[position * 2][j] = array[mama][j]; 473 } 474 else 475 { 476 if (array[mama][j] == rember.key[weizhi]) 477 narray[position * 2][j] = rember.values[weizhi]; 478 else 479 narray[position * 2][j] = rember.key[weizhi]; 480 } 481 482 weizhi = judgein(array[papa][j], location1, location2); 483 if (weizhi == -1) 484 { 485 narray[position * 2 + 1][j] = array[papa][j]; 486 } 487 else 488 { 489 if (array[papa][j] == rember.key[weizhi]) 490 narray[position * 2 + 1][j] = rember.values[weizhi]; 491 else 492 narray[position * 2 + 1][j] = rember.key[weizhi]; 493 } 494 495 } 496 497 498 ///*交换后半部分*/ 499 for (int j = location2 + 1; j < N; j++) 500 { 501 int weizhi = judgein(array[mama][j], location1, location2); 502 if (weizhi == -1) 503 { 504 narray[position * 2][j] = array[mama][j]; 505 } 506 else 507 { 508 if (array[mama][j] == rember.key[weizhi]) 509 narray[position * 2][j] = rember.values[weizhi]; 510 else 511 narray[position * 2][j] = rember.key[weizhi]; 512 } 513 514 weizhi = judgein(array[papa][j], location1, location2); 515 if (weizhi == -1) 516 { 517 narray[position * 2 + 1][j] = array[papa][j]; 518 } 519 else 520 { 521 if (array[papa][j] == rember.key[weizhi]) 522 narray[position * 2 + 1][j] = rember.values[weizhi]; 523 else 524 narray[position * 2 + 1][j] = rember.key[weizhi]; 525 526 } 527 } 528 529 signal = takeoutrepeat(position); 530 printf("\n--------------signal=%d--------------\n",signal); 531 } while (signal==false); 532 533 534 } 535 536 537 /************************/ 538 /* notval()函数 */ 539 /* */ 540 /************************/ 541 void notval(int i) 542 { 543 int position1; 544 int position2; 545 int temp; //两个基因点交换的中间变量 546 do 547 { 548 position1 = rndn(N); 549 position2 = rndn(N); 550 551 } while (position2 == position1); //当两个变异基因点相同时,循环。 552 553 temp = narray[i][position2]; 554 narray[i][position2] = narray[i][position1]; 555 narray[i][position1] = temp; 556 557 } 558 559 560 561 /***********************/ 562 /* mutation()函数 */ 563 /* 突变 */ 564 /***********************/ 565 void mutation() 566 { 567 int i;/* 循环的控制变量 */ 568 569 for (i = 0; i < Cluster_size * 2; ++i) 570 if ((rndn(100) / 100)<= MRATE) 571 /*染色体突变*/ 572 notval(i); 573 printf("\nmutation is complete\n"); 574 575 } 576 577 578 579 580 void mating() 581 { 582 583 int i; 584 int totalfitness = 0; 585 int roulette[Cluster_size];//存放评价值 586 int mama, papa; //父代的基因的号码 587 588 // 生成轮盘 589 for (i = 0; i < Cluster_size; ++i) 590 { 591 roulette[i] = values[i]; 592 totalfitness += roulette[i]; 593 } 594 595 //选择和交叉的循环 596 for (i = 0; i < Cluster_size; i++) 597 { 598 do { //父代的选择 599 mama = selectp(roulette, totalfitness); 600 papa = selectp(roulette, totalfitness); 601 } while (mama == papa); 602 603 //特定2染色体的交叉 604 crossing(mama, papa, i); 605 } 606 607 } 608 609 610 611 612 613 614 void outputrember() 615 { 616 for (int i = 0; i < N; i++) 617 printf("key=%d,values=%d\n", rember.key[i], rember.values[i]); 618 } 619 620 621 void outputnarray() 622 { 623 for (int i = 0; i < Cluster_size * 2; i++) 624 { 625 if (i % 2 == 0) 626 printf("---------------------------------------------------\n"); 627 for (int j = 0; j < N; j++) 628 printf("%d", narray[i][j]); 629 printf("\n"); 630 } 631 632 } 633 634 void copy_array() 635 { 636 637 for (int i = 0; i < Cluster_size; i++) 638 for (int j = 0; j < N; j++) 639 { 640 copyarray[i][j] = array[i][j]; 641 } 642 } 643 644 645 void outputarray() 646 { 647 for (int i = 0; i < Cluster_size; i++) 648 { 649 for (int j = 0; j < N; j++) 650 printf("%d", array[i][j]); 651 printf("\n"); 652 } 653 654 } 655 656 657 void output() 658 { 659 int i; 660 for (i = 0; i < Cluster_size; i++) 661 { 662 if (values[i] > max) 663 { 664 max = values[i]; 665 max_generation = generation; 666 } 667 printf("%3.1d", values[i]); 668 669 } 670 printf("\n"); 671 } 672 673 674 675 676 677 void init_Cluster() 678 { 679 int a[8]; 680 int x, y; 681 int count = 0; 682 683 for (; count < Cluster_size; count++) 684 { 685 686 for (y = 0; y < 8; y++) 687 { 688 x = rand() % 8; 689 a[y] = x; 690 } 691 692 if (judge(a, 8)) 693 { 694 for (int i = 0; i < 8; i++) 695 { 696 array[count][i] = a[i]; 697 } 698 } 699 else 700 --count; 701 702 } 703 704 } 705 706 707 708 709 int main() 710 { 711 srand((int)time(NULL)); //随机种子 712 init_Cluster(); 713 714 for (; generation < LASTG; generation++) 715 { 716 717 if (signal != -1) 718 break; 719 else 720 { 721 722 printf("\n%d代数\n", generation); 723 count_collidecount(); 724 printf("-------------output------------values----------------------------\n"); 725 output(); 726 printf("-------------outputarray----------------------------------------\n"); 727 outputarray(); 728 mating(); 729 printf("------------- outputarray----------------------------------------\n"); 730 outputarray(); 731 printf("-----------------mating选择交叉---------outputnarray---------------------------\n"); 732 outputnarray(); 733 mutation(); 734 printf("---------- mutation-变异------------outputnarray------------------------------\n"); 735 outputnarray(); 736 printf("-------------outputarray----------------------------------------\n"); 737 outputarray(); 738 copy_array(); 739 printf("--------------------------------------------------------------------\n"); 740 output_copy_array(); 741 printf("------------selection------outputarray下一代种群------------------------------\n"); 742 selection(); 743 outputarray(); 744 } 745 } 746 747 printf("\nsignal = %d, max = %d, max_generation = %d\n", signal,max,max_generation); 748 output_maxarray(); 749 return 0; 750 751 752 }