前提・実現したいこと
下記のURLのサイトを参考に、OneMax問題を遺伝的アルゴリズムを使って解こうとしております。
記載通りにコードを実行するとエラーが発生してしまいます。
pythonやプログラミング自体、超初心者でいまいち言葉を理解できておらず、エラーの解決法をご教示いただけますと幸いです。
(1)next_population[]のところでout of rangeエラーになってしまいます。理由がわかりません。
(2)記載されているコードで下記の部分について、私の理解はあっていますでしょうか。
population = []
for i in range(n)
arr = [random.randint(0, 1) for j in range(dim)]
population.append(arr)
population のリストを [] とする
iにn(1から20)を順番に代入する
0か1の整数をランダムにdim(10)個生成しjに代入し、arrという配列を作成する
populationのリストの最後にarrを挿入する
iにnを代入する操作は何のために必要(iはどこで使われている)なのでしょうか?
⇒populationを20個(20個体生成するという意味でしょうか)
for i in range(n)を追記すれば、前段のpopulation=[]をn回やるという意味なのでしょうか。
ソースコードにいろいろメモしていますが、もし間違いなどありましたら合わせて教えていただけますと幸いです。
https://phoro3.hatenablog.com/entry/2016/10/14/091310
発生している問題・エラーメッセージ
Generation: 0 <map object at 0x0000001F020F10D0> Generation: 1 Traceback (most recent call last): File "C:\-----\-----\Desktop\aaaa\aaa\onemax.py", line 90, in <modul e> child = cross(population[i], population[i+1]) IndexError: list index out of range
該当のソースコード
python
1import random 2import math 3import copy 4 5 6 7#各個体の適応度を計算し、エリートを選択する 8def calc_score(x):#calc_scoreの中を書き換えればほかの問題にも使える? 9 return sum(x)#onemaxなので合計した数が大きいものをエリートにしてる(と思う) 10 11def find_elite(population): 12 score = map(lambda x: calc_score(x), population) 13 #mapは複数の要素を格納したオブジェクトを関数に渡して実行する⇒populationをlambdaに渡して実行する 14 #lambdaはlamnbda 引数:返り値 ⇒引数がxで返り値がcalc_score(x) 15 max_val = -1 16 max_index = None 17 18 for i, val in enumerate(score): 19 if val > max_val: 20 max_val = val 21 max_index = i 22 23 return copy.deepcopy(population[max_index])#populationの各個体のスコアをscoreに格納して、その中からスコアが高い個体をreturnする 24 25#交叉 26def cross(parent1, parent2): 27 length = len(parent1) 28 r1 = int(math.floor(random.random() * length)) 29 r2 = r1 + int(math.floor(random.random() * (length - r1))) 30 31 child = copy.deepcopy(parent1) 32 child[r1:r2] = parent2[r1:r2] 33 34 return child 35 36#突然変異 37def mutate(parent): 38 r = int(math.floor(random.random() * len(parent))) 39 child = copy.deepcopy(parent) 40 child[r] = (parent[r] + 1) % 2 41 42 return child 43 44#現世代と次世代の個体群の中から適応度の高いN-1個を選択する(ルーレット選択) 45def select(num, population):#populationの中からnum個だけ選択する 46 selection = [] 47 score = map(lambda x:calc_score(x), population) 48 total = sum(score) 49 for i in range(n): 50 threshold = math.floor(random.random() * total) 51 sum_score = 0 52 for index, val in enumerate(score): 53 sum_score += val 54 if sum_score > threshold: 55 selection.append(population[index]) 56 break 57 58 return selection 59 60if __name__ == "__main__": 61 dim = 10 62 n = 20 63 cross_rate = 0.95 64 generation = 25 65 66#ランダムにN個の現世代の個体群を生成 67 population = [] 68 for i in range(n):#1から20を繰り返しiに代入する #arrは配列という意味 69 arr = [random.randint(0, 1) for j in range(dim)]#0~1の範囲でjをdim個生成する 70 population.append(arr)#populationの末尾にarrを追加 71 #random.randient(x,y)x以上y以下の整数⇒0か1 72 73 for g in range(generation): #range(25) gに1から25を代入する 74 print ("Generation: " + str(g) ) 75 76 77 #find elite 78 elite = find_elite(population) 79 80 81 #cross and mutate 82 next_population = [] 83 for i in range(n): #1~20から繰り返しiに代入する 84 if random.random() < cross_rate: #rando.rando.()は0.0~0.1の浮動小数点 85 if i != n - 1: 86 child = cross(population[i], population[i+1]) 87 else: 88 child = cross(population[i], population[0]) 89 else: 90 child = mutate(population[i]) 91 next_population.append(child) 92 93 94 #selection 95 population = select(n - 1, population + next_population) 96 population = [elite] + population 97 98 99 print(map(sum, population) )
試したこと
windows環境でpython3.8を使用しています。
dim=20にしましたが、同様にエラーが発生してしまいます。
エラー部分をi-1とiをcrossとしても同様にエラーが発生してしまいます。
エラー部分を if i != n: としても同様にエラーが発生してしまいます。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/06/08 22:55
2020/06/09 00:13 編集
2020/06/09 02:11
2020/06/09 03:04
2020/06/09 11:36