代碼地址:
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