2026-05-23

計算機が描く自然の美:数式とアルゴリズムが生み出すパターン

チューリング・パターンからフラクタルまで、自然界の模様を数式とコードで視覚的に読み解く

Table of Contents

シマウマの美しい縞模様、雪の結晶の対称性、海岸線の複雑な入り組み方——。 自然界に存在するこれらの美しいパターンは、一見すると無作為で複雑怪奇に見えますが、実は非常にシンプルな数式とアルゴリズムから生成されていることをご存知でしょうか。

本記事では、自然界に潜む「美のアルゴリズム」を、実際のビジュアルと数学的な説明を交えて解説していきます。「自然の美しさは、単純なルールの繰り返しから生まれる」という驚くべき真実を、ぜひ一緒に体験してみましょう。

Image
タテジマキンチャクダイ。この縞模様もチューリング・パターンの結果であると考えられている。

1. チューリング・パターン:生命の模様を描く方程式

動物の体表に見られる規則的な模様(斑点や縞々)は、どのようにして形成されるのでしょうか。この謎に数学的アプローチで挑んだのが、現代計算機科学の父であるアラン・チューリングです。

Image
アラン・チューリング(1912-1954)。コンピュータの基礎を築いただけでなく、自然界の模様形成のメカニズムも数式で解明した。

彼は、2種類の化学物質(アクティベーターとインヒビター)が「拡散」しながら「反応」する過程で、自発的に空間的な波の模様が生まれることを数式で示しました。これが反応拡散方程式です。

ut=Du2u+f(u,v)vt=Dv2v+g(u,v)\begin{align} \frac{\partial u}{\partial t} &= D_u \nabla^2 u + f(u, v) \\ \frac{\partial v}{\partial t} &= D_v \nabla^2 v + g(u, v) \end{align}
方程式の意味
  • u,vu, v:2種類の化学物質の濃度
  • Du,DvD_u, D_v:物質が広がるスピード(拡散係数)
  • 2\nabla^2:空間における濃度の広がり(ラプラシアン)
  • f,gf, g:2つの物質がどう反応するかを示す関数

つまり、「物質がじわじわ広がる力」「物質同士が化学反応する力」 のバランスだけで、シミュレーション上にも生体と同じような模様が描き出されるのです。

Image
計算機シミュレーションによって生成されたチューリング・パターンの例。
Image
フグの皮膚の実際の模様。チューリング・パターンの理論が自然界の模様形成を説明する有力なモデルであることがわかる。

Pythonでチューリング・パターンをシミュレーションする

実際にPythonを使って、反応拡散方程式(ここではよく用いられるGray-Scottモデル)を計算してみましょう。以下のコードを実行すると、単純な数式の反復から、生き物の皮膚のような複雑な模様が浮かび上がる様子を確認できます。

pufferfish_pattern.py
1import numpy as np
2import matplotlib.pyplot as plt
3from matplotlib.colors import LinearSegmentedColormap
4
5def laplacian(Z):
6    # 空間の広がり(ラプラシアン)を上下左右のセルから計算
7    return (np.roll(Z, 1, axis=0) + np.roll(Z, -1, axis=0) +
8            np.roll(Z, 1, axis=1) + np.roll(Z, -1, axis=1) - 4 * Z)
9
10# ★ここが重要! ラビリンス(迷路)模様を作るパラメータ
11Du, Dv = 0.16, 0.08  # 拡散係数はそのまま
12F, k = 0.042, 0.061  # Fとkのバランスを変えることで迷路模様になる
13iterations = 10000   # 模様が画面全体に広がるようにステップ数を増やす
14size = 200           # 網目状の細かさを表現するためにサイズを拡大
15
16# 初期状態のセットアップ
17U = np.ones((size, size))
18V = np.zeros((size, size))
19
20# 画面全体にランダムな「種」を撒く(全体から模様を成長させるため)
21np.random.seed(42) # 再現性のためのシード値
22U += 0.05 * np.random.random((size, size))
23V += 0.05 * np.random.random((size, size))
24
25# 中央付近に初期のきっかけを配置
26r = 20
27U[size//2-r:size//2+r, size//2-r:size//2+r] = 0.50
28V[size//2-r:size//2+r, size//2-r:size//2+r] = 0.25
29
30# 時間発展の計算
31for i in range(iterations):
32    Lu = laplacian(U)
33    Lv = laplacian(V)
34    
35    uvv = U * V * V
36    
37    U += Du * Lu - uvv + F * (1 - U)
38    V += Dv * Lv + uvv - (F + k) * V
39
40# ★画像のフグの色合いに似せたオリジナル・カラーマップを作成
41colors = ["#132226", "#2c4a45", "#81a166", "#d9e8b3"] # 暗い緑〜明るい黄緑
42puffer_cmap = LinearSegmentedColormap.from_list("puffer", colors)
43
44# 画像の生成と表示
45plt.figure(figsize=(6, 6))
46plt.imshow(V, cmap=puffer_cmap, interpolation='bicubic')
47plt.axis('off')
48plt.title("Labyrinth Pattern (Pufferfish Style)", fontsize=14)
49plt.tight_layout()
50plt.show()

2. フラクタル:無限に続く「自己相似」

自然界のもう一つの重要なパターンが フラクタル(Fractal) です。 リアス式海岸、雪の結晶、血管の分岐などは、全体を拡大していくと、その一部が再び全体と同じ形をしている「自己相似性」を持っています。

その代表例として、自然界に存在する美しいフラクタルである「ロマネスコ・ブロッコリー」を見てみましょう。

Image
ロマネスコ・ブロッコリー。小さな円錐が集まって大きな円錐を作り、それがさらに大きな円錐を作っている。

また、数学の世界で最も有名なフラクタルである「マンデルブロ集合」は、驚くほど単純な複素数の漸化式から生まれます。

zn+1=zn2+cz_{n+1} = z_n^2 + c

この単純な計算を無限に繰り返したとき、zz の値が発散しないような初期値 cc をプロットすると、あの息を呑むような無限の図形が浮かび上がります。

Image
マンデルブロ集合。境界部分をどれだけ拡大しても、元の図形と似た複雑な模様が永遠に現れ続ける。

Pythonでマンデルブロ集合を描く

実際にPythonを使って、この図形を計算してみましょう。

mandelbrot.py
1import numpy as np
2import matplotlib.pyplot as plt
3
4def generate_mandelbrot(width, height, x_min, x_max, y_min, y_max, max_iter):
5    # 複素数平面のグリッドを作成
6    x = np.linspace(x_min, x_max, width)
7    y = np.linspace(y_min, y_max, height)
8    X, Y = np.meshgrid(x, y)
9    C = X + 1j * Y
10    Z = np.zeros_like(C)
11    
12    # 発散するまでの繰り返し回数を記録する配列
13    escape_time = np.zeros(C.shape, dtype=int)
14    mask = np.ones(C.shape, dtype=bool)
15
16    for i in range(max_iter):
17        Z[mask] = Z[mask]**2 + C[mask]
18        
19        # 閾値(半径2)を超えたら発散とみなす
20        diverged = np.abs(Z) > 2
21        escape_time[diverged & mask] = i
22        mask[diverged] = False
23
24    return escape_time
25
26# 画像の生成と表示
27image = generate_mandelbrot(800, 800, -2.0, 0.5, -1.25, 1.25, 100)
28plt.imshow(image, cmap='magma', extent=[-2.0, 0.5, -1.25, 1.25])
29plt.axis('off')
30plt.show()

3. ライフゲーム:単純なルールから生まれる複雑系

最後にご紹介するのは、1970年にイギリスの数学者ジョン・コンウェイが考案した ライフゲーム(Game of Life) です。 これは「セル・オートマトン」と呼ばれる計算モデルの一種で、碁盤の目のようなグリッド上の細胞が、隣接する周囲8マスの状態(生・死)に応じて、次の世代の生死を決定します。

ルールは以下の4つだけです。

  1. 誕生:死んでいるセルの周囲に生きているセルがちょうど3つあれば、誕生する。
  2. 生存:生きているセルの周囲に生きているセルが2つか3つあれば、生き残る。
  3. 過疎:生きているセルの周囲に生きているセルが1つ以下ならば、過疎により死滅する。
  4. 過密:生きているセルの周囲に生きているセルが4つ以上ならば、過密により死滅する。

このたった4つのルールから、自ら移動し続ける「グライダー」や、細胞を無限に生み出し続ける「グライダー銃」など、まるで意思を持っているかのような生命的な挙動が生まれます。

Image
ゴスパーのグライダー銃。固定されたブロックから、右下に向かって進む細胞の塊(グライダー)が永遠に生成され続ける。

おわりに

自然界の美しさは、神がひとつひとつ筆で緻密に描いたものではなく、「単純な物理的ルール(数式)や反復演算(アルゴリズム)」が織りなす創発の結果です。

数学やプログラミングを学ぶことは、単にアプリを作ったり計算をしたりするためだけのものではありません。「世界がどのようにできているか」を理解し、シミュレーションによってその美しさを自らの手で再現するための強力なツールなのです。

次に自然界の模様を見たとき、そこに隠された数式やアルゴリズムの存在に思いを馳せてみてください。見慣れているはずの世界が、まるで新しい芸術作品のように見えてくるかもしれません。