多目标遗传算法 ------ NSGA-II (部分源码解析) 交叉操作 crossover.c

Posted Hello_BeautifulWorld

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多目标遗传算法 ------ NSGA-II (部分源码解析) 交叉操作 crossover.c相关的知识,希望对你有一定的参考价值。

遗传算法中的交叉操作是 对NSGA-II  源码分析的  最后一部分, 这一部分也是我 从读该算法源代码和看该算法论文理解偏差最大的  函数模块。

这里,首先提一下,遗传算法的  交叉操作、变异操作都是需要设定概率的, 即交叉概率和变异概率。

假设种群个体 大小为  popsize ,  那么交叉操作需要进行 popsize/2 次 ,   变异操作需要进行 popsize 次, 其中每次操作的时候都需要随机生成一个随机数来与给定的概率进行判断,若小于给定的概率则继续执行否则退出该操作。

如果继续操作的话  需要注意一个问题  对两个个体交叉 ,或  对单个个体进行变异  都是对 个体的所有变量  进行操作,其中变异对二进制编码的个体来说是对每个个体的每个变量 的二进制编码的 每个比特位进行变异。

 

 

包装函数,通过对标识位判断编码形式来决定 具体的核心功能 所调用的函数。

 1 /* Crossover routines */
 2 
 3 # include <stdio.h>
 4 # include <stdlib.h>
 5 # include <math.h>
 6 
 7 # include "global.h"
 8 # include "rand.h"
 9 
10 /* Function to cross two individuals */
11 void crossover (individual *parent1, individual *parent2, individual *child1, individual *child2)
12 {
13     if (nreal!=0)
14     {
15         realcross (parent1, parent2, child1, child2);
16     }
17     if (nbin!=0)
18     {
19         bincross (parent1, parent2, child1, child2);
20     }
21     return;
22 }

 

 

实数编码的  两个个体交叉操作, 采用 SBX 方式交叉。需要交叉的两个个体  每个变量  都进行交叉操作。

 1 /* Routine for real variable SBX crossover */
 2 void realcross (individual *parent1, individual *parent2, individual *child1, individual *child2)
 3 {
 4     int i;
 5     double rand;
 6     double y1, y2, yl, yu;
 7     double alpha, beta, betaq;
 8     if (randomperc() <= pcross_real)
 9     {
10         nrealcross++;
11         for (i=0; i<nreal; i++)
12         {
13             if (randomperc() <= 0.5 )
14             {
15                 if (parent1->xreal[i] < parent2->xreal[i])
16                 {
17                     y1 = parent1->xreal[i];
18                     y2 = parent2->xreal[i];
19                 }
20                 else
21                 {
22                     y1 = parent2->xreal[i];
23                     y2 = parent1->xreal[i];
24                 }
25                 if (fabs(parent1->xreal[i]-parent2->xreal[i]) > EPS)
26                 {
27                     yl = min_realvar[i];
28                     yu = max_realvar[i];
29                     rand = randomperc();
30                     beta = 1.0 + (2.0*(y1-yl)/(y2-y1));
31                     alpha = 2.0 - pow(beta,-(eta_c+1.0));
32                     if (rand <= (1.0/alpha))
33                     {
34                         betaq = pow ((rand*alpha),(1.0/(eta_c+1.0)));
35                     }
36                     else
37                     {
38                         betaq = pow ((1.0/(2.0 - rand*alpha)),(1.0/(eta_c+1.0)));
39                     }
40                     child1->xreal[i] = 0.5*((y1+y2)-betaq*(y2-y1));
41                     beta = 1.0 + (2.0*(yu-y2)/(y2-y1));
42                     alpha = 2.0 - pow(beta,-(eta_c+1.0));
43                     if (rand <= (1.0/alpha))
44                     {
45                         betaq = pow ((rand*alpha),(1.0/(eta_c+1.0)));
46                     }
47                     else
48                     {
49                         betaq = pow ((1.0/(2.0 - rand*alpha)),(1.0/(eta_c+1.0)));
50                     }
51                     child2->xreal[i] = 0.5*((y1+y2)+betaq*(y2-y1));
52                     if (child1->xreal[i]<yl)
53                     {
54                         child1->xreal[i]=yl;
55                     }
56                     if (child1->xreal[i]>yu)
57                     {
58                         child1->xreal[i]=yu;
59                     }
60                     if (child2->xreal[i]<yl)
61                     {
62                         child2->xreal[i]=yl;
63                     }
64                     if (child2->xreal[i]>yu)
65                     {
66                         child2->xreal[i]=yu;
67                     }
68                 }
69                 else
70                 {
71                     child1->xreal[i] = parent1->xreal[i];
72                     child2->xreal[i] = parent2->xreal[i];
73                 }
74             }
75             else
76             {
77                 child1->xreal[i] = parent1->xreal[i];
78                 child2->xreal[i] = parent2->xreal[i];
79             }
80         }
81     }
82     else
83     {
84         for (i=0; i<nreal; i++)
85         {
86             child1->xreal[i] = parent1->xreal[i];
87             child2->xreal[i] = parent2->xreal[i];
88         }
89     }
90     return;
91 }

 

 

 

 

二进制编码  的   交叉操作:

(双点 交叉)  两个个体的  每个对应的变量  彼此交叉操作。这里每个变量的 二进制编码 段 随机选取两点, 将中间部门的二进制段  互换,两个交叉点。

 1 /* Routine for two point binary crossover */
 2 void bincross (individual *parent1, individual *parent2, individual *child1, individual *child2)
 3 {
 4     int i, j;
 5     double rand;
 6     int temp, site1, site2;
 7     for (i=0; i<nbin; i++)
 8     {
 9         rand = randomperc();
10         if (rand <= pcross_bin)
11         {
12             nbincross++;
13             site1 = rnd(0,nbits[i]-1);
14             site2 = rnd(0,nbits[i]-1);
15             if (site1 > site2)
16             {
17                 temp = site1;
18                 site1 = site2;
19                 site2 = temp;
20             }
21             for (j=0; j<site1; j++)
22             {
23                 child1->gene[i][j] = parent1->gene[i][j];
24                 child2->gene[i][j] = parent2->gene[i][j];
25             }
26             for (j=site1; j<site2; j++)
27             {
28                 child1->gene[i][j] = parent2->gene[i][j];
29                 child2->gene[i][j] = parent1->gene[i][j];
30             }
31             for (j=site2; j<nbits[i]; j++)
32             {
33                 child1->gene[i][j] = parent1->gene[i][j];
34                 child2->gene[i][j] = parent2->gene[i][j];
35             }
36         }
37         else
38         {
39             for (j=0; j<nbits[i]; j++)
40             {
41                 child1->gene[i][j] = parent1->gene[i][j];
42                 child2->gene[i][j] = parent2->gene[i][j];
43             }
44         }
45     }
46     return;
47 }

 

以上是关于多目标遗传算法 ------ NSGA-II (部分源码解析) 交叉操作 crossover.c的主要内容,如果未能解决你的问题,请参考以下文章

多目标遗传算法 ------ NSGA-II (部分源码解析) 交叉操作 crossover.c

多目标非支配排序遗传算法-NSGA-II(二)

多目标遗传算法 ------ NSGA-II (部分源码解析)状态报告 打印 report.c

多目标遗传算法 ------ NSGA-II (部分源码解析)父子种群合并 merge.c

多目标遗传算法 ------ NSGA-II (部分源码解析)两个个体支配判断 dominance.c

多目标遗传算法 ------ NSGA-II (部分源码解析)辅助变量 双链表操作 list.c