锦标赛算法c语言,多目标遗传算法 ------ NSGA-II (部分源码解析) 交叉操作 crossover.c(示例代码)...

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

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

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

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

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

1 /*Crossover routines*/

2

3 # include

4 # include

5 # include

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 inti;5 doublerand;6 doubley1, y2, yl, yu;7 doublealpha, beta, betaq;8 if (randomperc() <=pcross_real)9 {10 nrealcross++;11 for (i=0; ixreal[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]xreal[i]=yl;55 }56 if (child1->xreal[i]>yu)57 {58 child1->xreal[i]=yu;59 }60 if (child2->xreal[i]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; ixreal[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 inti, j;5 doublerand;6 inttemp, site1, site2;7 for (i=0; isite2)16 {17 temp =site1;18 site1 =site2;19 site2 =temp;20 }21 for (j=0; jgene[i][j] = parent1->gene[i][j];24 child2->gene[i][j] = parent2->gene[i][j];25 }26 for (j=site1; jgene[i][j] = parent2->gene[i][j];29 child2->gene[i][j] = parent1->gene[i][j];30 }31 for (j=site2; jgene[i][j] = parent1->gene[i][j];34 child2->gene[i][j] = parent2->gene[i][j];35 }36 }37 else

38 {39 for (j=0; jgene[i][j] = parent1->gene[i][j];42 child2->gene[i][j] = parent2->gene[i][j];43 }44 }45 }46 return;47 }

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值