【初心者超歓迎】Pythonで人工生命を作ろう!! に参加した

【初心者超歓迎】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)
メニューを閉じる