続・遺伝的アルゴリズム、完全に理解した

# はじめに
この記事は[完全に理解したTalk Advent Calendar 2020](https://qiita.com/advent-calendar/2020/easyeasy "完全に理解したTalk Advent Calendar 2020")の14日目の記事です。
[前回](https://qiita.com/2000_4000/items/629410aa1d1a24d620a7)は遺伝的アルゴリズムの入門編のような記事を書いてみたのですが、自分で読み返しても「具体的な処理が分かりにくい！」と思ったので、今回は具体的なアルゴリズムの流れを示してみたいと思います。

# 動作環境
- 紙
- ペン
- サイコロ(6面体)

# 問題
***y=x^2を最小にするxを-1 <= X <= 1の範囲から求める***

# 概要
人間は微分とか式変形というエレガントな方法で厳密解を求めることができる問題ですが、アルゴリズムにとってはそうではありませんね。~~「いやニュートン法で解けるでしょ」というツッコミはなしで。~~
解くこと自体には全く意味のない問題ですが、ベーシックなGAの動きを理解するにはうってつけの問題かと思い、設定してみました。特定の言語によらない手法なので、今回は手を動かしてトライしてみたいと思います。

# 遺伝子型
今回の問題を解くにあたり、以下のような6bitのベクトルを遺伝子として設定しました。
- [-1, 1]の範囲を2^6(=64)等分する
- 各ポイントに2進数で番号をふる
- その2進数表記の各桁を成分とするベクトルを遺伝子とする(x=-1は[0,0,0,0,0,0]でx=1は[1,1,1,1,1,1])
- つまり最適解は31(=[0,1,1,1,1,1])もしくは32番目(=[1,0,0,0,0,0])となるときである

# 評価関数
- 評価関数はシンプルにy=x^2であり、yの計算結果が小さければ小さいほど適合度(Fitness)が良い
- でも直接的には代入できないので、「①遺伝子ベクトルを2進数表示」「②2進数を十進数化」「③十進数化した番号から対応するxを求める」「④xを代入してyを求める」という順番で適合度の計算を行うことになる

# 計算終了条件
最適解である[0,1,1,1,1,1]もしくは[1,0,0,0,0,0]が求められるまで。
できれば、最適解到達後も、なるべく時間と手首が許す限りサイコロを振って世代交代による適合度の平均値の挙動を確認する。

# パラメータ
- 個体数=6
    - サイコロが6面体なのでちょうどいいから。
    - 初期個体のベクトル成分はサイコロを振って3以下なら0、4以上なら1とする。
- 交叉率=0.5
    - 各個体に対してサイコロを振り、3以下なら交叉しない、4以上なら交叉する。
    - 交叉する個体に対してもう一度サイコロを振り、出た目で交叉相手と交叉位置を決める。
- 突然変異率=1/6=0.1666…
    - 各個体に対してサイコロを振り、1以外なら突然変異しない、1なら突然変異する。
    - 突然変異する個体に対してもう一度サイコロを振り、出た目の位置の成分を反転する
- エリート保存戦略=上位1個体
    - 各世代で最も適合度の良い個体をエリートとし、交叉も突然変異も行わず次世代に引き継ぐ。

# 第1世代(初期世代)
まずランダムに個体を生成しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272003/9c143b64-51f5-bda5-aab8-307f91c35b16.png)
各個体の適合度は以下のとおりです。問題が単純なこともあり、初期個体の中にすでに優秀なのが1個居ますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272003/ff838e6d-4608-2e41-d4f2-125ce2a4af94.png)
エリートである個体2を除き、交叉処理の要否をサイコロで決定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272003/9e8126dd-6a48-6c7a-46e3-764495f72753.png)
交叉結果です。個体4は成分4より後ろを個体2の成分で上書き、個体5は成分2より後ろを個体4の成分で上書きしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272003/fe63b1eb-7c3a-5aae-55a2-6fb4b2535931.png)
次に突然変異処理の要否をサイコロで決定します。こちらもエリートである個体2は除きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272003/5cb15da8-dbde-2008-7fea-c1943910d169.png)
突然変異結果です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272003/84ba1560-fdb6-08c1-38c5-d3a78afc1daf.png)
以上の処理を持って第1世代の演算を終了し、出来上がった個体群を第2世代に引き継ぎます。
毎世代全部載せると記事がめちゃくちゃ長くなるので、各世代の最初の適合度計算の結果だけここには載せていきます~~が、私は腱鞘炎に怯えながらサイコロを振りました~~。

# 第2世代
個体2が引き続きエリート。適合度が他の個体と比べて1桁違うので仕方ないですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272003/6069d0e5-c9cf-41ca-f4ac-99cc96c90b9e.png)

# 第3世代
個体2の牙城崩れず。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272003/57c25670-9fa1-33ef-4d78-6ce610d11cfd.png)

# 第4世代
個体1が下剋上してエリートに。最適解にかなり近づきました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272003/79f85402-b9dd-de48-6619-1fdf98c4f41e.png)

# 第5世代
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272003/851c926e-2c7f-3821-57b0-ff08cbbaeb78.png)

# 第6世代
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272003/4017703d-5d28-11fb-10f2-09b9a747d180.png)

# 第7世代
なんとエリート個体が2つ出来てしまいました。あんまり想定していなかったのですが、同率1位なので2個体とも残すことにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272003/cc757200-9467-e925-0283-516a25f11dba.png)

# 第8世代
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272003/1352ab8f-88de-b399-7295-1a7fc874061e.png)

# 第9世代
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272003/274f0f28-7014-920b-df2c-1d6a973758fc.png)

# 第10世代
なかなか学習が進みません。正直10世代くらいで終わると思っていたので焦ってます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272003/e14f7176-8b2a-294f-4d07-3c9a9eddf39a.png)

# 第11世代
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272003/84cbad94-bd92-987b-1c7d-6eb3f7fe8ffd.png)

# 第12世代
あと1歩で最適解というところまで来ました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272003/785c08b4-009a-d8b1-d15e-289b045edfda.png)

# 第13世代
再びエリート個体が複数登場しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272003/99e89665-83e8-51fc-c839-42a009a675fe.png)

# 第14世代
はい、第14世代目で遂に最適解である[0,1,1,1,1,1]に到達しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272003/b296f950-3722-9046-1b32-948b52aa2547.png)

# 第15世代～第25世代
最適解に到達してしまったのでエリート個体の適合度がこれ以上良くなることはありませんが、25世代目まで頑張りましたのでグラフでダイジェストを提示します。
![Generation vs Fitness.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272003/8a581122-8afc-9000-518f-20457bb069d5.png)
エリート個体を1個体保存しているので、Bestのグラフは単調減少になっています。エリート個体を保存しない場合は上がったり下がったりしながらだんだん減少してくようなグラフになるはずです。
それに対してAveのグラフは交叉や突然変異といった乱数を使った処理を行うことで、最適解到達後も解が収束することなく探索を継続している模様がわかります。