分岐過程の理論 — 絶滅確率の計算

ある種の動物が、各個体が平均して1.2頭の子を残す場合、その種は生き残れるでしょうか。直感的には「平均で1頭より多ければ増える」と思うかもしれません。しかし、子の数はランダムですから、運悪く子孫を残せない個体が続くと集団は絶滅してしまうかもしれません。こうした「ランダムな増殖と絶滅」の数学を扱うのが分岐過程(branching process)です。

分岐過程は19世紀にフランシス・ゴルトンが「名家の姓が消滅する確率」を計算しようとしたことに起源を持ち、その後ワトソンとともにこの問題を定式化しました。一見単純なモデルですが、集団の運命が平均子孫数という一つのパラメータで決まるという深い結果を含んでおり、現代では応用が驚くほど広範です。

  • 疫学: 感染症の基本再生産数 $R_0$ は分岐過程の平均子孫数 $m$ に対応し、$R_0 > 1$ でアウトブレイクが持続するかを判定します
  • 原子物理学: 核連鎖反応における中性子の増倍を分岐過程でモデル化します。臨界質量の計算にこの理論が使われました
  • コンピュータ科学: ランダムグラフの巨大連結成分の出現は分岐過程の超臨界転移と深く関係しています
  • 進化生物学: 遺伝子の系統樹の形成過程や有害変異の蓄積を分岐過程で記述します。突然変異が固定される確率の計算にも分岐過程の理論が使われます
  • ランダムグラフ理論: エルデシュ・レーニイのランダムグラフにおいて、巨大連結成分の出現は分岐過程の超臨界転移と本質的に同じ現象です

本記事では、ガルトン・ワトソンの分岐過程の基本理論を構築し、母関数を用いて絶滅確率を厳密に導出します。さらに、臨界性の分類と極限定理をPythonシミュレーションで検証します。

本記事の内容

  • ガルトン・ワトソン過程の定義と基本量
  • 母関数による絶滅確率の導出
  • 臨界性の分類(劣臨界・臨界・超臨界)
  • 期待値と分散の再帰関係
  • 極限定理(正規化マルチンゲール)
  • Pythonによるシミュレーションと理論の検証

前提知識

この記事を読む前に、以下の記事を読んでおくと理解が深まります。

分岐過程とは — 増殖と絶滅のモデル

直感的なイメージ

分岐過程は、各個体が独立に子孫を残す集団の世代交代モデルです。最も単純な設定では、各世代の各個体は同じ確率法則に従ってランダムな数の子孫を残し、次の世代を形成します。

たとえば、ある個体が0, 1, 2, 3頭の子をそれぞれ確率0.2, 0.3, 0.3, 0.2で残すとします。第0世代に1個体から始めて、この確率に従って子孫数を決定し、各子孫がまた同じ法則で子を残す、という過程を繰り返します。

ガルトン・ワトソン過程の定義

ガルトン・ワトソン過程(Galton-Watson process)$\{Z_n\}_{n \geq 0}$ は次のように定義されます。

  • $Z_0 = 1$(第0世代に1個体)
  • 子孫数の分布を $\{p_k\}_{k \geq 0}$ とする。すなわち、各個体が $k$ 個の子を残す確率が $p_k$ である
  • 第 $n+1$ 世代の個体数は、第 $n$ 世代の各個体の子孫数の総和である

$$ \begin{equation} Z_{n+1} = \sum_{i=1}^{Z_n} X_i^{(n)} \end{equation} $$

ここで $X_i^{(n)}$ は互いに独立で、すべて分布 $\{p_k\}$ に従います。$Z_n = 0$ の場合は $Z_{n+1} = 0$ と定義します(絶滅した集団は復活しない)。

基本量

子孫数分布の確率母関数(probability generating function, pgf)を次のように定義します。

$$ \begin{equation} G(s) = E[s^X] = \sum_{k=0}^{\infty} p_k s^k, \quad |s| \leq 1 \end{equation} $$

母関数は確率分布の情報を凝縮した強力な道具です。$G(s)$ のテイラー係数が確率 $p_k$ そのものであり、微分することでモーメントが得られます。

  • 平均子孫数: $m = G'(1) = E[X] = \sum_k k p_k$
  • 子孫数の分散: $\sigma^2 = G”(1) + G'(1) – [G'(1)]^2$

$m$ は分岐過程の振る舞いを決定する最も重要なパラメータです。

母関数の重要な性質を押さえたところで、絶滅確率の導出に進みましょう。

母関数による絶滅確率の導出

絶滅の定義

集団の絶滅(extinction)とは、ある有限の世代で個体数がゼロになることです。

$$ \begin{equation} q = P(\exists\, n : Z_n = 0) = P\left(\bigcup_{n=0}^\infty \{Z_n = 0\}\right) \end{equation} $$

$Z_n = 0$ ならば $Z_{n+1} = 0$ なので、事象 $\{Z_n = 0\}$ は $n$ に関して単調増大です。したがって、

$$ q = \lim_{n \to \infty} P(Z_n = 0) = \lim_{n \to \infty} q_n $$

ここで $q_n = P(Z_n = 0)$ は第 $n$ 世代までに絶滅する確率です。

$Z_n$ の母関数の再帰関係

$Z_n$ の確率母関数を $G_n(s) = E[s^{Z_n}]$ と書きます。$G_0(s) = s$($Z_0 = 1$ なので)です。

$Z_{n+1} = \sum_{i=1}^{Z_n} X_i^{(n)}$ という定義から、$Z_n = k$ が与えられたとき $Z_{n+1}$ は $k$ 個の独立な子孫数の和です。独立な確率変数の和の母関数は母関数の積になるので、

$$ E[s^{Z_{n+1}} | Z_n = k] = [G(s)]^k $$

$Z_n$ に関して期待値をとると、

$$ G_{n+1}(s) = E[E[s^{Z_{n+1}} | Z_n]] = E[G(s)^{Z_n}] = G_n(G(s)) $$

これは美しい再帰関係です。第 $n+1$ 世代の母関数は、第 $n$ 世代の母関数に $G(s)$ を「入れ子」にしたものです。

$$ \begin{equation} G_{n+1}(s) = G_n(G(s)) = G(G_n(s)) \end{equation} $$

帰納的に展開すると、

$$ G_n(s) = \underbrace{G(G(\cdots G}_{n \text{ 回}}(s)\cdots)) $$

つまり $G_n$ は $G$ の $n$ 回の合成(反復)です。

絶滅確率の不動点方程式

絶滅確率 $q_n = P(Z_n = 0) = G_n(0)$ です。$q_n = G_n(0) = G_{n-1}(G(0)) = G_{n-1}(p_0)$ と計算でき、$q_1 = G(0) = p_0$ から始まる再帰列

$$ q_{n+1} = G(q_n), \quad q_0 = 0 $$

が得られます($q_0 = P(Z_0 = 0) = 0$ は $Z_0 = 1$ より)。

$G$ は $[0, 1]$ 上で $G(0) = p_0 \geq 0$, $G(1) = 1$ であり、$G'(s) \geq 0$, $G”(s) \geq 0$($p_k \geq 0$ なので)です。つまり $G$ は下に凸な単調増大関数です。

$q_n$ は単調増大で1以下の列なので、極限 $q = \lim_{n \to \infty} q_n$ が存在します。極限で $q_{n+1} = G(q_n)$ の両辺を $n \to \infty$ とすると、

$$ \begin{equation} q = G(q) \end{equation} $$

が得られます。すなわち、絶滅確率 $q$ は母関数 $G$ の不動点です。

不動点の解析

$G(s) = s$ の解を調べます。$s = 1$ は常に解です($G(1) = 1$)。$s = 1$ 以外の解が $[0, 1)$ に存在するかどうかは、$G$ の形状に依存します。

$h(s) = G(s) – s$ と置くと、$h(0) = G(0) = p_0 \geq 0$, $h(1) = 0$ です。$h'(s) = G'(s) – 1$ なので、

  • $G'(1) = m > 1$ のとき: $h'(1) = m – 1 > 0$ なので、$s = 1$ の左近傍で $h(s) < 0$ です。$h(0) \geq 0$ と $h$ の連続性から、中間値の定理により $h(s) = 0$ の解が $(0, 1)$ に存在します
  • $G'(1) = m \leq 1$ のとき: $G$ の下凸性から $G(s) \geq s$ が $[0, 1]$ 上で成り立ち($m = 1$ のとき等号は $s = 1$ でのみ)、$s = 1$ 以外の不動点は存在しません

以上を絶滅確率の再帰列 $q_n = G(q_{n-1})$ の収束先と合わせると、次の基本定理が得られます。

絶滅確率の基本定理: 分岐過程の絶滅確率 $q$ は母関数の方程式 $G(q) = q$ の$[0, 1]$ における最小の解であり、

$$ \begin{equation} q = \begin{cases} 1 & \text{if } m \leq 1 \\ \text{$G(s) = s$ の最小の解} < 1 & \text{if } m > 1 \end{cases} \end{equation} $$

(ただし $p_0 > 0$ を仮定。$p_0 = 0$ のとき $q = 0$)

この定理は、集団の運命が平均子孫数 $m$ という単一のパラメータで決まるという、驚くべきシンプルな結果です。$m = 1$ という閾値を境に、集団の長期的な運命が質的に変わる「相転移」が起こります。

具体例: ポアソン分布の場合

子孫数がポアソン分布 $\text{Poisson}(m)$ に従う場合、母関数は $G(s) = e^{m(s-1)}$ です。不動点方程式 $e^{m(s-1)} = s$ の解を具体的に求めてみましょう。

$m = 1.5$ の場合、$e^{1.5(s-1)} = s$ を数値的に解くと $q \approx 0.4178$ が得られます。つまり、各個体が平均1.5頭の子を残す集団でも、約42%の確率で絶滅するのです。この値は直感よりも高いかもしれません。これは、ポアソン分布の $p_0 = e^{-1.5} \approx 0.223$(子を残せない確率)が無視できないためです。

$m = 2.0$ の場合、$q \approx 0.2032$ です。$m = 3.0$ では $q \approx 0.0595$ となり、平均子孫数が増えるにつれて絶滅確率は急速に減少します。

子孫数の分布が同じ平均 $m$ でも異なる場合、絶滅確率は分布の形状(特に $p_0$ の値)に依存します。一般に、分散が大きい分布ほど $p_0$ が大きくなるため、絶滅確率が高くなります。

二項分布 $\text{Bin}(4, m/4)$ の場合($m \leq 4$)、各個体が4回の「試行」で子を生むと考えると、分散は $m(1 – m/4)$ です。ポアソン分布の分散は $m$ であり、幾何分布 $\text{Geom}(1/(1+m))$ の分散は $m(1+m)$ です。幾何分布 > ポアソン > 二項分布の順に分散が大きく、同じ $m > 1$ に対して絶滅確率もこの順に高くなります。

この分散の効果は直感的にも理解できます。分散が大きいということは、「子孫をまったく残せない確率 $p_0$」が高いことを意味します。たとえ平均で多くの子を残せる場合でも、$p_0$ が大きければ初期の少数個体が偶然すべて子を残せない確率が無視できなくなり、絶滅のリスクが高まるのです。

臨界性の分類

劣臨界($m < 1$)

平均子孫数が1未満の場合、集団は確率1で絶滅します。直感的には、各世代で平均的に個体数が減少するため、いずれゼロに到達します。

$E[Z_n] = m^n \to 0$ なので、個体数の期待値は指数的にゼロに向かいます。実際には、$Z_n$ は整数値をとるため、$Z_n$ は期待値がゼロに向かうよりも前に(有限世代で)ゼロに到達します。

絶滅までの期待世代数は $E[\tau] = \sum_{n=0}^\infty P(Z_n > 0)$ で与えられ、$P(Z_n > 0) \leq E[Z_n] = m^n$ なので $E[\tau] \leq 1/(1-m)$ と有限です。

臨界($m = 1$)

平均子孫数がちょうど1の場合も、集団は確率1で絶滅します。しかし、劣臨界の場合に比べて絶滅までにはるかに長い時間がかかります。

臨界分岐過程では、$E[Z_n] = 1$(すべての世代で期待値は1)ですが、$P(Z_n > 0) \to 0$ です。これは一見矛盾しているように見えますが、「生き残っている場合の個体数の条件付き期待値が $\infty$ に発散する」ことで整合しています。

具体的には、$\sigma^2 = \text{Var}(X) > 0$ のとき($\sigma^2 = 0$ は自明な場合 $p_1 = 1$),

$$ P(Z_n > 0) \sim \frac{2}{n\sigma^2} \quad (n \to \infty) $$

$$ E[Z_n | Z_n > 0] \sim \frac{n\sigma^2}{2} \quad (n \to \infty) $$

生存確率は $1/n$ のオーダーでゼロに向かいますが、生き残った集団の平均サイズは $n$ に比例して大きくなります。この「条件付きでは大きくなるが、存在確率がゼロに向かう」という現象は臨界分岐過程の特徴的な性質です。

超臨界($m > 1$)

平均子孫数が1より大きい場合、集団は正の確率 $1 – q$ で生存し続けます。生存した場合、個体数は指数的に増大します。

マルチンゲール収束定理で見たように、正規化された個体数 $W_n = Z_n/m^n$ は非負マルチンゲールであり、$W_n \to W_\infty$ a.s. です。

  • $P(W_\infty = 0) = q$(絶滅した場合)
  • $P(W_\infty > 0) = 1 – q$(生存した場合)

生存した場合、$Z_n \approx W_\infty \cdot m^n$ と指数的に成長します。$W_\infty$ は「初期のランダムな揺らぎで決まる成長のスケール」を表しています。

期待値と分散の再帰関係

期待値

$Z_{n+1} = \sum_{i=1}^{Z_n} X_i$ の条件付き期待値を計算します。

$$ E[Z_{n+1} | Z_n] = Z_n \cdot m $$

全期待値をとると、

$$ \begin{equation} E[Z_{n+1}] = m \cdot E[Z_n] = m^{n+1} \cdot Z_0 \end{equation} $$

$Z_0 = 1$ のとき $E[Z_n] = m^n$ です。

分散

分散の再帰関係は条件付き分散の公式(全分散の法則)から得られます。

$$ \text{Var}(Z_{n+1}) = E[\text{Var}(Z_{n+1} | Z_n)] + \text{Var}(E[Z_{n+1} | Z_n]) $$

$Z_n$ が与えられたとき、$Z_{n+1}$ は $Z_n$ 個の独立な変数の和なので、

$$ \text{Var}(Z_{n+1} | Z_n) = Z_n \sigma^2, \quad E[Z_{n+1} | Z_n] = m Z_n $$

したがって、

$$ \text{Var}(Z_{n+1}) = \sigma^2 E[Z_n] + m^2 \text{Var}(Z_n) $$

$E[Z_n] = m^n$ を代入して再帰的に解くと、$m \neq 1$ のとき、

$$ \begin{equation} \text{Var}(Z_n) = \sigma^2 m^{n-1} \cdot \frac{m^n – 1}{m – 1} \end{equation} $$

$m = 1$ のときは $\text{Var}(Z_n) = n\sigma^2$ です。

超臨界($m > 1$)の場合、分散は $O(m^{2n})$ で増大し、標準偏差と期待値の比(変動係数)は $O(1)$ のオーダーに保たれます。劣臨界($m < 1$)の場合は期待値も分散もゼロに収束し、臨界($m = 1$)の場合は期待値は1に保たれるが分散は $n$ に比例して増大します。

これらの理論的結果をPythonシミュレーションで検証しましょう。

Pythonによるシミュレーションと検証

絶滅確率の数値計算と検証

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import brentq

np.random.seed(42)

# --- ポアソン分布の場合の母関数 G(s) = exp(m(s-1)) ---
def G_poisson(s, m):
    return np.exp(m * (s - 1))

# --- 絶滅確率の理論値(不動点方程式の解)---
def extinction_prob_theory(m):
    if m <= 1:
        return 1.0
    # G(q) = q, q < 1 の解
    f = lambda q: G_poisson(q, m) - q
    return brentq(f, 0, 1 - 1e-10)

# --- シミュレーション ---
m_values = np.linspace(0.5, 3.0, 30)
n_gen = 50
n_trials = 20000

ext_sim = []
ext_theory = []

for m in m_values:
    extinct_count = 0
    for _ in range(n_trials):
        Z = 1
        for gen in range(n_gen):
            if Z == 0:
                break
            Z = np.sum(np.random.poisson(m, Z))
            if Z > 50000:
                break
        if Z == 0:
            extinct_count += 1
    ext_sim.append(extinct_count / n_trials)
    ext_theory.append(extinction_prob_theory(m))

fig, axes = plt.subplots(1, 3, figsize=(16, 5))

# 左: 絶滅確率 vs m
ax = axes[0]
ax.plot(m_values, ext_sim, 'bo', markersize=4, alpha=0.7, label='Simulation')
ax.plot(m_values, ext_theory, 'r-', linewidth=2, label='Theory')
ax.axvline(1.0, color='gray', linestyle='--', linewidth=1, alpha=0.5,
           label='$m = 1$ (critical)')
ax.set_xlabel('Mean offspring $m$', fontsize=12)
ax.set_ylabel('Extinction probability $q$', fontsize=12)
ax.set_title('Extinction probability vs $m$', fontsize=13)
ax.legend(fontsize=9)
ax.grid(True, alpha=0.3)

# 中: 母関数と不動点の図示
ax = axes[1]
s_range = np.linspace(0, 1, 200)
for m_ex, color, ls in [(0.7, 'blue', '-'), (1.0, 'green', '-'), (1.5, 'red', '-'), (2.0, 'purple', '-')]:
    ax.plot(s_range, G_poisson(s_range, m_ex), color=color, linewidth=1.5,
            linestyle=ls, label=f'$G(s), m={m_ex}$')
ax.plot(s_range, s_range, 'k--', linewidth=1, label='$y = s$')
# 不動点をマーク
for m_ex, color in [(1.5, 'red'), (2.0, 'purple')]:
    q_ex = extinction_prob_theory(m_ex)
    ax.plot(q_ex, q_ex, 'o', color=color, markersize=8)
ax.set_xlabel('$s$', fontsize=12)
ax.set_ylabel('$G(s)$', fontsize=12)
ax.set_title('PGF and fixed points', fontsize=13)
ax.legend(fontsize=8)
ax.grid(True, alpha=0.3)
ax.set_xlim(0, 1)
ax.set_ylim(0, 1)

# 右: E[Z_n] の推移
ax = axes[2]
n_gen_plot = 15
for m_ex, color in [(0.7, 'blue'), (1.0, 'green'), (1.5, 'red'), (2.0, 'purple')]:
    # シミュレーション
    E_Z = []
    all_Z = np.ones(5000, dtype=int)
    for gen in range(n_gen_plot):
        E_Z.append(np.mean(all_Z[all_Z > 0]) if np.any(all_Z > 0) else 0)
        new_Z = np.zeros_like(all_Z)
        for i in range(len(all_Z)):
            if all_Z[i] > 0:
                new_Z[i] = np.sum(np.random.poisson(m_ex, min(all_Z[i], 1000)))
        all_Z = new_Z
    E_Z.append(np.mean(all_Z[all_Z > 0]) if np.any(all_Z > 0) else 0)
    # 理論
    gen_range = np.arange(n_gen_plot + 1)
    ax.plot(gen_range, [m_ex**n for n in gen_range], '--', color=color, linewidth=1, alpha=0.5)
    ax.plot(gen_range[:len(E_Z)], E_Z, 'o-', color=color, markersize=3, linewidth=1,
            label=f'$m={m_ex}$')

ax.set_xlabel('Generation $n$', fontsize=12)
ax.set_ylabel('$E[Z_n]$', fontsize=12)
ax.set_title('Expected population size', fontsize=13)
ax.set_yscale('log')
ax.legend(fontsize=9)
ax.grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig('branching_extinction.png', dpi=150, bbox_inches='tight')
plt.show()

このシミュレーション結果から、分岐過程の基本理論が正確に再現されていることが確認できます。

  1. 左図: 絶滅確率が $m = 1$ で相転移を起こしている。$m \leq 1$ では $q = 1$(確率1で絶滅)であり、$m > 1$ では $q < 1$ で $m$ の増加とともに減少しています。$m = 1$ 付近の急激な変化は、統計力学の相転移と同じ数学的構造です

  2. 中図: 母関数 $G(s)$ と直線 $y = s$ の交点が絶滅確率に対応している。$m \leq 1$ のとき交点は $s = 1$ のみ、$m > 1$ のとき $s < 1$ にもう一つの交点があり、それが絶滅確率 $q$ です

  3. 右図: 期待個体数 $E[Z_n] = m^n$ が理論通りに振る舞っている。超臨界($m > 1$)では指数的増大、劣臨界($m < 1$)では指数的減衰、臨界($m = 1$)では一定です

臨界分岐過程の特殊な性質

import numpy as np
import matplotlib.pyplot as plt

np.random.seed(789)

# --- 臨界分岐過程 (m=1) の詳細な分析 ---
sigma2 = 1.0  # 子孫数の分散 (幾何分布で m=1, p=0.5 の場合)

# 幾何分布: P(X=k) = (1/2)^{k+1}, m=1, sigma^2=2
# ここでは Poisson(1) を使用: m=1, sigma^2=1
m_crit = 1.0
n_gen = 200
n_trials = 100000

# 生存確率 P(Z_n > 0) の推移
survival_probs = []
for gen in range(n_gen):
    survival_probs.append(None)  # プレースホルダー

# 効率的なシミュレーション
alive = np.ones(n_trials, dtype=bool)
Z = np.ones(n_trials, dtype=int)
surv = []
mean_given_alive = []

for gen in range(n_gen):
    surv.append(np.mean(alive))
    if np.any(alive):
        mean_given_alive.append(np.mean(Z[alive]))
    else:
        mean_given_alive.append(0)
    # 次世代
    new_Z = np.zeros(n_trials, dtype=int)
    for i in range(n_trials):
        if alive[i]:
            new_Z[i] = np.sum(np.random.poisson(m_crit, min(Z[i], 5000)))
    Z = new_Z
    alive = Z > 0

fig, axes = plt.subplots(1, 3, figsize=(16, 5))

# 左: 生存確率
ax = axes[0]
gen_range = np.arange(1, len(surv) + 1)
ax.plot(gen_range, surv, 'b-', linewidth=1.5, label='Simulation')
ax.plot(gen_range, 2 / (gen_range * sigma2 + 2), 'r--', linewidth=1.5,
        label=r'$\sim 2/(n\sigma^2)$')
ax.set_xlabel('Generation $n$', fontsize=12)
ax.set_ylabel('$P(Z_n > 0)$', fontsize=12)
ax.set_title('Survival probability (critical, $m=1$)', fontsize=13)
ax.set_xscale('log')
ax.set_yscale('log')
ax.legend(fontsize=10)
ax.grid(True, alpha=0.3)

# 中: 条件付き期待値
ax = axes[1]
valid = [i for i in range(len(mean_given_alive)) if mean_given_alive[i] > 0]
ax.plot([i+1 for i in valid], [mean_given_alive[i] for i in valid],
        'b-', linewidth=1.5, label='Simulation')
ax.plot(gen_range, gen_range * sigma2 / 2, 'r--', linewidth=1.5,
        label=r'$\sim n\sigma^2/2$')
ax.set_xlabel('Generation $n$', fontsize=12)
ax.set_ylabel('$E[Z_n | Z_n > 0]$', fontsize=12)
ax.set_title('Conditional mean (critical)', fontsize=13)
ax.legend(fontsize=10)
ax.grid(True, alpha=0.3)

# 右: サンプルパス
ax = axes[2]
for _ in range(30):
    Z_path = [1]
    z = 1
    for gen in range(100):
        z = np.sum(np.random.poisson(m_crit, min(z, 5000)))
        Z_path.append(z)
        if z == 0:
            break
    ax.plot(range(len(Z_path)), Z_path, linewidth=0.5, alpha=0.5)

ax.set_xlabel('Generation $n$', fontsize=12)
ax.set_ylabel('$Z_n$', fontsize=12)
ax.set_title('Sample paths (critical)', fontsize=13)
ax.grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig('branching_critical.png', dpi=150, bbox_inches='tight')
plt.show()

臨界分岐過程の結果から、以下の特殊な性質が確認できます。

  1. 左図: 生存確率 $P(Z_n > 0)$ が $2/(n\sigma^2)$ に漸近的に一致している。両対数プロットで傾き $-1$ の直線に乗っており、$P(Z_n > 0) \sim 2/(n\sigma^2)$ という理論的予測が正確に再現されています

  2. 中図: 条件付き期待値 $E[Z_n | Z_n > 0]$ が $n$ に比例して増大している。生き残った集団の平均サイズが $n\sigma^2/2$ に漸近しており、「生存確率は下がるが、生き残った場合の集団サイズは増大する」という臨界分岐過程の特徴が明瞭に見えます

  3. 右図: サンプルパスのほとんどが早期に絶滅するが、一部は大きな個体数に到達してから絶滅する。臨界分岐過程は「いつかは必ず絶滅する」が、絶滅までの時間は非常に長くなることがあります

具体的な子孫数分布での絶滅確率

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import brentq

np.random.seed(42)

# --- 二項分布 B(n, p) の場合 ---
# G(s) = (1 - p + ps)^n, m = np

def G_binomial(s, n_binom, p_binom):
    return (1 - p_binom + p_binom * s)**n_binom

def ext_prob_binomial(n_binom, p_binom):
    m = n_binom * p_binom
    if m <= 1:
        return 1.0
    f = lambda q: G_binomial(q, n_binom, p_binom) - q
    return brentq(f, 0, 1 - 1e-10)

# 子の数: 0 or 2 (各確率 1/2) → m = 1, q = 1
# 子の数: 0, 1, 2, 3 (各確率 p0, p1, p2, p3)

# カスタム分布: 具体的な例を計算
print("=== 具体的な絶滅確率の計算 ===")
print()

# 例1: P(X=0) = 0.3, P(X=1) = 0.3, P(X=2) = 0.4
# m = 0*0.3 + 1*0.3 + 2*0.4 = 1.1
p_dist1 = {0: 0.3, 1: 0.3, 2: 0.4}
m1 = sum(k*v for k, v in p_dist1.items())
G1 = lambda s: sum(v * s**k for k, v in p_dist1.items())
if m1 > 1:
    q1 = brentq(lambda q: G1(q) - q, 0, 1 - 1e-10)
else:
    q1 = 1.0

# シミュレーション検証
n_trials_check = 50000
n_gen_check = 100
ext_count1 = 0
for _ in range(n_trials_check):
    Z = 1
    for gen in range(n_gen_check):
        if Z == 0:
            break
        Z = sum(np.random.choice(list(p_dist1.keys()), p=list(p_dist1.values()))
                for _ in range(min(Z, 10000)))
    if Z == 0:
        ext_count1 += 1

print(f"Distribution 1: p = {p_dist1}")
print(f"  m = {m1:.2f}")
print(f"  Extinction prob (theory): {q1:.6f}")
print(f"  Extinction prob (sim):    {ext_count1/n_trials_check:.6f}")
print()

# 複数の分布の比較プロット
fig, axes = plt.subplots(1, 2, figsize=(13, 5.5))

# 左: ポアソン分布 vs 二項分布 vs 幾何分布
ax = axes[0]

m_range = np.linspace(1.01, 3.0, 100)

# ポアソン
q_poisson = [extinction_prob_theory(m) for m in m_range]

# 二項 B(4, p) with m = 4p
q_binom = []
for m in m_range:
    p_b = m / 4
    if p_b > 1:
        q_binom.append(np.nan)
    else:
        q_binom.append(ext_prob_binomial(4, p_b))

# 幾何分布: P(X=k) = (1-p)^k * p, G(s) = p/(1-(1-p)s), m = (1-p)/p
q_geom = []
for m in m_range:
    p_g = 1 / (1 + m)  # m = (1-p)/p → p = 1/(1+m)
    G_g = lambda s, pg=p_g: pg / (1 - (1 - pg) * s)
    try:
        q_val = brentq(lambda q, pg=p_g: G_g(q, pg) - q, 0, 1 - 1e-10)
    except:
        q_val = 1.0
    q_geom.append(q_val)

ax.plot(m_range, q_poisson, 'b-', linewidth=2, label='Poisson')
ax.plot(m_range, q_binom, 'r--', linewidth=2, label='Binomial(4, m/4)')
ax.plot(m_range, q_geom, 'g-.', linewidth=2, label='Geometric')
ax.set_xlabel('Mean offspring $m$', fontsize=12)
ax.set_ylabel('Extinction probability $q$', fontsize=12)
ax.set_title('Extinction prob. for different distributions', fontsize=13)
ax.legend(fontsize=10)
ax.grid(True, alpha=0.3)

# 右: 再帰列 q_n = G(q_{n-1}) の収束
ax = axes[1]
for m_ex, color in [(1.5, 'blue'), (2.0, 'red'), (2.5, 'green')]:
    q_n = [0]
    for _ in range(50):
        q_n.append(G_poisson(q_n[-1], m_ex))
    q_true = extinction_prob_theory(m_ex)
    ax.plot(range(len(q_n)), q_n, '-', color=color, linewidth=1.5,
            label=f'$m={m_ex}$, $q={q_true:.3f}$')
    ax.axhline(q_true, color=color, linestyle=':', linewidth=1, alpha=0.5)

ax.set_xlabel('Iteration $n$', fontsize=12)
ax.set_ylabel('$q_n = G^{(n)}(0)$', fontsize=12)
ax.set_title('Convergence of $q_n$ to extinction probability', fontsize=13)
ax.legend(fontsize=10)
ax.grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig('branching_distributions.png', dpi=150, bbox_inches='tight')
plt.show()

この結果から、以下の重要な点が確認できます。

  1. 左図: 絶滅確率は子孫数分布の種類に依存する。同じ平均 $m$ でも、分散の大きい分布(幾何分布)ほど絶滅確率が高くなります。これは、分散が大きいと「子孫ゼロ」の確率 $p_0$ が高くなるためです

  2. 右図: 再帰列 $q_n = G^{(n)}(0)$ が絶滅確率に単調に収束している。$m$ が大きいほど収束が速く(不動点が $s = 0$ に近いため)、$m$ が1に近いほど収束が遅くなります

分岐過程の応用

核分裂連鎖反応

分岐過程の歴史的に最も重要な応用は、核分裂連鎖反応のモデル化です。1942年のマンハッタン計画において、核分裂の連鎖反応が維持されるかどうかの分析に分岐過程が使われました。

中性子が原子核に衝突すると核分裂が起こり、平均 $m$ 個の新たな中性子が放出されます。各世代の中性子が次世代を生成する過程はガルトン・ワトソンの分岐過程そのものです。

  • $m < 1$(未臨界): 連鎖反応は自然に停止する。原子炉の安全な状態
  • $m = 1$(臨界): 連鎖反応がちょうど維持される。原子炉の定常運転
  • $m > 1$(超臨界): 連鎖反応が指数的に増大する。核爆弾の原理

原子炉の制御棒は $m$ を正確に1に保つことで、安定した連鎖反応を維持します。

感染症の伝播

感染症の拡散は分岐過程の枠組みで自然にモデル化できます。基本再生産数 $R_0$(1人の感染者が生み出す二次感染者の平均数)が分岐過程の $m$ に対応します。

  • $R_0 < 1$: 感染は自然に収束する(風土病にならない)
  • $R_0 > 1$: 感染が爆発的に広がる可能性がある(パンデミックの条件)

COVID-19の初期の $R_0$ は2-3と推定され、これは「超臨界」な分岐過程に対応します。ワクチンや行動制限によって実効再生産数 $R_t$ を1未満に下げることが感染制御の本質です。

分岐過程の絶滅確率の理論は、感染の最終的な規模(final size)の予測にも使われます。$R_0 = 2$ のとき絶滅確率 $q \approx 0.203$ であり、逆に $1 – q \approx 0.797$ が大規模流行(エピデミック)の発生確率に対応します。

系図学と姓の消滅

分岐過程はもともとガルトン(Francis Galton)とワトソン(Henry William Watson)が1874年に英国の貴族の姓が世代を経て消滅していく現象を説明するために導入したものです。

各世代で男子の数が $\{p_k\}$ に従う分岐過程を考えると、姓は男系でのみ継承されるため、集団の絶滅は姓の消滅に対応します。たとえ $m > 1$ であっても $q > 0$(正の確率で絶滅する)ことが理論的に示され、多くの姓が歴史的に消滅した現象を説明できます。

多型分岐過程への拡張

実際の応用では、個体が複数の「型」を持つ場合があります。多型分岐過程(multitype branching process)は、$d$ 型の個体が各型の子孫を異なる分布で生成するモデルです。

各世代の型ごとの個体数を $\bm{Z}_n = (Z_n^{(1)}, \dots, Z_n^{(d)})$ とすると、平均行列 $\bm{M}$($M_{ij} = E[\text{型 } i \text{ の子孫数} | \text{親が型 } j]$)の最大固有値(ペロン・フロベニウス固有値)$\rho$ が臨界性を決定します。

  • $\rho < 1$: 劣臨界(絶滅する)
  • $\rho = 1$: 臨界
  • $\rho > 1$: 超臨界(正の確率で生存)

この拡張は、突然変異を含む進化モデル、異なるタイプの細胞の増殖、通信ネットワークの信号伝播など、多くの応用で使われます。

まとめ

本記事では、ガルトン・ワトソンの分岐過程の基本理論とその応用について解説しました。

  • ガルトン・ワトソン過程: 各個体が独立に $\{p_k\}$ に従う数の子を残す集団の増殖モデルです。$Z_{n+1} = \sum_{i=1}^{Z_n} X_i$ で再帰的に定義されます
  • 絶滅確率: 母関数の不動点方程式 $G(q) = q$ の最小非負解として求まります。$m \leq 1$ なら $q = 1$(確率1で絶滅)、$m > 1$ なら $q < 1$(正の確率で生存)です。この結果は母関数の凸性と不動点定理から導かれます
  • 臨界性の分類: 劣臨界($m < 1$)、臨界($m = 1$)、超臨界($m > 1$)で振る舞いが質的に異なります。臨界の場合は確率1で絶滅しますが、条件付き生存集団のサイズは $n$ に比例して成長するという特殊な性質を持ちます
  • 正規化マルチンゲール: $W_n = Z_n/m^n$ は非負マルチンゲールであり、マルチンゲール収束定理により $W_\infty$ にほぼ確実に収束します
  • 応用: 核分裂連鎖反応の臨界制御、感染症の基本再生産数 $R_0$ による伝播予測、系図学における姓の消滅など、分岐過程は多岐にわたる現象のモデル化に使われます
  • 多型分岐過程: 複数型の個体を持つ拡張では、平均行列のペロン・フロベニウス固有値が臨界性を決定し、多様な応用に対応します

次のステップとして、以下の記事も参考にしてください。