logo

メイ-レナード競争モデル 📂動力学

メイ-レナード競争モデル

概要

メイ-レナード競争モデルは、3つのグループが含まれる競争状態における個体群動態モデルであり、各グループが互いに食べるという三角関係を描写している。これら3つのパーティは、政党や企業、または実際に相性のある競争となることもある。

モデル1

$$ \begin{align*} \dot{x_{1}} =& x_{1} \left( 1 - x_{1} - b x_{2} - a x_{3} \right) \\ \dot{x_{2}} =& x_{2} \left( 1 - a x_{1} - x_{2} - b x_{3} \right) \\ \dot{x_{3}} =& x_{3} \left( 1 - b x_{1} - a x_{2} - x_{3} \right) \end{align*} $$

変数

  • $x_{1}(t)$: 時点$t$におけるグループ$x_{1}$の個体数を表す。
  • $x_{2}(t)$: 時点$t$におけるグループ$x_{2}$の個体数を表す。
  • $x_{3}(t)$: 時点$t$におけるグループ$x_{3}$の個体数を表す。

パラメータ

  • $0<a<1$: 相対的に有利なグループから受ける競争係数。
  • $b>1$: 相対的に不利なグループから受ける競争係数。

説明

メイ-レナードモデルは$3$次元のシステムとして、パラメータが二つしかないが、これは三つのグループ間の競争のみに焦点を当て、実際の個体群に関連するパラメータはすべて抽象化して正規化したためである。$x_{1}$、$x_{2}$、$x_{3}$の各軸上の値は$[0,1]$を超えることはない。

実際、「メイ-レナード競争モデル」という用語はあまり頻繁に使われるわけではない。それは、より一般的な形であるロトカ-ボルテラ競争モデルが存在するためだ。ただし、精密な生態系の描写ではなく、わずかに三つの種を扱い、パラメータ設定が非常にシンプルなメイ-レナードモデルの方が数学的に魅力的である可能性がある。

現実世界でこのような$3$者対立関係が見られる例としては、次のようなものが考えられる:

  • ポケモン: 歴史的に、ナンバリングシリーズでスターティングポケモンは草、火、水の三つのタイプが選ばれていた。草タイプの防御システムが最も弱かったり、進化によって逆相性になったりすることは置いておくとしても、これら三者の相性そのものが食べる関係であることに変わりはなかった。 ポケモン
  • ウタヒメドリトカゲuta stansburiana: オスのウタヒメドリトカゲは同じ種でありながら、首の飾り(以下「首飾り」と呼ぶ)の色によって三つのタイプに分かれ、それぞれ異なる繁殖戦略をとる。2 3 uta_lizard.png
    • オレンジ色、極支配型: 体が最も大きく攻撃的で、多くのメスを持つ広い生息範囲を持つ。青い首飾りの個体からメスを奪うことが得意だが、黄色い首飾りの個体の潜伏戦術には弱い。
    • 青色、支配型: 中間サイズで、攻撃性が少なく、より小さい生息範囲で一つのメスとペアを作る。一つのメスがいる場合、黄色い首飾りの個体の潜伏試みをよく見破るが、それでもオレンジの首飾りの個体にメスを奪われることがある。
    • 黄色、こそ泥タイプ: 特定の領域を持たず、最も広い範囲を移動する。成熟したメスに似た外見を利用して、他のタイプのオスの領域に潜入し、発見されずに密かな交配を行う。

導出

$$ \begin{align*} \dot{x_{1}} =& r_{1} x_{1} {{ K_{1} - x_{1} - \beta_{12} x_{2} } \over { K_{1} }} \\ \dot{x_{2}} =& r_{2} x_{2} {{ K_{2} - x_{2} - \beta_{21} x_{1} } \over { K_{2} }} \end{align*} $$

導出は単純で、グループを一つ追加し、固有の成長率と環境収容力を1に設定することにより、ロトカ-ボルテラ競争モデルを拡張したものである。

一般化

  • $n$個のグループに対するロトカ-ボルテラ競争モデルの一般化は、$i = 1 , \cdots , n$に対して、次のように表現できる。 $$ { { d x_{i} } \over { d x_{t} } } = x_{i} \left( a_{i0} - \sum_{j=1}^{n} a_{ij} x_{j} \right) $$

シミュレーション

じゃんけん(ロック・ペーパー・シザーズ)ゲームを格子モデルでシミュレーションしてみよう。各色は以下の要素を表し、カラーマッチングはRGB順ではなく、現代のゲームでよく使われる火<水<草の相性に合わせ、パステル調の調色を採用している:

  • 赤色 - Rock
  • 青色 - Paper
  • 緑色 - Scissors

RPS_game_20

上のGIFは、20x20の格子空間での3つのグループの競争を示している。初めは緑色が優勢に見えるが、青色の個体数が減少すると、捕食者が少なくなった赤色が優勢になるなど、予想通りのトレンドが見られる。しかし、空間が狭すぎるため、運が大きく影響し、緑色がチャンスをつかみ、突破に成功してしまう。

RPS_game_100

解像度とfpsを上げて見ると、激戦が各地で起こり、全体的なバランスが保たれていることがわかる。

コード

以下はJuliaで実装された完全なコードである。

cd(@__DIR__) # 파일 저장 경로

@time using Plots
@time using Random

# 0:W: Empty
# 1:R:R: Rock
# 2:B:P: Paper
# 3:G:S: scissors
colormap_RPS = [colorant"#FFFFFF", colorant"#FFCCCC", colorant"#99CCFF", colorant"#CCFFCC"]
row_size = 20
column_size = 20
p = 3/4
Random.seed!(0);

stage_lattice = zeros(Int64, row_size, column_size)
stage_lattice[rand(2:(row_size-1)), rand(2:(column_size-1))] = 1; stage_lattice
stage_lattice[rand(2:(row_size-1)), rand(2:(column_size-1))] = 2; stage_lattice
stage_lattice[rand(2:(row_size-1)), rand(2:(column_size-1))] = 3; stage_lattice
figure = heatmap(reverse(stage_lattice,dims=1), color=colormap_RPS,
  xaxis=false,yaxis=false,axis=nothing, size = [400,400], legend = false)
png(figure, "08-01.png")

function duel(A::Int, B::Int; p=0.5)
  if A > B
    A, B = B, A
  end

  if A == 0 || A == B
    return B
  elseif A == 1 && B == 3
    if rand() < p
      return 1
    else
      return 3
    end
  elseif rand() < p
    return B
  else
    return A
  end
end

stage_duel = copy(stage_lattice)
for i in 2:(row_size-1)
  for j in 2:(row_size-1)
    I = i + rand([-1,0,1])
    J = j + rand([-1,0,1])
    A = stage_lattice[I, J]

    I = i + rand([-1,0,1])
    J = j + rand([-1,0,1])
    B = stage_lattice[I, J] #중복 허용
    if A != 0 || B != 0
      stage_duel[i,j] = duel(A, B, p=1)
    end
  end
end
stage_lattice = stage_duel
figure = heatmap(reverse(stage_lattice,dims=1), color=colormap_RPS,
  xaxis=false,yaxis=false,axis=nothing, size = [400,400], legend = false)
png(figure, "08-02.png")

let
  Random.seed!(0);
  row_size = 20
  column_size = 20

  stage_lattice = zeros(Int64, row_size, column_size)
  stage_lattice[rand(2:(row_size-1)), rand(2:(column_size-1))] = 1; stage_lattice
  stage_lattice[rand(2:(row_size-1)), rand(2:(column_size-1))] = 2; stage_lattice
  stage_lattice[rand(2:(row_size-1)), rand(2:(column_size-1))] = 3; stage_lattice
  figure = heatmap(reverse(stage_lattice,dims=1), color=colormap_RPS,
    xaxis=false,yaxis=false,axis=nothing, size = [400,400], legend = false)

  anim = @animate for t = 1:400
    stage_duel = copy(stage_lattice)
    for i in 2:(row_size-1)
      for j in 2:(row_size-1)
        I = i + rand([-1,0,1])
        J = j + rand([-1,0,1])
        A = stage_lattice[I, J]
    
        I = i + rand([-1,0,1])
        J = j + rand([-1,0,1])
        B = stage_lattice[I, J] #중복 허용
        if A != 0 || B != 0
          stage_duel[i,j] = duel(A, B, p=1)
        end
      end
    end
    stage_lattice = stage_duel
    figure = heatmap(reverse(stage_lattice,dims=1), color=colormap_RPS,
      xaxis=false,yaxis=false,axis=nothing, size = [400,400], legend = false)
    end
  gif(anim, "RPS_game_20.gif", fps = 4)
end

  1. Allen. (2006). An Introduction to Mathematical Biology: p251. ↩︎

  2. Barry Sinervo. (1996). The rock-paper-scissors game and the evolution of alternative male strategies ↩︎

  3. https://en.wikipedia.org/wiki/Common_side-blotched_lizard ↩︎