Spaces:
Sleeping
Sleeping
KJMAN678
commited on
Commit
·
76c9bfe
1
Parent(s):
2b28e98
実行ファイルを追加、チームや取り組んだチャレンジ概要をREADME.mdに追記
Browse files- README.md +29 -3
- StableDiffusionSample.ipynb +0 -0
- simulation.py +439 -0
README.md
CHANGED
@@ -5,11 +5,37 @@
|
|
5 |
- Mr. Matsubara (松原さん)
|
6 |
- Me, Shimizu (清水(記))
|
7 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8 |
- [Slide (Sorry, Japanese)](https://docs.google.com/presentation/d/1Umq53JqME-GUJN6TgCDA7Fu1CcQhMJTG/edit#slide=id.g15d379b926a_3_0)
|
9 |
|
10 |
### Output Images
|
|
|
|
|
|
|
|
|
|
|
11 |
<div align="center">
|
12 |
-
<img src="./images/first_generation.png" alt="エビフライトライアングル" title="サンプル"
|
13 |
-
<img src="./images/500th_generation.png" alt="エビフライトライアングル" title="サンプル"
|
14 |
-
<img src="./images/1000th_generation.png" alt="エビフライトライアングル" title="サンプル"
|
|
|
|
|
|
|
15 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
- Mr. Matsubara (松原さん)
|
6 |
- Me, Shimizu (清水(記))
|
7 |
|
8 |
+
### Choice Theme
|
9 |
+
|
10 |
+
- [BUILD A SPACE BIOLOGY SUPERHERO](https://2022.spaceappschallenge.org/challenges/2022-challenges/space-biology-superhero/details)
|
11 |
+
|
12 |
+
### Discription
|
13 |
+
|
14 |
+
- 簡単な火星の環境をシミュレートした遺伝的アルゴリズムにより導き出した究極生命体の特徴(=画像生成に与えるキーワード)を画像生成プログラムに与えて未来に生き残る究極生命体の画像を生成する。
|
15 |
+
- The image generation program is given the characteristics of the ultimate life form (= keywords for image generation) derived by a genetic algorithm that simulates a simple Martian environment to generate images of the ultimate life form that will survive in the future.
|
16 |
+
|
17 |
- [Slide (Sorry, Japanese)](https://docs.google.com/presentation/d/1Umq53JqME-GUJN6TgCDA7Fu1CcQhMJTG/edit#slide=id.g15d379b926a_3_0)
|
18 |
|
19 |
### Output Images
|
20 |
+
|
21 |
+
##### left: first Generation! Very Furry Tall Herd of No teeth Lighter skin Ferocious alien from Mars
|
22 |
+
##### center: 500th Generation! Pair Carnivorous Gentle alien from Mars
|
23 |
+
##### right: 1000th Generation! Pair Herbivorous Ferocious alien from Mars
|
24 |
+
|
25 |
<div align="center">
|
26 |
+
<img src="./images/first_generation.png" alt="エビフライトライアングル" title="サンプル" style="width:300px;">
|
27 |
+
<img src="./images/500th_generation.png" alt="エビフライトライアングル" title="サンプル" style="width:300px;"/>
|
28 |
+
<img src="./images/1000th_generation.png" alt="エビフライトライアングル" title="サンプル" style="width:300px;"/>
|
29 |
+
</div>
|
30 |
+
|
31 |
+
### file organization
|
32 |
|
33 |
+
- StableDiffusionSample.ipynb
|
34 |
+
- An executable file that performs image generation.
|
35 |
+
- 画像生成を行う実行ファイル。
|
36 |
+
- simulation.py
|
37 |
+
- A file with a genetic algorithm simulation running in StableDiffusionSample.ipynb
|
38 |
+
- StableDiffusionSample.ipynb で実行する、遺伝的アルゴリズムによるシミュレーションを行っているファイル。
|
39 |
+
- images
|
40 |
+
- Folder containing the Output image described above.
|
41 |
+
- 上述のOutput画像が入ったフォルダ
|
StableDiffusionSample.ipynb
ADDED
The diff for this file is too large to render.
See raw diff
|
|
simulation.py
ADDED
@@ -0,0 +1,439 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# -*- coding: utf-8 -*-
|
2 |
+
"""simulation.ipynb
|
3 |
+
|
4 |
+
Automatically generated by Colaboratory.
|
5 |
+
|
6 |
+
Original file is located at
|
7 |
+
https://colab.research.google.com/drive/1ZVm7p9Kb39Br5GUk1qVby8sG7YmlXLJX
|
8 |
+
|
9 |
+
- [遺伝アルゴリズム 参考記事](https://mori-memo.hateblo.jp/entry/2022/06/16/232644#%E5%88%9D%E6%9C%9F%E4%B8%96%E4%BB%A3%E3%81%AE%E4%BD%9C%E6%88%90)
|
10 |
+
- [バックアップ](https://colab.research.google.com/drive/1CfA0nBjBrrTS3lj0H5-TbOTTD0JdSCqW#scrollTo=rLmsKrtg1NPE)
|
11 |
+
- [【NASAより】火星の気温](https://mars.nasa.gov/files/mep/facts/Temperature-Mars-Facts.jpg)
|
12 |
+
"""
|
13 |
+
|
14 |
+
import numpy as np
|
15 |
+
import matplotlib.pyplot as plt
|
16 |
+
import random
|
17 |
+
from typing import Tuple, Dict, List
|
18 |
+
|
19 |
+
"""### HACK
|
20 |
+
1. (済) 画像生成実行colab で下記のシミュレーションを実行できるよう修正
|
21 |
+
2. (済) 画像生成ワードを3つから6つに戻す
|
22 |
+
3. (済) 各パラメーターのスコアの推移を表示
|
23 |
+
4. スコアがintデータから途中でfloat型になってしまう -> スコアは修正済み、遺伝子の中の数が変
|
24 |
+
5. パラメーター調整 -> 気温や餌の量のしきい値、共同体の規模や世代数など
|
25 |
+
"""
|
26 |
+
|
27 |
+
class Individual:
|
28 |
+
'''各個体のクラス
|
29 |
+
args: 個体の持つ遺伝子情報(np.array)'''
|
30 |
+
def __init__(self, genom_size):
|
31 |
+
self.body_hair = np.random.randint(0, 2, genom_size).tolist()
|
32 |
+
self.body_size = np.random.randint(0, 2, genom_size).tolist()
|
33 |
+
self.herd_num = np.random.randint(0, 2, genom_size).tolist()
|
34 |
+
self.eating = np.random.randint(0, 2, genom_size).tolist()
|
35 |
+
self.body_color = np.random.randint(0, 2, genom_size).tolist()
|
36 |
+
self.ferocity = np.random.randint(0, 2, genom_size).tolist()
|
37 |
+
|
38 |
+
self.all_genoms = {
|
39 |
+
"body_hair": self.body_hair,
|
40 |
+
"body_size": self.body_size,
|
41 |
+
"herd_num": self.herd_num,
|
42 |
+
"eating": self.eating,
|
43 |
+
"body_color": self.body_color,
|
44 |
+
"ferocity": self.ferocity,
|
45 |
+
}
|
46 |
+
self.fitness = {
|
47 |
+
"body_hair": 0,
|
48 |
+
"body_size": 0,
|
49 |
+
"herd_num": 0,
|
50 |
+
"eating": 0,
|
51 |
+
"body_color": 0,
|
52 |
+
"ferocity": 0,
|
53 |
+
} # 個体の適応度(set_fitness関数で設定)
|
54 |
+
self.set_fitness()
|
55 |
+
self.set_all_genoms()
|
56 |
+
|
57 |
+
def set_fitness(self):
|
58 |
+
'''個体に対する目的関数(OneMax)の値をself.fitnessに代入'''
|
59 |
+
self.fitness = {key: sum(value) for key, value in self.all_genoms.items()}
|
60 |
+
|
61 |
+
def get_fitness(self):
|
62 |
+
'''self.fitnessを出力'''
|
63 |
+
return self.fitness
|
64 |
+
|
65 |
+
def set_all_genoms(self):
|
66 |
+
'''self.all_parameterの中身をself.body_hair以下に代入する'''
|
67 |
+
self.body_hair = self.all_genoms["body_hair"]
|
68 |
+
self.body_size = self.all_genoms["body_size"]
|
69 |
+
self.herd_num = self.all_genoms["herd_num"]
|
70 |
+
self.eating = self.all_genoms["eating"]
|
71 |
+
self.body_color = self.all_genoms["body_color"]
|
72 |
+
self.ferocity = self.all_genoms["ferocity"]
|
73 |
+
|
74 |
+
def mutate(self):
|
75 |
+
'''遺伝子の突然変異'''
|
76 |
+
for i, (parameter, genom) in enumerate(self.all_genoms.items()):
|
77 |
+
|
78 |
+
tmp = genom.copy()
|
79 |
+
i = np.random.randint(0, len(genom) - 1)
|
80 |
+
tmp[i] = float(not genom[i])
|
81 |
+
self.all_genoms[parameter] = tmp
|
82 |
+
|
83 |
+
self.set_all_genoms()
|
84 |
+
self.set_fitness()
|
85 |
+
|
86 |
+
def random_temperature() -> float:
|
87 |
+
"""
|
88 |
+
火星の気温20℃〜-140℃の範囲でrandomにfloat値を返す
|
89 |
+
|
90 |
+
args
|
91 |
+
times (int): 試行回数
|
92 |
+
return
|
93 |
+
float: ランダムに作成した 火星の気温
|
94 |
+
"""
|
95 |
+
|
96 |
+
temperature = random.uniform(-140, 30)
|
97 |
+
|
98 |
+
return temperature
|
99 |
+
|
100 |
+
def random_food_volume(food_volume):
|
101 |
+
"""
|
102 |
+
餌の量
|
103 |
+
|
104 |
+
args
|
105 |
+
times (int): 試行回数
|
106 |
+
return
|
107 |
+
float: ランダムに作成した 火星の気温
|
108 |
+
"""
|
109 |
+
|
110 |
+
food_volume += random.randint(-100, 100)
|
111 |
+
if food_volume < 0:
|
112 |
+
food_volume = 0
|
113 |
+
|
114 |
+
return food_volume
|
115 |
+
|
116 |
+
def create_generation(POPURATIONS, GENOMS_SIZE):
|
117 |
+
'''初期世代の作成
|
118 |
+
return: 個体クラスのリスト'''
|
119 |
+
generation = {}
|
120 |
+
for i in range(POPURATIONS):
|
121 |
+
individual = Individual(GENOMS_SIZE)
|
122 |
+
generation[individual] = 0
|
123 |
+
return generation
|
124 |
+
|
125 |
+
def select_tournament(generation_: List[Tuple[Individual, int]]) -> List[Tuple[Individual, int]]:
|
126 |
+
|
127 |
+
"""
|
128 |
+
選択の関数(トーナメント方式)。すべてのgenerationから3つ選び、強い(scoreが最も高い)genomを1つ選ぶ。これをgenerationのサイズだけ繰り返す
|
129 |
+
|
130 |
+
args
|
131 |
+
generation List[Tuple[Individual, int]]: Individual で作成したゲノム情報 [["body_hair"], ["body_size"], ["herd_num"]] , 評価score
|
132 |
+
return
|
133 |
+
List[Tuple[Individual, int]] : トーナメント戦で生き残ったゲノム1つ
|
134 |
+
"""
|
135 |
+
|
136 |
+
selected_gemems = []
|
137 |
+
|
138 |
+
for i in range(len(generation)):
|
139 |
+
|
140 |
+
# 最もスコアのよいgeneration を採用
|
141 |
+
tournament = random.sample(generation_, TOUNAMENT_NUM)
|
142 |
+
max_genom = max(tournament, key=lambda x: x[1])
|
143 |
+
|
144 |
+
selected_gemems.append(max_genom)
|
145 |
+
|
146 |
+
return selected_gemems
|
147 |
+
|
148 |
+
def cross_two_point_copy(child1, child2):
|
149 |
+
'''二点交叉'''
|
150 |
+
|
151 |
+
new_child1 = {}
|
152 |
+
new_child2 = {}
|
153 |
+
|
154 |
+
for parameter_genom_1, parameter_genom_2 in zip(child1[0].all_genoms.items(), child2[0].all_genoms.items()):
|
155 |
+
|
156 |
+
size = len(parameter_genom_1[1])
|
157 |
+
|
158 |
+
tmp_child_parameter1 = parameter_genom_1[0]
|
159 |
+
tmp_child_parameter2 = parameter_genom_2[0]
|
160 |
+
|
161 |
+
tmp_child_genom1 = parameter_genom_1[1].copy()
|
162 |
+
tmp_child_genom2 = parameter_genom_2[1].copy()
|
163 |
+
|
164 |
+
cxpoint1 = np.random.randint(1, size)
|
165 |
+
cxpoint2 = np.random.randint(1, size - 1)
|
166 |
+
|
167 |
+
if cxpoint2 >= cxpoint1:
|
168 |
+
cxpoint2 += 1
|
169 |
+
else:
|
170 |
+
cxpoint1, cxpoint2 = cxpoint2, cxpoint1
|
171 |
+
|
172 |
+
tmp_child_genom1[cxpoint1:cxpoint2], tmp_child_genom2[cxpoint1:cxpoint2] = tmp_child_genom2[cxpoint1:cxpoint2].copy(), tmp_child_genom1[cxpoint1:cxpoint2].copy()
|
173 |
+
|
174 |
+
child1[0].all_genoms[tmp_child_parameter1] = tmp_child_genom1
|
175 |
+
child2[0].all_genoms[tmp_child_parameter2] = tmp_child_genom2
|
176 |
+
|
177 |
+
child1[0].set_all_genoms()
|
178 |
+
child1[0].set_fitness()
|
179 |
+
child2[0].set_all_genoms()
|
180 |
+
child2[0].set_fitness()
|
181 |
+
|
182 |
+
return child1, child2
|
183 |
+
|
184 |
+
def crossover(selected):
|
185 |
+
'''交叉の関数'''
|
186 |
+
children = []
|
187 |
+
if POPURATIONS % 2:
|
188 |
+
selected.append(selected[0])
|
189 |
+
for child1, child2 in zip(selected[::2], selected[1::2]):
|
190 |
+
if np.random.rand() < CROSSOVER_PB:
|
191 |
+
child1, child2 = cross_two_point_copy(child1, child2)
|
192 |
+
children.append(child1)
|
193 |
+
children.append(child2)
|
194 |
+
children = children[:POPURATIONS]
|
195 |
+
return children
|
196 |
+
|
197 |
+
def mutate(children):
|
198 |
+
for child in children:
|
199 |
+
if np.random.rand() < MUTATION_PB:
|
200 |
+
child.mutate()
|
201 |
+
return children
|
202 |
+
|
203 |
+
def mutate(children):
|
204 |
+
|
205 |
+
tmp_children = []
|
206 |
+
|
207 |
+
for child in children:
|
208 |
+
individual, score = child[0], child[1]
|
209 |
+
individual.mutate()
|
210 |
+
|
211 |
+
tmp_children.append((individual, score))
|
212 |
+
|
213 |
+
return tmp_children
|
214 |
+
|
215 |
+
def reset_generation_score(generation_):
|
216 |
+
|
217 |
+
for i, (individual, score) in enumerate(generation_):
|
218 |
+
generation_[i] = (individual, 0)
|
219 |
+
|
220 |
+
return generation_
|
221 |
+
|
222 |
+
def scoring(generation_, temperature, food_volume):
|
223 |
+
|
224 |
+
generation_ = reset_generation_score(generation_)
|
225 |
+
|
226 |
+
# scoring を実施
|
227 |
+
for i, (individual, score) in enumerate(generation_):
|
228 |
+
|
229 |
+
# 各パラメーターの特性値を探索
|
230 |
+
for parameter, fitness in individual.get_fitness().items():
|
231 |
+
|
232 |
+
# 気温が高い
|
233 |
+
if temperature > THREASHOLD_TEMPRETURE:
|
234 |
+
if parameter == "body_hair": # body_hair が小さいほうが有利、大きいほうが不利
|
235 |
+
score += MAX_NUM - fitness
|
236 |
+
elif parameter == "body_size": # body_size が小さいほうが有利、大きいほうが不利
|
237 |
+
score += MAX_NUM - fitness
|
238 |
+
elif parameter == "body_color": # body_color が暗い方が有利、明るいほうが不利
|
239 |
+
score += fitness
|
240 |
+
|
241 |
+
# 気温が低い
|
242 |
+
else:
|
243 |
+
if parameter == "body_hair": # body_hair が大きいほうが有利、小さいほうが不利
|
244 |
+
score += fitness
|
245 |
+
elif parameter == "body_size": # body_size が大きいほうが有利、小さいほうが不利
|
246 |
+
score += fitness
|
247 |
+
elif parameter == "body_color": # body_color が明るい方が有利、暗いほうが不利
|
248 |
+
score += MAX_NUM - fitness
|
249 |
+
|
250 |
+
# エサが多い
|
251 |
+
if food_volume > THREASHOLD_FOOD_VOLUME:
|
252 |
+
if parameter == "body_size": # body_size が大きいほうが有利、小さいほうが不利
|
253 |
+
score += fitness
|
254 |
+
elif parameter == "herd_num": # herd_num が大きいほうが有利、小さいほうが不利
|
255 |
+
score += fitness
|
256 |
+
elif parameter == "eating": # eating が大きい(肉食)ほうが有利、小さい(草食)ほうが不利
|
257 |
+
score += fitness
|
258 |
+
|
259 |
+
# エサが少ない
|
260 |
+
else:
|
261 |
+
if parameter == "body_size": # body_size が小さいほうが有利、大きいほうが不利
|
262 |
+
score += MAX_NUM - fitness
|
263 |
+
elif parameter == "herd_num": # herd_num が小さいほうが有利、大きいほうが不利
|
264 |
+
score += MAX_NUM - fitness
|
265 |
+
elif parameter == "eating": # eating が小さい(草食)ほうが有利、大さい(肉食)ほうが不利
|
266 |
+
score += MAX_NUM - fitness
|
267 |
+
|
268 |
+
|
269 |
+
# 強さ
|
270 |
+
if parameter == "body_size": # body_size が大きいほうが有利、小さい方が不利
|
271 |
+
score += fitness
|
272 |
+
elif parameter == "herd_num":
|
273 |
+
score += fitness
|
274 |
+
elif parameter == "ferocity": # ferocity が大きい(凶暴)ほうが有利、小さい(おとなしい)ほうが不利
|
275 |
+
score += fitness
|
276 |
+
|
277 |
+
|
278 |
+
# score を更新
|
279 |
+
generation_[i] = (individual, int(score))
|
280 |
+
|
281 |
+
return generation_
|
282 |
+
|
283 |
+
def ga_solve(generation):
|
284 |
+
'''遺伝的アルゴリズムのソルバー
|
285 |
+
return: 最終世代の最高適応値の個体、最低適応値の個体'''
|
286 |
+
|
287 |
+
best = []
|
288 |
+
worst = []
|
289 |
+
|
290 |
+
temperature_transition = []
|
291 |
+
food_volume = 500
|
292 |
+
food_volume_transition = []
|
293 |
+
|
294 |
+
parameter_transiton = {
|
295 |
+
"body_size" : [],
|
296 |
+
"body_hair" : [],
|
297 |
+
"herd_num" : [],
|
298 |
+
"eating" : [],
|
299 |
+
"body_color" : [],
|
300 |
+
"ferocity" : [],
|
301 |
+
}
|
302 |
+
|
303 |
+
# --- Generation loop
|
304 |
+
print('Generation loop start.')
|
305 |
+
|
306 |
+
# Dict[Individual, int] から List[Tuple(individual, int)]へ変換
|
307 |
+
# Dict だと Key の重複ができないため
|
308 |
+
generation_ = [(individual, score) for individual, score in generation.items()]
|
309 |
+
|
310 |
+
for i in range(GENERATIONS):
|
311 |
+
|
312 |
+
temperature = random_temperature()
|
313 |
+
temperature_transition.append(temperature)
|
314 |
+
food_volume = random_food_volume(food_volume)
|
315 |
+
food_volume_transition.append(food_volume)
|
316 |
+
|
317 |
+
# スコアリング
|
318 |
+
generation_ = scoring(generation_, temperature, food_volume)
|
319 |
+
|
320 |
+
|
321 |
+
# --- Step1. Print fitness in the generation
|
322 |
+
best_individual_score = max(generation_, key=lambda x: x[1])
|
323 |
+
|
324 |
+
best.append(best_individual_score[0].fitness)
|
325 |
+
worst_individual_score = min(generation_, key=lambda x: x[1])
|
326 |
+
|
327 |
+
worst.append(worst_individual_score[0].fitness)
|
328 |
+
# print("Generation: " + str(i) \
|
329 |
+
# + ": Best fitness: " + str(best_individual_score[0].fitness) + "Best fitness score: " + str(best_individual_score[1]) \
|
330 |
+
# + ". Worst fitness: " + str(worst_individual_score[0].fitness) + "Worst fitness score: " + str(worst_individual_score[1])
|
331 |
+
# )
|
332 |
+
|
333 |
+
# --- Step2. Selection (Roulette)
|
334 |
+
selected_genoms = select_tournament(generation_)
|
335 |
+
|
336 |
+
# --- Step3. Crossover (two_point_copy)
|
337 |
+
children = crossover(selected_genoms)
|
338 |
+
|
339 |
+
# --- Step4. Mutation
|
340 |
+
generation_ = mutate(children)
|
341 |
+
|
342 |
+
for parameter, genom in best_individual_score[0].all_genoms.items():
|
343 |
+
parameter_transiton[parameter].append(sum(genom))
|
344 |
+
|
345 |
+
best_individual_score[0].set_all_genoms()
|
346 |
+
best_individual_score[0].set_fitness()
|
347 |
+
|
348 |
+
print("Generation loop ended. The best individual: ")
|
349 |
+
print(best_individual_score[0].all_genoms)
|
350 |
+
|
351 |
+
plt.figure(figsize=(20, 5))
|
352 |
+
plt.title("temperature")
|
353 |
+
plt.plot(temperature_transition)
|
354 |
+
plt.ylabel("temperature Celsius")
|
355 |
+
plt.xlabel("generation")
|
356 |
+
plt.savefig("simlation_tempreture.png")
|
357 |
+
|
358 |
+
plt.figure(figsize=(20, 5))
|
359 |
+
plt.title("food volume")
|
360 |
+
plt.plot(food_volume_transition)
|
361 |
+
plt.ylim(0);
|
362 |
+
plt.ylabel("food volume")
|
363 |
+
plt.xlabel("generation")
|
364 |
+
plt.savefig("simlation_food_volume.png")
|
365 |
+
|
366 |
+
plt.figure(figsize=(20, 16))
|
367 |
+
for i, (parameter, transition) in enumerate(parameter_transiton.items()):
|
368 |
+
plt.subplot(6, 1, i+1)
|
369 |
+
plt.title(parameter)
|
370 |
+
plt.plot(transition, label=parameter)
|
371 |
+
plt.legend()
|
372 |
+
plt.ylim(0, 4)
|
373 |
+
plt.tight_layout()
|
374 |
+
plt.savefig("each_parameter_transition.png")
|
375 |
+
|
376 |
+
return best, worst
|
377 |
+
|
378 |
+
def get_word_for_image_generate(word_dict, best, index):
|
379 |
+
|
380 |
+
# アルゴリズムの結果に対応するwordを抽出
|
381 |
+
word_list = [word_dict[parameter][int(fitness)] for parameter, fitness in best[index].items()]
|
382 |
+
|
383 |
+
# 最終的な I/F 補足: スペース区切りの文字列 を渡す, 英語もありうる
|
384 |
+
word = " ".join(word_list)
|
385 |
+
return word
|
386 |
+
|
387 |
+
"""### 実行"""
|
388 |
+
|
389 |
+
# シード値の固定
|
390 |
+
SEED = 42
|
391 |
+
np.random.seed(seed=SEED)
|
392 |
+
random.seed(SEED)
|
393 |
+
|
394 |
+
# パラメーター
|
395 |
+
POPURATIONS = 200
|
396 |
+
GENOMS_SIZE = 4 # 遺伝配列 0, 1 のどちらかを要素とした配列のサイズ
|
397 |
+
GENERATIONS = 1000 # 世代数
|
398 |
+
CROSSOVER_PB = 0.5 # cross over(交差) する確率
|
399 |
+
MUTATION_PB = 0.7 # mutation(突然変異)する確率
|
400 |
+
TOUNAMENT_NUM = 10 # トーナメント方式で競わせる数
|
401 |
+
MAX_NUM = 4 # fitness の最大値
|
402 |
+
|
403 |
+
THREASHOLD_TEMPRETURE = 5
|
404 |
+
THREASHOLD_FOOD_VOLUME = 1500
|
405 |
+
|
406 |
+
# 渡すデータの加工イメージ
|
407 |
+
# dict 型 {項目(key): 画像生成プログラムに与えるキーワード{value}}
|
408 |
+
word_dict = {
|
409 |
+
"body_size": ["Very small", "Small", "Ordinary size", "Big", "Giant"],
|
410 |
+
"body_hair": ["Very Skinny", "Skinny", "Ordinary Skin", "Furry", "Very Furry"],
|
411 |
+
"herd_num": ["Lone", "Pair", "Eight", "Many", "Too Many"],
|
412 |
+
"eating": ["Very Herbivorous", "Herbivorous", "Omnivorous", "Carnivorous","Very Carnivorous"],
|
413 |
+
"body_color": ["Lightest", "Lighter", "Ordinary Tone", "Darker", "Darkest"],
|
414 |
+
"ferocity": ["Very Gentle", "Gentle", "Ordinary", "Ferocious", "Very Ferocious"],
|
415 |
+
}
|
416 |
+
|
417 |
+
# create first genetarion
|
418 |
+
generation = create_generation(POPURATIONS, GENOMS_SIZE)
|
419 |
+
|
420 |
+
# アルゴリズムの実行
|
421 |
+
best, worst = ga_solve(generation)
|
422 |
+
|
423 |
+
# 抽出する世代
|
424 |
+
first_generation = 0
|
425 |
+
midle_generation = len(best) // 2
|
426 |
+
last_generation = -1
|
427 |
+
|
428 |
+
first_generation_word = get_word_for_image_generate(word_dict, best, first_generation) + " alien from Mars"
|
429 |
+
midle_generation_word = get_word_for_image_generate(word_dict, best, midle_generation) + " alien from Mars"
|
430 |
+
last_generation_word = get_word_for_image_generate(word_dict, best, last_generation) + " alien from Mars"
|
431 |
+
|
432 |
+
# 抽出する世代のワードを出力
|
433 |
+
print()
|
434 |
+
print(
|
435 |
+
"最初の世代:", first_generation_word, "\n",
|
436 |
+
f"中間の{midle_generation}世代目:", midle_generation_word, "\n",
|
437 |
+
f"最後の{GENERATIONS}世代目:", last_generation_word, "\n",
|
438 |
+
)
|
439 |
+
|