代码地址:
https://github.com/guojun007/real_sga
本部分是采用实数编码的标准遗传算法,整体流程与上一篇二进制编码的基本一致,
主要区别在于本部分的交叉操作为模拟二进制交叉,即SBX ,
变异操作 为 多项式变异。
real_sga/crossover/crossover.py
#实数编码,SBX交叉
def crossover(population, pcross_real, V, minRealVal, maxRealVal, eta_c):
for i in xrange(0, len(population), 2):
#如果随机概率大于交叉概率则不进行交叉操作
if random.random()>pcross_real:
continue #对两个个体执行SBX交叉操作
for j in xrange(V):
#对某自变量交叉
ylow=minRealVal[j]
yup=maxRealVal[j]
y1=population[i][j]
y2=population[i+1][j]
r=random.random()
if r<=0.5:
betaq=(2*r)**(1.0/(eta_c+1.0))
else:
betaq=(0.5/(1.0-r))**(1.0/(eta_c+1.0)) child1=0.5*( (1+betaq)*y1+(1-betaq)*y2 )
child2=0.5*( (1-betaq)*y1+(1+betaq)*y2 )
child1=min(max(child1, ylow), yup)
child2=min(max(child2, ylow), yup) population[i][j]=child1
population[i+1][j]=child2
以上代码是根据相关论文所写,是原始方式的化简版本。
以下给出官方的原始代码的 Python2.7 重构版。
#实数编码,SBX交叉
def crossover(population, pcross_real, V, minRealVal, maxRealVal, eta_c):
for i in xrange(0, len(population), 2):
#如果随机概率大于交叉概率则不进行交叉操作
if random.random()>pcross_real:
continue
#对两个个体执行SBX交叉操作
for j in xrange(V):
#判断是否对某自变量交叉
if random.random()>0.5:
continue
#如果两个体某自变量相等则不操作
if population[i][j]==population[i+1][j]:
continue
#对某自变量交叉
y1=min(population[i][j], population[i+1][j])
y2=max(population[i][j], population[i+1][j])
ylow=minRealVal[j]
yup=maxRealVal[j]
r=random.random()
beta=1.0+(2.0*(y1-ylow)/(y2-y1))
alpha=2.0-beta**( -(eta_c+1.0) )
if r<=(1.0/alpha):
betaq=(r*alpha)**(1.0/(eta_c+1.0))
else:
betaq=(1.0/(2.0-r*alpha))**(1.0/(eta_c+1.0))
child1=0.5*( (y1+y2)-betaq*(y2-y1) ) beta=1.0+(2.0*(yup-y2)/(y2-y1))
alpha=2.0-beta**( -(eta_c+1.0) )
if r<=(1.0/alpha):
betaq=(r*alpha)**(1.0/(eta_c+1.0))
else:
betaq=(1.0/(2.0-r*alpha))**(1.0/(eta_c+1.0))
child2=0.5*( (y1+y2)-betaq*(y2-y1) ) child1=min(max(child1, ylow), yup)
child2=min(max(child2, ylow), yup)
population[i][j]=child1
population[i+1][j]=child2
多项式变异:
#Routine for real polynomial mutation of an individual
#实数编码的常规多项式变异 def mutation(population, pmut_real, V, minRealVal, maxRealVal, eta_m):
for i in xrange(len(population)):
for j in xrange(V):
r=random.random()
#对个体某变量进行变异
if r<=pmut_real:
y=population[i][j]
ylow=minRealVal[j]
yup=maxRealVal[j]
delta1=1.0*(y-ylow)/(yup-ylow)
delta2=1.0*(yup-y)/(yup-ylow)
#delta=min(delta1, delta2)
r=random.random()
mut_pow=1.0/(eta_m+1.0)
if r<=0.5:
xy=1.0-delta1
val=2.0*r+(1.0-2.0*r)*(xy**(eta_m+1.0))
deltaq=val**mut_pow-1.0
else:
xy=1.0-delta2
val=2.0*(1.0-r)+2.0*(r-0.5)*(xy**(eta_m+1.0))
deltaq=1.0-val**mut_pow
y=y+deltaq*(yup-ylow)
y=min(yup, max(y, ylow))
population[i][j]=y