多目标遗传算法 ------ NSGA-II (部分源码解析)二元锦标赛选择 tourselect.c
tourselect.c 文件中共有两个函数:
selection (population *old_pop, population *new_pop)
individual* tournament (individual *ind1, individual *ind2)
首先,第一个函数代码如下:
/* Routine for tournament selection, it creates a new_pop from old_pop by performing tournament selection and the crossover */
void selection (population *old_pop, population *new_pop)
{
int *a1, *a2;
int temp;
int i;
int rand;
individual *parent1, *parent2;
a1 = (int *)malloc(popsize*sizeof(int));
a2 = (int *)malloc(popsize*sizeof(int));
for (i=; i<popsize; i++)
{
a1[i] = a2[i] = i;
}
for (i=; i<popsize; i++)
{
rand = rnd (i, popsize-);
temp = a1[rand];
a1[rand] = a1[i];
a1[i] = temp;
rand = rnd (i, popsize-);
temp = a2[rand];
a2[rand] = a2[i];
a2[i] = temp;
}
for (i=; i<popsize; i+=)
{
parent1 = tournament (&old_pop->ind[a1[i]], &old_pop->ind[a1[i+]]);
parent2 = tournament (&old_pop->ind[a1[i+]], &old_pop->ind[a1[i+]]);
crossover (parent1, parent2, &new_pop->ind[i], &new_pop->ind[i+]);
parent1 = tournament (&old_pop->ind[a2[i]], &old_pop->ind[a2[i+]]);
parent2 = tournament (&old_pop->ind[a2[i+]], &old_pop->ind[a2[i+]]);
crossover (parent1, parent2, &new_pop->ind[i+], &new_pop->ind[i+]);
}
free (a1);
free (a2);
return;
}
其中,
a1 = (int *)malloc(popsize*sizeof(int));
a2 = (int *)malloc(popsize*sizeof(int));
分别生成两个 种群个体大小的数组 a1 a2,这两个数组里面以后会分别保存乱序的种群个体序号。
for (i=; i<popsize; i++)
{
a1[i] = a2[i] = i;
}
对两个数组进行初始话,顺序存放种群个体序号。
for (i=; i<popsize; i++)
{
rand = rnd (i, popsize-);
temp = a1[rand];
a1[rand] = a1[i];
a1[i] = temp;
rand = rnd (i, popsize-);
temp = a2[rand];
a2[rand] = a2[i];
a2[i] = temp;
}
对a1, a2 数组中存放的个体序号打乱,其中打乱的次数为 popsize ,该操作基本保证所有个体的序号基本不在其原有位置上。
(在高级面向对象语言中以上代码可以用一句库函数调用代替)
for (i=; i<popsize; i+=)
{
parent1 = tournament (&old_pop->ind[a1[i]], &old_pop->ind[a1[i+]]);
parent2 = tournament (&old_pop->ind[a1[i+]], &old_pop->ind[a1[i+]]);
crossover (parent1, parent2, &new_pop->ind[i], &new_pop->ind[i+]);
parent1 = tournament (&old_pop->ind[a2[i]], &old_pop->ind[a2[i+]]);
parent2 = tournament (&old_pop->ind[a2[i+]], &old_pop->ind[a2[i+]]);
crossover (parent1, parent2, &new_pop->ind[i+], &new_pop->ind[i+]);
}
这部分代码完成了遗传算法中的 选择操作 和 交叉操作。
其中 old_pop new_pop 都是相同种群个体大小的种群,其种群大小均为 popsize。
tournament 锦标赛法,这里面使用的是二元锦标赛选择法,循环体内共有4次 tournament 操作,该循环共执行 popsize/4 次,故共进行了 popsize 次二元锦标赛选择。由于每次选择出一个新个体,所以该方式选择出的新种群 new_pop 个体数 和 旧种群 old_pop 个体数一致。
同理,crossover 操作进行了 popsize/2 次 , (其中每次进行交叉操作的时候都是选择两个个体,每次判断选择的两个个体是否进行交叉都要根据给定的交叉概率进行判断),该循环体中crossover函数总共会对 popsize 个个体进行处理。
注意: crossover 操作 循环调用 popsize/2 次 而不是 popsize 次。
/* Routine for binary tournament */
individual* tournament (individual *ind1, individual *ind2)
{
int flag;
flag = check_dominance (ind1, ind2);
if (flag==)
{
return (ind1);
}
if (flag==-)
{
return (ind2);
}
if (ind1->crowd_dist > ind2->crowd_dist)
{
return(ind1);
}
if (ind2->crowd_dist > ind1->crowd_dist)
{
return(ind2);
}
if ((randomperc()) <= 0.5)
{
return(ind1);
}
else
{
return(ind2);
}
}
二元锦标赛竞赛法比较简单, 其中调用 check_dominance 函数判断两个个体的支配关系,如果互不支配则判断两个个体的拥挤距离,如果都相同这则随机选择一个个体。
最新文章
- FileInputStream、FileReader、FileInputStream、FileWriter使用小结
- Android 数据传递(二)Activity与fragment之间的通信
- 二、JavaScript语言--事件处理--DOM事件探秘
- js或jquery实现页面打印可局部打印
- HDU 3584 树状数组
- svn代码版本管理总结
- 从web页面启动winform程序的实现方法
- jquery 跳转到当前页面指定位置
- javaNIO学习
- 400. Nth Digit
- Data 语义学(2)
- STL模板_multimap_智能指针作为键值
- .net 网站应对压力的一些方案总结
- 插入光盘,创建挂载点,挂载设备,安装rpm包,升级rpm包,卸载rpm包,查询rpm包是否安装,查询rpm包信息、安装位置,查询系统文件名属于哪个安装包
- Ubuntu安装MySQL和Python库MySQLdb步骤
- JMeter快速入门
- 隐马尔科夫_HMM
- R语言学习 第四篇:函数和流程控制
- Kotlin中常量和静态方法
- Visual Studio - 安装VAX