八皇后问题遗传算法实现(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 }

 

posted @ 2020-12-05 11:34  liweikuan  阅读(1220)  评论(0编辑  收藏  举报