本文主要介紹遺傳算法(實數編碼)的交叉操作中的SBX,模擬二進制交叉。
首先,給出個人用python2.7實現的代碼,具體模塊已上傳到:
https://github.com/guojun007/sbx_cross
1 #!/usr/bin/env python 2 #encoding:UTF-8 3 import numpy as np 4 import random 5 6 """ 7 SBX 模擬二進制交叉 8 9 輸入: 10 population 種群矩陣 11 alfa 交叉概率 12 numRangeList 決策變量的上限(下限默認為0) 13 mu SBX方式的分布指數, 推薦為1 14 """ 15 def cross(population, alfa, numRangeList, mu=1): 16 N=population.shape[0] 17 V=population.shape[1] 18 populationList=range(N) 19 20 for _ in xrange(N): 21 r=random.random() 22 23 if r<alfa: 24 p1, p2=random.sample(populationList, 2) 25 bq=np.array([0]*V) 26 randList=np.random.random(V) 27 #根據概率向量判斷不同概率函數的選擇 28 orTF=(randList<=0.5) 29 30 #計算不同決策變量的 不同概率選擇 下的 系數 31 for j in xrange(V): 32 if orTF[j]==True: 33 bq[j]=(2.0*randList[j])**(1.0/(mu+1)) 34 else: 35 bq[j]=(1.0/(2.0*(1-randList[j])))**(1.0/(mu+1)) 36 37 #取出選定的兩個個體 38 old_p1=population[p1, ] 39 old_p2=population[p2, ] 40 #計算交叉后的兩個新個體 41 new_p1=0.5*((1+bq)*old_p1+(1-bq)*old_p2) 42 new_p2=0.5*((1-bq)*old_p1+(1+bq)*old_p2) 43 44 #上下限判斷,防止越界 45 new_p1=np.max(np.vstack((new_p1, np.array([0]*V))), 0) 46 new_p1=np.min(np.vstack((new_p1, numRangeList)), 0) 47 48 new_p2=np.max(np.vstack((new_p2, np.array([0]*V))), 0) 49 new_p2=np.min(np.vstack((new_p2, numRangeList)), 0) 50 51 #將交叉后的個體更新回種群 52 population[p1, ]=new_p1 53 population[p1, ]=new_p2 54 55 56 ###以下是測試用例 57 if __name__=="__main__": 58 random.seed(0) 59 np.random.seed(0) 60 xN=20 61 yN=3 62 alfa=0.9 63 population=np.random.rand(xN*yN).reshape(xN, yN)*1.0 64 65 ###運行函數 66 print population 67 print '-'*50 68 cross(population, alfa, np.array([1]*3)) 69 print '-'*50 70 print population
以下內容引至:
http://blog.csdn.net/silence1214/article/details/48802317
最近在做作業遇到一個Dejong’s fifth function的multi modal的問題,用傳統的GA方法嘗試了很多次,的確沒辦法搞定,隨機很多次也不一定在global optimum的地方得到一次解。前幾天去導師家里的路上談到這個事情,導師說一般現在都用SBX和polynomial的mutation。於是回來找了相關論文來看,找到了SBX最早的論文,奇怪的是,在論文中竟然沒有給出偽代碼,只是在講解他的motivation。大概的motivation是這樣的:
1:SBX主要是用於real number的編碼問題,但是借鑒與來自binary 編碼的idea。在binary中,假設2個parent分別為p1和p2,后代分別為c1和c2。那么是這么一個屬性的:(p1+p2)/2=(c1+c2)/2。再定義一個叫做spread factor的玩意β=|(c2−c1)/(p2−p1)|
2:在SBX中就要滿足第一個屬性,以及盡量β也binary中的概率分布一致。由此一個方案:
c1=(p2+p1)−0.5∗β(p2−p1)
c2=(p2+p1)+0.5∗β(p2−p1)
大家可以自己計算,是滿足上面2個玩意的。
3:那么接下來其實就是求β的,因為是要讓在real的問題中的β的分布盡量接近binary中的,那么就要首先知道binary中的分布。binary中的分布如下:
c(β)=0.5(n+1)βn,β≤1 and c(β)=0.5(n+1)1βn+2,β>1
也就是說β有2個分布的,具體怎么做呢?我看到有人實現是這么來的。
3.1:隨機一個數字在[0,1]之間,如果該數字小於等於0.5按照第一個來求,否則按照第二個來求。求解的時候是按照對β的概率分布等於這個隨機數字來計算的。這個只需要求積分即可,手工就能推導出來。
最后我用這個方法再加上tournament selection以及polynomial mutation的方法,在求解上面說的multi modal的問題的時候,竟然很多次都求解出來了!