八皇后問題的遺傳算法實現過程詳解
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 }