【初心者超歓迎】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)