Pythonで一次元セル・オートマトンを実装してみた

Pythonで一次元セルオートマトンの発展を描画するコードを書いてみました。最後にいくつかのルールで実行した結果を載せています。
#セル・オートマトン
セルオートマトン(cellular automaton)はある局所的な規則(ルール)によってセルの状態を発展させていくというもので、物理学者[Stephen Wolfram](https://ja.wikipedia.org/wiki/%E3%82%B9%E3%83%86%E3%82%A3%E3%83%BC%E3%83%96%E3%83%B3%E3%83%BB%E3%82%A6%E3%83%AB%E3%83%95%E3%83%A9%E3%83%A0)や数学者[John Horton Conway](https://ja.wikipedia.org/wiki/%E3%82%B8%E3%83%A7%E3%83%B3%E3%83%BB%E3%83%9B%E3%83%BC%E3%83%88%E3%83%B3%E3%83%BB%E3%82%B3%E3%83%B3%E3%82%A6%E3%82%A7%E3%82%A4)らによりその性質が詳細に研究されました。
ルールを変えることにより様々な自然現象を模すことができ、2次元のものは「ライフゲーム」として知られています。

#ルール
![Untitled Diagram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463630/a0ffc128-4949-c2f6-d3a4-9d1d3f6080bd.png)

一次元セルオートマトンのルールには番号がつけられています。例えばルール214とよばれる規則は上図のようになります。よくわからなければ[こちらの記事](https://qiita.com/78hack/items/3086af76d1319f549c49)に詳しく書いてあるのでみていただければ良いかと思います。

#Pythonで実装
上の規則を実装してみます。

```python:1d_ca.py
import matplotlib.pyplot as plt

def cellautomaton(l_bit, rule, pattern=False, padding=0):
    # pattern: 周期的境界条件, padding: 枠外のセルの値
    l_bit_new = []
    if not pattern:
        l_bit = [padding] + l_bit
        l_bit.append(padding)
    else:
        l_bit = [l_bit[-1]] + l_bit
        l_bit.append(l_bit[1])
    for i in range(1, len(l_bit)-1):
        l_bit_new.append(next_state(l_bit[i-1],l_bit[i],l_bit[i+1], rule))
    return l_bit_new

def next_state(l, x, r, rule):
    # 次のセルの状態を決定
    bin_str = format(rule, '08b')
    bin_num = int(str(l)+str(x)+str(r), 2)
    return int(bin_str[-(bin_num+1)])

def main():
    result = []
    loop = 200
    rule = 110 # ルール番号(0~255)

    ## リストxで初期状態を指定
    x = [0]*200
    x[-1] = 1
    result.append(x)
    for i in range(loop):
        x = cellautomaton(x, rule, pattern=False)
        result.append(x)
    plt.figure()
    plt.title("rule{}".format(rule))
    plt.imshow(result, cmap="binary")
    plt.show()

main()
```
デフォルトでは長さ100で、一番右のセルだけが1、あとは0の一次元配列にしてあります。色々いじって変えてみると面白いです。
最後にこのコードを使っていくつかのルールでの例をみてみます。

#ルール30
[Stephen Wolfram](https://ja.wikipedia.org/wiki/%E3%82%B9%E3%83%86%E3%82%A3%E3%83%BC%E3%83%96%E3%83%B3%E3%83%BB%E3%82%A6%E3%83%AB%E3%83%95%E3%83%A9%E3%83%A0)は一次元セルオートマトンの振る舞いを4つのクラスに分類しています。簡単にいうと次のような感じです。

- クラス1: 全て0、全て1のような状態に収束する
- クラス2: 決まった振動を繰り返す状態に収束する
- クラス3: カオスな状態になる
- クラス4: 周期的な状態とカオスな状態が共存する(カオスの縁)

ルール30はクラス3のカオスな状態になる規則です。![rule30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463630/f5fb7dfd-f8c6-4f0e-b3d9-6f6749ab8e4c.png)

複雑で周期性のない模様になっていることがわかります。

#ルール90
ルール90はクラス3に属する規則ですが、シルピンスキー・ガスケットと呼ばれるフラクタル図形を描きます。
![rule90.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463630/59d4c63e-4cb5-0177-0076-5e3871aa9c74.png)
フラクタル図形とは、拡大/縮小すると同じような形が現れるような図形です。

#ルール110
ルール110は周期的な状態とカオスの中間的な状態をとるクラス4に属する規則です。

![rule110.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463630/aa7a7d58-f00d-90aa-f7be-ad6e8e42ab8d.png)

周期性ができてしばらく続いて壊れる、といったのがみて取れると思います。このオーダーとカオスの中間的なダイナミクスは自然現象に多くみられることが知られ、またこのような領域の豊かなダイナミクスを利用して、チューリングマシンを模すこともできるそうです。

以上です。他のルールの図形は[この記事](https://qiita.com/gushwell/items/feca11a0147b90613d5d)など、調べるといっぱいあります。実用的な例だと[この記事](https://qiita.com/gushwell/items/767112fcf1c725632113)のように交通シミュレーションで使われることがあるようです。

#参考文献
[図解雑学 複雑系(今野紀雄　ナツメ社)](https://hb.afl.rakuten.co.jp/ichiba/1bc63814.31bba873.1bc63815.5874eb3b/?pc=https%3A%2F%2Fitem.rakuten.co.jp%2Fcomicset%2F4816323899%2F&link_type=hybrid_url&ut=eyJwYWdlIjoiaXRlbSIsInR5cGUiOiJoeWJyaWRfdXJsIiwic2l6ZSI6IjI0MHgyNDAiLCJuYW0iOjEsIm5hbXAiOiJyaWdodCIsImNvbSI6MSwiY29tcCI6ImRvd24iLCJwcmljZSI6MSwiYm9yIjoxLCJjb2wiOjEsImJidG4iOjEsInByb2QiOjB9)