回答編集履歴
7
test
CHANGED
@@ -20,7 +20,7 @@
|
|
20
20
|
new_population = []
|
21
21
|
# probeの総和を1にするためにfitnessの合計値を求めておく
|
22
22
|
s = sum(u.fitness for u in population)
|
23
|
-
# fitnessから求めた population各個体の
|
23
|
+
# fitnessから求めた population各個体の選出確率のリスト(重みリスト)
|
24
24
|
prob = [p.fitness/s for p in population]
|
25
25
|
for i in range(len(population)):
|
26
26
|
sub_population = np.random.choice(population,size=M,replace=False,p=prob)
|
6
test
CHANGED
@@ -14,13 +14,15 @@
|
|
14
14
|
# 追記
|
15
15
|
M個を重複なしで、かつfitness に応じて優先的に選出したい(fitness大ならば選出確率大)という場合、
|
16
16
|
random.sample の重み付き版である `numpy.random.choice(replace=false, p=重みリスト)`を使ってみてはいかがでしょうか。
|
17
|
+
(非復元重み付きランダムサンプリング)
|
17
18
|
```python
|
18
19
|
def select(population,M):
|
19
20
|
new_population = []
|
20
21
|
# probeの総和を1にするためにfitnessの合計値を求めておく
|
21
22
|
s = sum(u.fitness for u in population)
|
23
|
+
# fitnessから求めた population各個体のの選出確率のリスト(重みリスト)
|
24
|
+
prob = [p.fitness/s for p in population]
|
22
25
|
for i in range(len(population)):
|
23
|
-
prob = [p.fitness/s for p in population]
|
24
26
|
sub_population = np.random.choice(population,size=M,replace=False,p=prob)
|
25
27
|
best = min(sub_population,key=lambda tree:tree.fitness)
|
26
28
|
new_population.append(deepcopy(best))
|
5
追記
test
CHANGED
@@ -11,3 +11,44 @@
|
|
11
11
|
sub_population = random.choices(population, weights=(1/p.fitness for p in population), k=M)
|
12
12
|
```
|
13
13
|
|
14
|
+
# 追記
|
15
|
+
M個を重複なしで、かつfitness に応じて優先的に選出したい(fitness大ならば選出確率大)という場合、
|
16
|
+
random.sample の重み付き版である `numpy.random.choice(replace=false, p=重みリスト)`を使ってみてはいかがでしょうか。
|
17
|
+
```python
|
18
|
+
def select(population,M):
|
19
|
+
new_population = []
|
20
|
+
# probeの総和を1にするためにfitnessの合計値を求めておく
|
21
|
+
s = sum(u.fitness for u in population)
|
22
|
+
for i in range(len(population)):
|
23
|
+
prob = [p.fitness/s for p in population]
|
24
|
+
sub_population = np.random.choice(population,size=M,replace=False,p=prob)
|
25
|
+
best = min(sub_population,key=lambda tree:tree.fitness)
|
26
|
+
new_population.append(deepcopy(best))
|
27
|
+
return new_population
|
28
|
+
```
|
29
|
+
|
30
|
+
numpyを使わない場合は下記のような形で。
|
31
|
+
```python
|
32
|
+
def select(population,M):
|
33
|
+
new_population = []
|
34
|
+
for i in range(len(population)):
|
35
|
+
sub_population = []
|
36
|
+
# 選出用populationのインデックスとfitnessのペアを格納したプール
|
37
|
+
pool = [[idx, p.fitness] for idx,p in enumerate(population)]
|
38
|
+
|
39
|
+
# M個選出するためにM回繰り返す
|
40
|
+
for _ in range(M):
|
41
|
+
# 現在のプールの重みリスト
|
42
|
+
w = [p[1] for p in pool]
|
43
|
+
# 重み付き確率に応じて選出プールから1個選出する
|
44
|
+
selected = random.choices(pool, weights=w, k=1)[0]
|
45
|
+
sub_population.append(population[selected[0]])
|
46
|
+
# 選出された個体の重みをゼロにして選出対象外とする
|
47
|
+
selected[1]=0
|
48
|
+
|
49
|
+
best = min(sub_population,key=lambda tree:tree.fitness)
|
50
|
+
new_population.append(deepcopy(best))
|
51
|
+
return new_population
|
52
|
+
|
53
|
+
```
|
54
|
+
※いずれにしても計算は重くなります。
|
4
追記
test
CHANGED
@@ -6,8 +6,8 @@
|
|
6
6
|
```
|
7
7
|
|
8
8
|
fitnessが小さいものを優先するのであれば下記のようになるかと
|
9
|
-
|
9
|
+
|
10
10
|
```py
|
11
11
|
sub_population = random.choices(population, weights=(1/p.fitness for p in population), k=M)
|
12
12
|
```
|
13
|
-
|
13
|
+
|
3
追記
test
CHANGED
@@ -2,6 +2,12 @@
|
|
2
2
|
https://docs.python.org/ja/3.10/library/random.html#random.choices
|
3
3
|
random.choices()関数の引数 weights に各要素の重みを指定することで、相対的な重みに基づいて要素が選ばれます。
|
4
4
|
```py
|
5
|
-
|
6
5
|
sub_population = random.choices(population, weights=(p.fitness for p in population), k=M)
|
7
6
|
```
|
7
|
+
|
8
|
+
fitnessが小さいものを優先するのであれば下記のようになるかと
|
9
|
+
```
|
10
|
+
```py
|
11
|
+
sub_population = random.choices(population, weights=(1/p.fitness for p in population), k=M)
|
12
|
+
```
|
13
|
+
```
|
2
test
CHANGED
@@ -3,5 +3,5 @@
|
|
3
3
|
random.choices()関数の引数 weights に各要素の重みを指定することで、相対的な重みに基づいて要素が選ばれます。
|
4
4
|
```py
|
5
5
|
|
6
|
-
sub_population = random.choices(population, weights=(p.fitness for p in population), k=M)
|
6
|
+
sub_population = random.choices(population, weights=(p.fitness for p in population), k=M)
|
7
7
|
```
|
1
test
CHANGED
@@ -3,5 +3,5 @@
|
|
3
3
|
random.choices()関数の引数 weights に各要素の重みを指定することで、相対的な重みに基づいて要素が選ばれます。
|
4
4
|
```py
|
5
5
|
|
6
|
-
random.choices(population, weights=(p.fitness for p in population), k=M))
|
6
|
+
sub_population = random.choices(population, weights=(p.fitness for p in population), k=M))
|
7
7
|
```
|