八皇后問題遺傳算法實現(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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM