(セル・オートマトン法)
独立変数である時間や空間座標を差分化するだけでなく,従属変数(関数)の取りうる値も離散化 (ディジタル化) したモデルで法則を表現することも可能である。有限系しか扱えない点を除けば,丸め誤差のことを心配せずに正確な計算ができ,計算機をもっとも効率的に駆使することができる。実際,この方法はビット演算を基本とするディジタル回路網の発想そのものと関わりを持っており,計算機が開発された当時から研究が行われてきた。その後「ライフゲーム」などを経て,今日ではセルオートマトン法と呼ばれ様々な分野で応用されている。
(1次元モデル)
(0, 1) のビットを1列に並べておき,次の瞬間の各ビットの値を「現在の自分と両隣 (場合によってはさらにその隣) の値のセットから決める規則」を与え,ビット列を同時的に更新する。
(規則の例)
111 110 101 100 011 010 001 000
| | | | | | | |
V V V V V V V V
1 0 1 1 1 0 0 0 <---- 184の2進数表現
(10111000)と読む
このような規則は,「どんな場合でも0に変わる」「どんな場合でも1に変わる」というトリビアルなものも含めて全部で256種類作ることができる。これに通し番号をつけて,上の例なら「ルール184」のように名付ける。
得られるパターンは,・一様なパターン,・周期的パターン,・進行パターン,・繰り返しパターン,などに分類することができる。この「ルール184」は0(1)の数を保存する進行パターンになり,先にあげたバーガース方程式の離散化モデルとも解釈される。
(多次元モデル)
多次元への拡張は明白であろう。しかしパターンの変化を図示し目で見て確認できるのは2次元に限られる。この場合は,2次元の正方格子網の各格子点にビットを配置しておき,自分と左右上下(斜め上下)の5つ(9つ)の値のセットから次の値を決めるルールを与える。
「ライフゲーム」の例
・各格子点は「生」「死」の2値をとる。
・左右上下斜め上下の8つの近隣の点のうち
「生」が1以下または4以上の場合には,「生」は「死」へ
「生」がちょうど3個の場合だけ,「死」は「生」へ
変わる。
プログラムは簡単である。
(例) 最初に中心に1個だけ 「生」# があり,ルールが 「8つの近隣のうち1個が『生』のときだけ新たに『生』に転じ,それ以外は変わらない」 の場合:
# # # # # # # #
# # # # # # # # # # # # # # # # # #
# # # # # # # #
# # # # # # # # # # # # # # # #
# # # # # # # # # # # # # #
# # # # # # # # # # # # # # # #
# # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # #
# # #
# # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # #
# # # # # # # # # # # # # # # #
# # # # # # # # # # # # # #
# # # # # # # # # # # # # # # #
# # # # # # # #
# # # # # # # # # # # # # # # # # #
# # # # # # # #
INTEGER :: b(-40:40, -40:40) = 0, a(-40:40, -40:40) = 0, i, j, t
b(0,0) = 1
DO t = 1, 38
DO i = -39, 39
DO j = -39, 39
a(i,j) = b(i+1,j) + b(i+1,j+1) + b(i,j+1) + b(i-1,j+1) &
+ b(i-1,j) + b(i-1,j-1) + b(i,j-1) + b(i+1,j-1)
END DO
END DO
!
DO i= -40, 40
DO j= -40, 40
IF( a(i,j)==1 ) b(i,j)=1
END DO
END DO
END DO
.................
Fortranでは配列演算式を用いれば,もっと簡単に書けるが,Cプログラムでも解釈可能な形で書いた。作業を2段階に分けることにより,配列 b の全要素は(結果的には)同時的に更新されるようになっていることに注意しよう。
<課題1>
(交通渋滞) 上で1次元の例にあげた 「ルール184」 は,「高速道の自然渋滞モデル」 と呼ばれるもので,(0,1) は各点に 「車がいない」 「いる」 を表し,「すぐ前 (右) が空いているときには車は1つずつ前 (右) へ進み,他の車がいるときには止まったまま」 という規則に相当する。
端は周期的に繋ぐ(=サーキットだ!)とし,適当な長さの格子点上に最初に(0,1)をランダムにばらまいておいて,その後のパターン変化の様子を(一部分でよいから)表示してみよ。
プログラムはすべてのルール番号(≦255)について適用可能な形で書くことにせよ。[ルールは関数ではなく,予め要素数8の配列で表すようにする方が効率的である。]
<課題2>
(森林火災) 森林にまばらに木が生えている。それぞれの木は,隣接する木のうち1本でも燃えだしたら自分も発火する。どこかで火災が発生したとき,どれくらいの密度で木が生えていたら森林のほとんどが類焼してしまうであろうか? デモ→ 森林火災(=サイト問題) 浸水(=ボンド問題)
(1) まず,L×Lの正方形の格子点に,pの割合(つまり全部でpL2本)でランダムに木をばらまく。[ Lは大きいほどよいが,L=200 くらいが限度であろう。]
(2) 最初にランダムにどれかの木を一本選んで発火させる(=値を1にする)。
(3) 上下左右斜め上下の隣接する8箇所のうち,1本でも発火している木があったら,次のステップで自分も発火するルールを与える。もちろん全ての木を同時的に更新。
(4) 燃えている木の数が一定になるまでステップを繰り返す。[ヒント:燃えている木の総数は減ることはなく,また同じ値が2回続けばそれ以上増えることはない。]
(5) 定常に達したときの燃えている木の占める率(最初にばらまいた本数に対する率)とpの関係を求め,これが0から1へと急激に変わるpのおよその値(自然鎮火の限界値)を見いだせ。特に 0.35 と 0.45 の間はくわしく調べること。各pの値に対して木の配置を変えて10回くらい繰り返して平均を取ること。
隣接点を上下左右のみにした例:限界値は上の場合と異なり,0.59 程度。
(ヒント) 上下辺上および右端の処理だけプログラム上は特別にしなければならないが,用意する配列を実際の森の大きさより1つずつ大きめにとり,ここは木が生えていないようにしておけば簡単化できる。なお,木が生えていることを表す配列と,燃えていることを表す配列は別にしておく方がプログラムしやすいであろう。