多目标遗传算法 ------ NSGA-II (部分源码解析) 交叉操作 crossover.c
遗传算法中的交叉操作是 对NSGA-II 源码分析的 最后一部分, 这一部分也是我 从读该算法源代码和看该算法论文理解偏差最大的 函数模块。
这里,首先提一下,遗传算法的 交叉操作、变异操作都是需要设定概率的, 即交叉概率和变异概率。
假设种群个体 大小为 popsize , 那么交叉操作需要进行 popsize/2 次 , 变异操作需要进行 popsize 次, 其中每次操作的时候都需要随机生成一个随机数来与给定的概率进行判断,若小于给定的概率则继续执行否则退出该操作。
如果继续操作的话 需要注意一个问题 对两个个体交叉 ,或 对单个个体进行变异 都是对 个体的所有变量 进行操作,其中变异对二进制编码的个体来说是对每个个体的每个变量 的二进制编码的 每个比特位进行变异。
包装函数,通过对标识位判断编码形式来决定 具体的核心功能 所调用的函数。
/* Crossover routines */ # include <stdio.h>
# include <stdlib.h>
# include <math.h> # include "global.h"
# include "rand.h" /* Function to cross two individuals */
void crossover (individual *parent1, individual *parent2, individual *child1, individual *child2)
{
if (nreal!=)
{
realcross (parent1, parent2, child1, child2);
}
if (nbin!=)
{
bincross (parent1, parent2, child1, child2);
}
return;
}
实数编码的 两个个体交叉操作, 采用 SBX 方式交叉。需要交叉的两个个体 每个变量 都进行交叉操作。
/* Routine for real variable SBX crossover */
void realcross (individual *parent1, individual *parent2, individual *child1, individual *child2)
{
int i;
double rand;
double y1, y2, yl, yu;
double alpha, beta, betaq;
if (randomperc() <= pcross_real)
{
nrealcross++;
for (i=; i<nreal; i++)
{
if (randomperc() <= 0.5 )
{
if (parent1->xreal[i] < parent2->xreal[i])
{
y1 = parent1->xreal[i];
y2 = parent2->xreal[i];
}
else
{
y1 = parent2->xreal[i];
y2 = parent1->xreal[i];
}
if (fabs(parent1->xreal[i]-parent2->xreal[i]) > EPS)
{
yl = min_realvar[i];
yu = max_realvar[i];
rand = randomperc();
beta = 1.0 + (2.0*(y1-yl)/(y2-y1));
alpha = 2.0 - pow(beta,-(eta_c+1.0));
if (rand <= (1.0/alpha))
{
betaq = pow ((rand*alpha),(1.0/(eta_c+1.0)));
}
else
{
betaq = pow ((1.0/(2.0 - rand*alpha)),(1.0/(eta_c+1.0)));
}
child1->xreal[i] = 0.5*((y1+y2)-betaq*(y2-y1));
beta = 1.0 + (2.0*(yu-y2)/(y2-y1));
alpha = 2.0 - pow(beta,-(eta_c+1.0));
if (rand <= (1.0/alpha))
{
betaq = pow ((rand*alpha),(1.0/(eta_c+1.0)));
}
else
{
betaq = pow ((1.0/(2.0 - rand*alpha)),(1.0/(eta_c+1.0)));
}
child2->xreal[i] = 0.5*((y1+y2)+betaq*(y2-y1));
if (child1->xreal[i]<yl)
{
child1->xreal[i]=yl;
}
if (child1->xreal[i]>yu)
{
child1->xreal[i]=yu;
}
if (child2->xreal[i]<yl)
{
child2->xreal[i]=yl;
}
if (child2->xreal[i]>yu)
{
child2->xreal[i]=yu;
}
}
else
{
child1->xreal[i] = parent1->xreal[i];
child2->xreal[i] = parent2->xreal[i];
}
}
else
{
child1->xreal[i] = parent1->xreal[i];
child2->xreal[i] = parent2->xreal[i];
}
}
}
else
{
for (i=; i<nreal; i++)
{
child1->xreal[i] = parent1->xreal[i];
child2->xreal[i] = parent2->xreal[i];
}
}
return;
}
二进制编码 的 交叉操作:
(双点 交叉) 两个个体的 每个对应的变量 彼此交叉操作。这里每个变量的 二进制编码 段 随机选取两点, 将中间部门的二进制段 互换,两个交叉点。
/* Routine for two point binary crossover */
void bincross (individual *parent1, individual *parent2, individual *child1, individual *child2)
{
int i, j;
double rand;
int temp, site1, site2;
for (i=; i<nbin; i++)
{
rand = randomperc();
if (rand <= pcross_bin)
{
nbincross++;
site1 = rnd(,nbits[i]-);
site2 = rnd(,nbits[i]-);
if (site1 > site2)
{
temp = site1;
site1 = site2;
site2 = temp;
}
for (j=; j<site1; j++)
{
child1->gene[i][j] = parent1->gene[i][j];
child2->gene[i][j] = parent2->gene[i][j];
}
for (j=site1; j<site2; j++)
{
child1->gene[i][j] = parent2->gene[i][j];
child2->gene[i][j] = parent1->gene[i][j];
}
for (j=site2; j<nbits[i]; j++)
{
child1->gene[i][j] = parent1->gene[i][j];
child2->gene[i][j] = parent2->gene[i][j];
}
}
else
{
for (j=; j<nbits[i]; j++)
{
child1->gene[i][j] = parent1->gene[i][j];
child2->gene[i][j] = parent2->gene[i][j];
}
}
}
return;
}
对于 遗传算法的交叉操作, 有一点是需要注意的 那就是 交叉操作 执行 popsize/2 次, 而且是按照种群个体的排序顺序(按照个体的序号)依次取出两个个体进行交叉操作,而每次执行交叉操作时是否真的进行交叉还要比对随机生成的随机数 与 给定的交叉概率大小 。
多目标遗传算法 ------ NSGA-II (部分源码解析) 交叉操作 crossover.c的更多相关文章
- 多目标遗传算法 ------ NSGA-II (部分源码解析)介绍
NSGA(非支配排序遗传算法).NSGA-II(带精英策略的快速非支配排序遗传算法),都是基于遗传算法的多目标优化算法,是基于pareto最优解讨论的多目标优化. 在官网: http://www.ii ...
- 多目标遗传算法 ------ NSGA-II (部分源码解析)目标函数 problemdef.c
/* Test problem definitions */ # include <stdio.h> # include <stdlib.h> # include <ma ...
- 多目标遗传算法 ------ NSGA-II (部分源码解析)二元锦标赛选择 tourselect.c
tourselect.c 文件中共有两个函数: selection (population *old_pop, population *new_pop) individual* tournament ...
- 多目标遗传算法 ------ NSGA-II (部分源码解析)状态报告 打印 report.c
/* Routines for storing population data into files */ # include <stdio.h> # include <stdlib ...
- 多目标遗传算法 ------ NSGA-II (部分源码解析) 拥挤距离计算 crowddist.c
/* Crowding distance computation routines */ # include <stdio.h> # include <stdlib.h> # ...
- 多目标遗传算法 ------ NSGA-II (部分源码解析)README 算法的部分英文解释
This is the Readme file for NSGA-II code. About the Algorithm--------------------------------------- ...
- 多目标遗传算法 ------ NSGA-II (部分源码解析) 实数、二进制编码的变异操作 mutation.c
遗传算法的变异操作 /* Mutation routines */ # include <stdio.h> # include <stdlib.h> # include < ...
- 多目标遗传算法 ------ NSGA-II (部分源码解析)两个个体支配判断 dominance.c
/* Domination checking routines */ # include <stdio.h> # include <stdlib.h> # include &l ...
- 多目标遗传算法 ------ NSGA-II (部分源码解析) 临时种群生成新父代种群 fillnds.c
/* Nond-domination based selection routines */ # include <stdio.h> # include <stdlib.h> ...
随机推荐
- JSON和JSONP区别
JSON(JavaScript Object Notation)和JSONP(JSON with Padding) JSON是一种数据交换格式,JSONP是一种跨域数据交互协议 JSONP利用scri ...
- 织梦DeDeCms列表分页和内容页分页错位解决办法
文章页分页代码在这里/include/arc.archives.class.php列表页分页/include/arc.listview.class.php 很多入门的站长会碰到这样的问题,织梦的通病, ...
- servlet+jdbc+javabean其实跟ssh差不多
我给的这个架构可以代替ssh的架构进行项目的开发 common中放的是一些公用类 dao中放的是一些对数据的处理 entity其实也就是javabean service中放的是一些抽象类,简单来说抽象 ...
- (转)ThinkPHP使用心得分享-分页类Page的用法
转之--http://www.jb51.net/article/50138.htm ThinkPHP中的Page类在ThinkPHP/Extend/Library/ORG/Util/Page.clas ...
- myeclipse 'no default proposals' when use 'alt + /'.
solution: Window -> Preferences -> Java -> Editor -> Content Assist -> Advanced in th ...
- Python文件操作方法
python中对文件.文件夹(文件操作函数)的操作需要涉及到os模块和shutil模块. 得到当前工作目录,即当前Python脚本工作的目录路径: os.getcwd() 返回指定目录下的所有 ...
- 说说oracle的 sysdate、trunc函数
SQL> select trunc(sysdate)+1/24+3 from dual; TRUNC(SYSDATE)+1/24-------------------2015-08-14 01: ...
- 你真的了解console吗?
对于前端开发者来说,在开发过程中需要监控某些表达式或变量的值的时候,用 debugger 会显得过于笨重,取而代之则是会将值输出到控制台上方便调试.最常用的语句就是console.log(expres ...
- winform 绘制label 中文字 - 摘
private void label2_Paint(object sender, PaintEventArgs e) {//绘制label中文字 string text = "Sri Lan ...
- ACCESS中类型操作(限制、转换)
ACCESS如何保留两位小数 1.可以通过修改表结构中字段的“小数位数”即可. 2.可以通过“更新查询”,将所有该字段的值更新为round(字段名,2) ACCESS如何转换类型 每个函数都可以强制将 ...