【初心者超歓迎】Pythonで人工生命を作ろう!!に参加した。その際のメモ
人工生命とは
・人工生命は実験数学
・ダーウィンの進化説の流れの制約を取り払い、新しい進化の中に生まれてくる生命に思いを馳せる研究分野
・現存する生命だけでなく、理論的に生命を理解しようとするアプローチ
・計算で何万年先の生命を想定することができる。
⇒単細胞から人類まで進化のなかで、最初はシンプルなルールのもとに単細胞が生まれ
そこからいくつもの進化を経て人類となった。そのシンプルなルールや進化を仮想的に経験させる分野と個人的には理解した
・強化学習のツールとして利用されることが多い
ライフゲーム
生命の誕生、進化、淘汰などのプロセスを簡易的なモデルで再現したシミュレーションゲーム
セルラーオートマトン
・ライフゲームの1種
・3マスある場合、1マスが生きている(■)か、死んでいる(□)かで8パターン存在する
右からパターン0、パターン1、…とする
■■■ ■■□ ■□□ ■□■ □■■ □■□ □□■ □□□
・そのマスが生きているか、死んでいるかどうかは、上にある3マスに依存する
例えばルール10の場合、2進数では 00001010 であり、
パターン0であれば0、パターン1であれば1、パターン2であれば0、パターン3であれば1、それ以降はすべて0となる
・つまりルール10で初期列が□□■□■□■■□であると、その後は以下のようになる
□□■□■□■■□
□■□□□□■□□
■□□□□■□□□
…
セルラーオートマトンをpython(Windows Subsystem for Linux)で実行してみる
Windows 10などの設定
Firefoxが閲覧できれば、問題なし
Windows Subsystem for Linuxでの設定
https://github.com/alifelab/alife_book_src
上記を参考に試してみたが、最新Anacondaはpython3.7となっており、以下のエラーが発生した
/root/anaconda3/lib/python3.7/site-packages/vispy/visuals/isocurve.py:22: UserWarning: VisPy is not yet compatible with matplotlib 2.2+
warnings.warn("VisPy is not yet compatible with matplotlib 2.2+")
どうもVisPyとmatplotlibの相性が悪く、結果としてSegmentation faultで実行できなかったため、古いバージョンのAnacondaをインストールした
# sudo su # apt update # apt upgrade # wget -d https://repo.anaconda.com/archive/Anaconda3-5.2.0-Linux-x86_64.sh # chmod +x Anaconda3-5.2.0-Linux-x86_64.sh # ./Anaconda3-5.2.0-Linux-x86_64.sh ... # /root/anaconda3/bin/pip install pyglet pymunk vispy keras tensorflow PyQt5 ... # git clone https://github.com/alifelab/alife_book_src.git # cd alife_book_src/chap02/ # /root/anaconda3/bin/python3.6 cellular_automata_1d.py
参考
https://github.com/alifelab/alife_book_src
# cat /home/shimizu/alife_book_src/chap02/cellular_automata_1d.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys, os
sys.path.append(os.pardir) # 親ディレクトリのファイルをインポートするための設定
import numpy as np
from alifebook_lib.visualizers import ArrayVisualizer
# visualizerの初期化 (Appendix参照)
visualizer = ArrayVisualizer()
SPACE_SIZE = 600
# CAのバイナリコーディングされたルール (Wolfram code)
RULE = 30
# CAの状態空間
state = np.zeros(SPACE_SIZE, dtype=np.int8)
next_state = np.empty(SPACE_SIZE, dtype=np.int8)
# 最初の状態を初期化
### ランダム ###
# state[:] = np.random.randint(2, size=len(state))
### 中央の1ピクセルのみ1、後は0 ###
state[len(state)//2] = 1
while visualizer: # visualizerはウィンドウが閉じられるとFalseを返す
# stateから計算した次の結果をnext_stateに保存
for i in range(SPACE_SIZE):
# left, center, right cellの状態を取得
l = state[i-1]
c = state[i]
r = state[(i+1)%SPACE_SIZE]
# neighbor_cell_codeは現在の状態のバイナリコーディング
# ex) 現在が[1 1 0]の場合
# neighbor_cell_codeは 1*2^2 + 1*2^1 + 0*2^0 = 6となるので、
# RULEの6番目のビットが1ならば、次の状態は1となるので、
# RULEをneighbor_cell_code分だけビットシフトして1と論理積をとる。
neighbor_cell_code = 2**2 * l + 2**1 * c + 2**0 * r
if (RULE >> neighbor_cell_code) & 1:
next_state[i] = 1
else:
next_state[i] = 0
# 最後に入れ替え
state, next_state = next_state, state
# 表示をアップデート
visualizer.update(1-state)
