回答編集履歴

7

 

2022/11/26 01:06

投稿

退会済みユーザー
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

 

2022/11/26 01:06

投稿

退会済みユーザー
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

追記

2022/11/26 01:02

投稿

退会済みユーザー
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

追記

2022/11/25 13:34

投稿

退会済みユーザー
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

追記

2022/11/25 13:34

投稿

退会済みユーザー
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

 

2022/11/25 13:30

投稿

退会済みユーザー
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

2022/11/25 11:09

投稿

退会済みユーザー
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
  ```