ぱらぱらめくる『作って動かすALife』

作って動かすALife ―実装を通した人工生命モデル理論入門

作って動かすALife ―実装を通した人工生命モデル理論入門

  • 準備(Windowsでやってみる)
    • Anacondaを入れる
    • Anacondaでパッケージを入れたい
      • こちらにあるようにAnacondaのrootから、open terminalして、本のまえがき viii にあるように、pyglet pymunk vispy keras tensorflowをAnadondaの環境にインストールする
    • 本のコードをgithub(こちら)からgit cloneしておく
    • Anaconda経由のターミナルで、git cloneしたディレクトリの、ch02に移動して
python gray_scott.py
    • とすると、描画される
    • Anacondaのjupyer labにて、新しいlab notebookを、同様にch02ディレクトリに作った上で、gray_scott.pyの中身をコピーしてやれば、jupyter labの上でコードをいじりながらできる
    • Alife本のコードを読み込むために、次のようにフルパス指定したにとダメかもしれない(git cloneした先が、デスクトップのgitフォルダの下の場合)
sys.path.append('C:\\Users\\ryamada\\Desktop\\git\\alife_book_src')
  • 2章 生命のパターンを作る(自己組織化、変化を繰り返す)
    • Gray-Scottモデル
      • gray_scott.py の次の行の値を変えると生じるパターンが変わることが確かめられる(本のp30あたり)
f,k =0.05, 0.06
    • 1次元セルラーオートマトン
      • コード内のRULEパラメタを変えることで、図2-21のような多彩なパターンが現れる
    • 2次元セルラーオートマトン(ライフ・ゲーム)
      • anacondaのjupyter labでコードをいじりながらやるには、冒頭を以下のように少し変えてやる必要がある
import sys, os
# sys.path.append(os.pardir)  # 親ディレクトリのファイルをインポートするための設定
sys.path.append('C:\\Users\\ryamada\\Desktop\\git\\alife_book_src')
import numpy as np
from alifebook_lib.visualizers import MatrixVisualizer
# import game_of_life_patterns
import chap02.game_of_life_patterns
    • game_of_life_patterns.pyに定義された、ライフ・ゲームパターンを指定しなおすためには、以下のように、game_of_life_patterns.py へのパスを指定するべく少し工夫する
pattern = chap02.game_of_life_patterns.OSCILLATOR
    • 以上のコードのまとめ
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys, os
# sys.path.append(os.pardir)  # 親ディレクトリのファイルをインポートするための設定
sys.path.append('C:\\Users\\ryamada\\Desktop\\git\\alife_book_src')
import numpy as np
from alifebook_lib.visualizers import MatrixVisualizer

# visualizerの初期化 (Appendix参照)
visualizer = MatrixVisualizer()

# シミュレーションの各パラメタ
SPACE_GRID_SIZE = 256
dx = 0.01
dt = 1
VISUALIZATION_STEP = 8  # 何ステップごとに画面を更新するか。

# モデルの各パラメタ
Du = 2e-5
Dv = 1e-5
f, k = 0.04, 0.06  # amorphous
# f, k = 0.035, 0.065  # spots
# f, k = 0.012, 0.05  # wandering bubbles
# f, k = 0.025, 0.05  # waves
# f, k = 0.022, 0.051 # stripe

# 初期化
u = np.ones((SPACE_GRID_SIZE, SPACE_GRID_SIZE))
v = np.zeros((SPACE_GRID_SIZE, SPACE_GRID_SIZE))
# 中央にSQUARE_SIZE四方の正方形を置く
SQUARE_SIZE = 20
u[SPACE_GRID_SIZE//2-SQUARE_SIZE//2:SPACE_GRID_SIZE//2+SQUARE_SIZE//2,
  SPACE_GRID_SIZE//2-SQUARE_SIZE//2:SPACE_GRID_SIZE//2+SQUARE_SIZE//2] = 0.5
v[SPACE_GRID_SIZE//2-SQUARE_SIZE//2:SPACE_GRID_SIZE//2+SQUARE_SIZE//2,
  SPACE_GRID_SIZE//2-SQUARE_SIZE//2:SPACE_GRID_SIZE//2+SQUARE_SIZE//2] = 0.25
# 対称性を壊すために、少しノイズを入れる
u += np.random.rand(SPACE_GRID_SIZE, SPACE_GRID_SIZE)*0.1
v += np.random.rand(SPACE_GRID_SIZE, SPACE_GRID_SIZE)*0.1

while visualizer:  # visualizerはウィンドウが閉じられるとFalseを返す
    for i in range(VISUALIZATION_STEP):
        # ラプラシアンの計算
        laplacian_u = (np.roll(u, 1, axis=0) + np.roll(u, -1, axis=0) +
                       np.roll(u, 1, axis=1) + np.roll(u, -1, axis=1) - 4*u) / (dx*dx)
        laplacian_v = (np.roll(v, 1, axis=0) + np.roll(v, -1, axis=0) +
                       np.roll(v, 1, axis=1) + np.roll(v, -1, axis=1) - 4*v) / (dx*dx)
        # Gray-Scottモデル方程式
        dudt = Du*laplacian_u - u*v*v + f*(1.0-u)
        dvdt = Dv*laplacian_v + u*v*v - (f+k)*v
        u += dt * dudt
        v += dt * dvdt
    # 表示をアップデート
    visualizer.update(u)
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys, os
# sys.path.append(os.pardir)  # 親ディレクトリのファイルをインポートするための設定
sys.path.append('C:\\Users\\ryamada\\Desktop\\git\\alife_book_src')
import numpy as np
from alifebook_lib.visualizers import ArrayVisualizer

# visualizerの初期化 (Appendix参照)
visualizer = ArrayVisualizer()

SPACE_SIZE = 600

# CAのバイナリコーディングされたルール (Wolfram code)
RULE = 26

# 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)
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys, os
# sys.path.append(os.pardir)  # 親ディレクトリのファイルをインポートするための設定
sys.path.append('C:\\Users\\ryamada\\Desktop\\git\\alife_book_src')
import numpy as np
from alifebook_lib.visualizers import MatrixVisualizer
# import game_of_life_patterns
import chap02.game_of_life_patterns
# visualizerの初期化 (Appendix参照)
visualizer = MatrixVisualizer()

WIDTH = 50
HEIGHT = 50

state = np.zeros((HEIGHT,WIDTH), dtype=np.int8)
next_state = np.empty((HEIGHT,WIDTH), dtype=np.int8)

# 初期化
### ランダム ###
state = np.random.randint(2, size=(HEIGHT,WIDTH), dtype=np.int8)
### game_of_life_patterns.pyの中の各パターンを利用. 左上(2,2)の位置にセットする. ###
pattern = chap02.game_of_life_patterns.OSCILLATOR
# state[2:2+pattern.shape[0], 2:2+pattern.shape[1]] = pattern

while visualizer:  # visualizerはウィンドウが閉じられるとFalseを返す
    for i in range(HEIGHT):
        for j in range(WIDTH):
            # 自分と近傍のセルの状態を取得
            # c: center (自分自身)
            # nw: north west, ne: north east, c: center ...
            nw = state[i-1,j-1]
            n  = state[i-1,j]
            ne = state[i-1,(j+1)%WIDTH]
            w  = state[i,j-1]
            c  = state[i,j]
            e  = state[i,(j+1)%WIDTH]
            sw = state[(i+1)%HEIGHT,j-1]
            s  = state[(i+1)%HEIGHT,j]
            se = state[(i+1)%HEIGHT,(j+1)%WIDTH]
            neighbor_cell_sum = nw + n + ne + w + e + sw + s + se
            if c == 0 and neighbor_cell_sum == 3:
                next_state[i,j] = 1
            elif c == 1 and neighbor_cell_sum in (2,3):
                next_state[i,j] = 1
            else:
                next_state[i,j] = 0
    state, next_state = next_state, state
    # 表示をアップデート
    visualizer.update(1-state) # 1を黒, 0を白で表示する
  • 3章 個と自己複製
    • 2次元セルラーオートマトンを少し複雑にした感じ
    • 反応(反応する存在がある。触媒もある。反応するだけでなく移動もする。反応するには、物理的に近接した上で、反応するかどうかという生起確率事象もある(らしい))とそれを周囲から隔絶する膜を作ることで、「細胞」という個を作る
  • 4章
    • 個体ができたら、それが集団をなし、集団は集団として動き回る
  • 5章 身体性
    • 知的行動は、どのような体にとって知的によい行動をとるか、ということであり、知性と身体は切り離せない、という話(の用だ)
  • 6章 個体の動きが進化する
    • 場を指定する画像ファイルを使うらしいのだが、それがうまく読み込めない模様…