遺傳算法,是最常用的解決優化問題的算法,是最早的群智能算法。遺傳算法中主要包括,選擇、交叉、變異算子,其中對DNA個體的編碼方式分為實數編碼和二進制編碼等。今日由於學習和工作需要對該算法進行了一些了解,對該算法中常用的競賽選擇方式做如下筆記:
遺傳算法中的競賽選擇方式是一種放回抽樣,幾元競賽就是一次性在總體中取出幾個個體,然后在這些個體中取出最優的個體放入保留到下一代種群的集合中。需要保存多少個體就重復此操作幾次。
以下為python2.7寫的代碼,已經測試過,共兩個文件,可以通過修改mycmp.py中的比較函數以適應不同需求。
tournament_selection.py
1 #!/usr/bin/env python 2 #encoding:UTF-8 3 import random 4 import numpy as np 5 from mycmp import mycmp 6 7 """ 8 錦標賽方式選擇, 選擇出個體編號 9 indicateValueDict {個體索引號:(Value1, Value2), } 10 key為索引號,從0開始。value為元組,一般不超過兩個元素。 11 12 selectNum 需要選擇出的個體個數 13 elementNum=2 默認為二元競賽選擇 14 """ 15 def tournament_selection_Dict(indicateValueDict, selectNum, elementNum=2): 16 #個體索引列表 17 indicateList=range(len(indicateValueDict)) 18 #選擇出的個體序號 列表 19 remainIndicateList=[] 20 21 #構建列表 [(索引號,(Value1, Value2)), ] 22 indicateValueList=indicateValueDict.items() 23 24 #對列表排序, 排序規則按個人需求定制,修改mycmp即可 25 for i in xrange(selectNum): 26 tempList=random.sample(indicateValueList, elementNum) 27 tempList.sort(cmp=mycmp) 28 29 bestIndicate=tempList[0][0] 30 remainIndicateList.append(bestIndicate) 31 ###返回選擇的索引列表 32 return remainIndicateList 33 34 35 def tournament_selection_Matrix(indicateValueMatrix, selectNum, elementNum=2): 36 #個體索引列表 37 indicateList=range(indicateValueMatrix.shape[0]) 38 #選擇出的個體序號 列表 39 remainIndicateList=[] 40 41 for i in xrange(selectNum): 42 tempList=random.sample(indicateList, elementNum) 43 tempMatrix=indicateValueMatrix[tempList, ] 44 45 tempMatrixToList=tempMatrix.tolist() 46 tempMatrixToList=[(k[0], k[1:])for k in tempMatrixToList] 47 tempMatrixToList.sort(mycmp) 48 49 remainIndicateList.append(tempMatrixToList[0][0]) 50 return remainIndicateList 51 52 53 def tournament_selection_Dict2(indicateValueDict, selectNum, elementNum=2): 54 #個體索引列表 55 indicateList=range(len(indicateValueDict)) 56 #選擇出的個體序號 列表 57 remainIndicateList=[] 58 59 #構建列表 [(索引號,(Value1, Value2)), ] 60 indicateValueList=indicateValueDict.items() 61 62 #對列表排序, 排序規則按個人需求定制,修改mycmp即可 63 indicateValueList.sort(cmp=mycmp) 64 65 for i in xrange(selectNum): 66 tempList=[] 67 tempList.extend(random.sample(indicateList, elementNum)) 68 bestIndicate=indicateValueList[min(tempList)][0] 69 remainIndicateList.append(bestIndicate) 70 ###返回選擇的索引列表 71 return remainIndicateList 72 73 74 if __name__=="__main__": 75 xN=20 76 yN=3 77 selectNum=10 78 indicateValueDict={0:[1,2.1], 1:[1,2.2], 2:[1,2.3], 3:[1,2.4], 4:[1,2.5], 5:[1,2.6], 6:[1,2.7], 7:[1,2.8], 8:[1,2.9], 9:[1,3.0], 10:[0,2.1], 11:[0,2.2], 12:[0,2.3], 13:[0,2.4], 14:[0,2.5], 15:[0,2.6], 16:[0,2.7], 17:[0,2.8], 18:[0,2.9], 19:[0,3.0]} 79 random.seed(0) 80 print tournament_selection_Dict(indicateValueDict, selectNum) 81 print '-'*50 82 random.seed(0) 83 print tournament_selection_Dict2(indicateValueDict, selectNum) 84 print '-'*50 85 indicateValueMatrix=np.matrix([[0, 1, 2.1], [1, 1, 2.2], [2, 1, 2.3], [3, 1, 2.4], [4, 1, 2.5], [5, 1, 2.6], [6, 1, 2.7], [7, 1, 2.8], [8, 1, 2.9], [9, 1, 3.0], [10, 0, 2.1], [11, 0, 2.2], [12, 0, 2.3], [13, 0, 2.4], [14, 0, 2.5], [15, 0, 2.6], [16, 0, 2.7], [17, 0, 2.8], [18, 0, 2.9], [19, 0, 3.0]]) 86 random.seed(0) 87 print tournament_selection_Matrix(indicateValueMatrix, selectNum)
mycmp.py
1 #!/usr/bin/env python 2 #encoding:UTF-8 3 4 ###列表比較 算子 CMP 5 ### 第一位元素升序, 第二位元素降序 6 def mycmp(left, right): 7 #left 位於列表左的元素, right列表右側的元素 8 a=left[1] 9 b=right[1] 10 11 if a[0]>b[0]: 12 return 1 13 elif a[0]<b[0]: 14 return -1 15 elif a[1]<b[1]: 16 return 1 17 elif a[1]>b[1]: 18 return -1 19 else: 20 return 0 21 22 if __name__=="__main__": 23 data=[(0, (0, 1)), (1, (1, 0)), (2, (1, 1))] 24 data.sort(cmp=mycmp) 25 print data
運行效果圖:

本程序可以作為單獨模塊被調用,具體代碼地址如下:
https://github.com/guojun007/tournament_selection
