Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Pythonで人工生命『生命のパターンを作ってみよう』

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
Avatar for EngineerCafe EngineerCafe
November 23, 2023
340

 Pythonで人工生命『生命のパターンを作ってみよう』

Avatar for EngineerCafe

EngineerCafe

November 23, 2023
Tweet

More Decks by EngineerCafe

Transcript

  1. かっこ内は参考書で想定されているバージョン(最新でも⼀応動いてます) n NumPy (1.14.5) n Vispy (0.5.3) n PyQt (5.10.1)

    n Pyglet (1.3.2) n Pymunk (5.3.2) n Pillow (5.1.0) n Keras (2.2.0) n TensorFlow (1.8.0) 必要なライブラリ 11
  2. Gray-Scottモデルの仕組み:「反応」 20 U V U U U V V V

    V V V V 物質Uを一定の 補充率で追加 反応:2つのVが エサとしてUを使いVを作る 物質Vは一定の 減量率で不活性化 P U
  3. Gray-Scottモデルの仕組み:「拡散」 21 U U U U U U U U

    U U U U U U U U U U U U U U V V V V V V V V V V V V V V V V
  4. 物質UとVの濃度の変化を表す式で表される!(u,vはU,Vの濃度で0〜1) 𝜕𝑢 𝜕𝑡 = 𝐷𝑢Δ𝑢 − 𝑢𝑣! + 𝑓 1

    − 𝑢 𝜕𝑣 𝜕𝑡 = 𝐷𝑣Δ𝑣 + 𝑢𝑣! − 𝑣(𝑓 + 𝑘) Gray-Scottモデルの振る舞いを表す式 22 変化量 拡散 反応 流入・流出
  5. 数式を読み解いていこう:変化量 23 u, vは「とある位置(x, y)、とある時間(t)の濃度」 デジタルではこれらの変数x, y, tは離散 𝜕𝑢 𝜕𝑡

    , 𝜕𝑣 𝜕𝑡 は「とある位置に、⾜される量(変化量)」 今のステップ t = n 次のステップ t = n+1 + =
  6. import sys, os sys.path.append(os.pardir) # 親ディレクトリのファイルをインポートするための設定 import numpy as np

    from alifebook_lib.visualizers import MatrixVisualizer # visualizerの初期化 (Appendix参照) visualizer = MatrixVisualizer() 結果を可視化するための準備 30
  7. # シミュレーションの各パラメタ SPACE_GRID_SIZE = 256 # 空間サイズ(縦横のマス数) dx = 0.01

    dt = 1 VISUALIZATION_STEP = 8 # 何ステップごとに画⾯を更新するか。 シミュレーション空間の設定 31
  8. # モデルの各パラメタ Du = 2e-5 Dv = 1e-5 f, k

    = 0.035, 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 定数の設定 32
  9. # 初期化 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 初期状態の設定 33
  10. 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) シミュレーション 34
  11. 1. 空間がある セルを格⼦状に敷き詰める「空間」 2. 時間がある セルの状態を変更する時間単位(ステップ)がある 3. 状態がある 「⽣死の2つ」や「誕⽣、維持、志望の3つ」 4.

    セルの状態を変える条件がある 基本的には、対象のセルの現在の状態と隣接するセルの状態によって、対象の セルの状態を決定する セルラー・オートマトンのルール 37
  12. import sys, os sys.path.append(os.pardir) # 親ディレクトリのファイルをインポートす るための設定 import numpy as

    np from alifebook_lib.visualizers import ArrayVisualizer # visualizerの初期化 (Appendix参照) visualizer = ArrayVisualizer() 結果を可視化するための準備 42
  13. 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) シミュレーションの設定 43
  14. # 最初の状態を初期化 state[len(state)//2] = 1 while visualizer: # 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] シミュレーションを実⾏・可視化 44
  15. 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) シミュレーションを可視化(続き) 45
  16. n RULE の値を変更 # CAのバイナリコーディングされたルール (Wolfram code) RULE = 110

    おすすめルール:40・232・94・108・54・90・110・121 n 最初の状態を初期化 の部分を変更 # 最初の状態を初期化 ### ランダム ### state[:] = np.random.randint(2, size=len(state)) いろいろ変えて遊んでみよう 46