多目标遗传算法 ------ NSGA-II (部分源码解析) 实数、二进制编码的变异操作 mutation.c

时间:2021-08-25 16:47:34

遗传算法的变异操作

 /* Mutation routines */

 # include <stdio.h>
# include <stdlib.h>
# include <math.h> # include "global.h"
# include "rand.h" /* Function to perform mutation in a population */
void mutation_pop (population *pop)
{
int i;
for (i=; i<popsize; i++)
{
mutation_ind(&(pop->ind[i]));
}
return;
}

一次进化过程中的 变异操作,  需要调用   变异函数 mutation_ind  种群个数popsize 次。

函数包装,判断是实数编码还是二进制编码并调用不同的变异函数

 /* Function to perform mutation of an individual */
void mutation_ind (individual *ind)
{
if (nreal!=)
{
real_mutate_ind(ind);
}
if (nbin!=)
{
bin_mutate_ind(ind);
}
return;
}

二进制编码 的  变异操作:

每个个体  的   每个变量  的  二进制编码段   的  每个比特位,   以变异概率  pmut_bin  进行变异。

(单点变异)

 /* Routine for binary mutation of an individual */
void bin_mutate_ind (individual *ind)
{
int j, k;
double prob;
for (j=; j<nbin; j++)
{
for (k=; k<nbits[j]; k++)
{
prob = randomperc();
if (prob <=pmut_bin)
{
if (ind->gene[j][k] == )
{
ind->gene[j][k] = ;
}
else
{
ind->gene[j][k] = ;
}
nbinmut+=;
}
}
}
return;
}

实数编码  情况下的   变异操作:

(多项式变异)

 /* Routine for real polynomial mutation of an individual */
void real_mutate_ind (individual *ind)
{
int j;
double rnd, delta1, delta2, mut_pow, deltaq;
double delta;
double y, yl, yu, val, xy;
for (j=; j<nreal; j++)
{
rnd = randomperc();
if (rnd <= pmut_real)
{
y = ind->xreal[j];
yl = min_realvar[j];
yu = max_realvar[j];
delta1 = (y-yl)/(yu-yl);
delta2 = (yu-y)/(yu-yl);
delta = minimum (delta1,delta2);
rnd = randomperc();
mut_pow = 1.0/(eta_m+1.0);
if (rnd <= 0.5)
{
xy = 1.0-delta1;
val = 2.0*rnd+(1.0-2.0*rnd)*(pow(xy,(eta_m+1.0)));
deltaq = pow(val,mut_pow) - 1.0;
}
else
{
xy = 1.0-delta2;
val = 2.0*(1.0-rnd)+2.0*(rnd-0.5)*(pow(xy,(eta_m+1.0)));
deltaq = 1.0 - (pow(val,mut_pow));
}
y = y + deltaq*(yu-yl);
if (y<yl)
{
y = yl;
}
if (y>yu)
{
y = yu;
}
ind->xreal[j] = y;
nrealmut+=;
}
}
return;
}
eta_m 为 实数编码的 多项式变异的 参数, 为全局设定。
(该变异方式是为了模拟二进制编码的单点变异,逻辑比较简单,数学含义不明) 每个个体  的   每个变量  的  实数表示,   以变异概率  pmut_real  进行变异