Pythonでラングトンのアリ! 人工生命入門

皆さんラングトンのアリって聞いたことありますか?

ラングトンのアリは、とても単純な規則で動くチューリングマシンで、移動して訪れた格子状の平面のセルに何らかの変化を記録しながら、その環境と対話する形で、行動をする人工生命です。アリはあまり関係ないように感じますが、自分が訪れた位置に記録を残す点でアリに似ていますね。人工生命入門では、以前、ライフゲームについて説明しましたが、このラングトンのアリも、格子平面上の小さなセルに対する単純な規則のみで、はたから見ると、知的な行動・意思決定をしているように見える面白いものです。

では、Pythonでプログラムを作成していきましょう!

ラングトンのアリとは

ラングトンのアリは、アメリカの計算機科学者のクリストファー・ラングトンにより発明されたチューリングマシンです。

ルールは簡単です、格子状の平面にあるセルにありは存在することができ、今注目しているセルが黒なら白に反転させて左に移動、白なら黒に反転させて右に移動、ということを永遠と繰り返すだけです。前回のライフゲームよりもっとルールが簡単ですね!

ラングトンのアリをPythonで実装!

まずは、必要なライブラリをインポートします。

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from IPython.display import HTML
class L_ant:
  def __init__(self, floor, j, i, S):
    self.floor = floor
    self.Y, self.X = floor.shape
    self.i = i  #jとiはx, y座標の値、Sはステートとして上右下左のどちらを向いているかの初期状態を0~3で指定
    self.j = j
    self.S = S

  def start(self): 
    if self.floor[self.i, self.j] == 1:
      self.floor[self.i, self.j] = 0
      self.left()
    else:
      self.floor[self.i, self.j] = 1
      self.right()
    return self.floor

  def left(self):
    if self.S == 0:
      self.S = 3
      self.j -= 1
      self.check()

    elif self.S == 1:
      self.S = 0
      self.i -= 1
      self.check()

    elif self.S == 2:
      self.S = 1
      self.j += 1
      self.check()

    else:
      self.S = 2
      self.i += 1
      self.check()


  def right(self):
    if self.S == 0:
      self.S = 1
      self.j += 1
      self.check()

    elif self.S == 1:
      self.S = 2
      self.i += 1
      self.check()

    elif self.S == 2:
      self.S = 3
      self.j -= 1
      self.check()

    else:
      self.S = 0
      self.i -= 1
      self.check()

  def check(self):
    if self.i < 0:
      self.i = self.Y - 1
    elif self.i >= self.Y:
      self.i = 0

    if self.j < 0:
      self.j = self.X - 1
    elif self.j >= self.X:
      self.j = 0
ant = L_ant(np.zeros((100, 100), dtype=np.int), 50, 50, 0)

#アニメーション生成の前準備
fig = plt.figure(figsize=(15, 15))
#表示される図の目盛りを非表示にします。
plt.tick_params(labelbottom=False,
                labelleft=False,
                labelright=False,
                labeltop=False)
ims = []  # アニメーション作成に使用します。

for _ in range(100000):
  im = plt.imshow(ant.start(), cmap=plt.cm.gray_r, animated=True)
  ims.append([im])

#アニメーションの生成をします。
ani = animation.ArtistAnimation(fig, ims)
plt.close()

# save as JavaScript/Html file
f = open("ani.html", "w")
f.write(ani.to_jshtml())
f.close()

#HTML(ani.to_html5_video())
HTML(ani.to_jshtml())

どうでしょう?動きましたか?

自分が訪れたところの色を反転させて、色に応じで左か右に曲がるのみという本当に単純な仕組みのみで、最初はでたらめに動いているのに、いきなり規則的に動き出し、黒の部分にぶつかると、またでたらめに動き出す…なんとも不思議ですね。

人工生命もかなり単純なようで奥深く楽しいものがあります。もっと勉強したいですね。

※gifファイルにすると長すぎてPCを丸一日動かしていても結果が出なかったので、ここでGifかYouTube動画の実演はお見せできませんが、プログラムが正しく動作していることは確認済みですので、近いうちに何とかしたいと思います。

Follow me!