标准遗传算法(实数编码 python实现)模拟二进制交叉SBX 多项式变异

代码地址:

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

 

 

多项式变异:

real_sga/mutation/mutation.py

#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

 

 

posted on 2017-02-06 13:22  Angry_Panda  阅读(3011)  评论(1编辑  收藏  举报

导航