見出し画像

非同期同調セル・オートマトンの実装とRNAワールド仮説からの考察(コード付き)

フォン・ノイマンによって考案されたセル・オートマトンは、単純なルールが生み出すカオスの創発のトイ・モデルとしてさまざまなバージョンが生み出されてきた。

代表的なものに、ラングトンの蟻やコンウェイによるライフ・ゲームがある。

ラングトンのアリ

ウルフラムによる分類によれば、最も単純なセル・オートマトンは4つのクラスに分類され、そのうちの4番目のクラスがカオス的でありながら周期的な興味深い状態、すなわち「カオスの淵」に位置する。そして、この4番目のクラスは、ルール全体を見回しても滅多に見当たらないレアなものである。

定説によれば、あらゆる生命体はこの4番目のクラスの自己複製プロセスを進化の過程で身に付けたが故に、いい感じに環境に適応できるちょうどいいカオス状態=自己組織臨界状態を身につけてきた、という。

ウルフラムによるセル・オートマトンのクラスの分類。右下が「カオスの淵」。

郡司ぺギオ幸夫による「非同期同調セル・オートマトン(AT ECA)」はこの定説に対して疑義を呈する。

通常のセル・オートマトンでは、横一列に並んだ全てのセルが同時に更新される、すなわちグローバル・クロックによる更新が行われるが、非同期(Asynchronous)なセル・オートマトンは各セルが持つローカル・クロックに基づいて更新が行われる。同期をずらす方法にはいくつかの実装方法が考えられるが、郡司がここで用いるのは毎回の更新において異なる「更新の順番」を定め、セルが順次自らの値を更新していくという方法だ。そして、通常セル・オートマトンに非同期性を持ち込むと、いい感じのカオス性が損なわれる場合が多いので、それを避けるための仕組みとして「同調」、つまり非同期的更新によって生じる歪みをルールの部分的更新によって補填する仕組みを郡司は導入した。

この「非同期同調」ルールを使えば、クラス1〜3に属する「ありふれた」ルールであっても、自己組織臨界状態に持ち込むことができる。下が通常バージョン、上が非同期同調バージョンだ。同じセルの更新ルールであったとしても、クラス3のルールが非同期同調性を盛り込むことでクラス4に変換されていることがわかる。

再現実験をしてみた。

郡司の実験によると、これらのクラス4に分類されるセル・オートマトンは、最近流行りのリザーバーコンピューティングのリザーバとしても優秀な成績を示す。つまり、生物の計算はこれらの自己組織化臨界状態を賢く活用するために、何らかの非同期同調性を自然な形で実装しているのだ、というのが郡司の主張だ。

この構造は、DNAについての考え方の変遷に似ているように思える。

遺伝子をめぐる言説はこれまでクリックによって提唱された「セントラルドグマ」に基づいて、「DNA→RNA→タンパク質」という一方向の流れによって支配され、それによって生命のあらゆる遺伝的形質が生み出されている、という説が支配的だった。ところがゲノム解析が進むにつれて、実際には転写の役割を担う「RNA」、その中でのタンパク質の合成に関与しない「非コードRNA」がゲノム配列のかなりの割合を占めていることが明らかになった。

中屋敷は「遺伝子とは何か?」の中で、以下のように述べる。

ヒトゲノムには、わずか数万個の遺伝子に対して潜在的に数百万個に及び制御配列が存在し、選抜されたものに限っても、タンパク質をコードする塩基配列の6.5倍の量の塩基数が制御配列として機能しているということになる。たとえていうなら、見えている電球の数を遥かに超える配線が天井や壁の裏に張り巡らされており、その途中のあちらこちらにある調節スイッチで、1つあるいは複数の電球のオンオフや光強度を変えて、複雑な電飾パフォーマンスを演じている、生体とはそのようなイメージでできていることが示唆されたのである。

「遺伝子とは何か? 現代生命科学の新たな謎」

郡司の非同期同調セル・オートマトンにおいて、「タンパク質合成」の役割を担うのが、セル更新のルールだとするならば、「非コードRNA」にあたるのが、彼の導入した「非同期同調ルール」だ。

興味深いことに、郡司が定義した「非同期同調ルール」には能動的ルールと受動的ルールの2通りのルールがある。これらはスタート時点では同一のものを使用するが、能動的ルールは計算の過程でルールの中身が更新されていく。

この「受動的ルール」と「能動的ルール」の関係は、ハードディスクに例えられる「DNA」(固定ルール、突然変異などで変更されることがない限りは変更がない)と、状況に合わせて流動的に変化する「RNA」の関係に似ている。

だとすると、郡司の導入した「非同期同調ルール」は、RNAワールドの驚くべき多様性を鑑みるに、もっと多様で複雑なルールに拡張しうるのではないかという展望が見えてくる。すなわち、セル・オートマトンの実際の更新ルールよりもむしろ、その更新ルールの「発現度合い」を調整するための「背後のルール」を多様化・複雑化することで、より自己組織臨界状態に近いパターンを生成するセル・オートマトンを開発できる可能性がある。「非コードルール」が持っている可能性を、探究する余地があるということだ。

(参考)Google Colab上で、非同期同調セル・オートマトンを実行できるコードをChatGPTを用いて作成したので、試してみたい方はぜひ。

import numpy as np
import matplotlib.pyplot as plt

# 初期設定
cols = 1000
steps = 1000
rule_number = 60

# ルールの変換
rule_bin = np.array([int(x) for x in np.binary_repr(rule_number, width=8)])

# 初期の能動的ルールと受動的ルールは同じ
active_rule = rule_bin.copy()
passive_rule = rule_bin.copy()

def apply_rule(left, center, right, rule):
    index = left * 4 + center * 2 + right
    return rule[7 - index]

# セルオートマトンの初期状態をランダムに設定
initial_cells = np.random.randint(0, 2, cols)

# 各セルの更新状態を管理
updated = np.zeros(cols, dtype=bool)

# 非同期同調セルオートマトンの実行
async_history = [initial_cells.copy()]
async_cells = initial_cells.copy()

for step in range(steps):
    new_async_cells = async_cells.copy()
    indices = np.random.permutation(cols)  # ランダムな順番でセルを更新
    for i in indices:
        left = async_cells[i - 1] if i > 0 else async_cells[-1]
        center = async_cells[i]
        right = async_cells[(i + 1) % cols]

        if not updated[i - 1] and not updated[(i + 1) % cols]:  # 隣接するセルがどちらも未更新の場合
            new_async_cells[i] = apply_rule(left, center, right, active_rule)
            updated[i] = True
        elif updated[i - 1] and updated[(i + 1) % cols]:  # 隣接するセルがどちらも更新済みの場合
            new_async_cells[i] = apply_rule(left, center, right, passive_rule)
            updated[i] = True
            active_rule = passive_rule.copy()  # 能動的ルールを変更
        else:  # 隣接するセルの片方だけが更新済みの場合
            new_async_cells[i] = apply_rule(left, center, right, passive_rule)
            updated[i] = True
            active_rule = np.array([apply_rule(0, 0, 0, passive_rule)] * 8)

    async_cells = new_async_cells.copy()
    async_history.append(async_cells.copy())
    updated = np.zeros(cols, dtype=bool)  # 各ステップ終了後に更新状態をリセット

# 通常のセルオートマトンの実行
sync_history = [initial_cells.copy()]
sync_cells = initial_cells.copy()

for step in range(steps):
    new_sync_cells = sync_cells.copy()
    for i in range(cols):
        left = sync_cells[i - 1] if i > 0 else sync_cells[-1]
        center = sync_cells[i]
        right = sync_cells[(i + 1) % cols]
        new_sync_cells[i] = apply_rule(left, center, right, rule_bin)
    sync_cells = new_sync_cells.copy()
    sync_history.append(sync_cells.copy())

# 進捗の可視化
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 20))

# 非同期同調セルオートマトンの可視化
ax1.imshow(async_history, cmap='binary')
ax1.set_title('Asynchronous Synchronous Cell Automaton (Rule 60)')
ax1.set_xlabel('Cells')
ax1.set_ylabel('Steps')

# 通常のセルオートマトンの可視化
ax2.imshow(sync_history, cmap='binary')
ax2.set_title('Synchronous Cell Automaton (Rule 60)')
ax2.set_xlabel('Cells')
ax2.set_ylabel('Steps')

plt.tight_layout()
plt.show()

Yukio , Gunji. Self-Organized Criticality in Asynchronously Tuned Elementary Cellular Automata, https://arxiv.org/pdf/1306.4419

(参考)
郡司の「非同期同調セル・オートマトン(AT ECA)のルールの詳細

①隣接するセルがどちらも未更新の場合、両隣の未更新セルの状態に能動的ルールが適用されて更新され、能動的ルールは更新されない。

②隣接するセルがどちらも更新済みの場合、両隣の更新済みセルの状態に受動的ルールが適用されて更新される。その後、両隣が未更新であった場合の能動的ルールの更新を、この時の更新でできた状態と同じになるように能動的ルールを変更する。

③隣接するセルの片方だけが更新済みの場合、更新済みのセルの状態に受動的ルールが適用されて更新される。その後、両隣が未更新であった場合の能動的ルールの更新を、受動的ルールの「000」に対する更新と同じになるように能動的ルールを変更する。

この記事が気に入ったらサポートをしてみませんか?