메이-레너드 경쟁 모델
개요
메이-레너드 경쟁 모델은 세 가지 집단이 포함된 경쟁 상태에서의 인구 동역학 모델로, 세 집단이 서로 먹고 먹히는 삼각 관계를 묘사한다. 세 개의 당이나 기업, 혹은 실제로 상성이 있는 경쟁이 될 수도 있다.
모델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
- 주황색, 극우성: 몸집이 가장 크고 공격적이며, 넓은 생활 반경을 가지고 많은 암컷들을 거느린다. 남색 목도리들의 짝을 빼앗는데 능하지만 샛노란 목도리들의 위장에 취약하다.
- 남색, 우성: 중간 사이즈에 덜 공격적이고 더 작은 생활 반경에 하나의 짝과 함께한다. 하나의 짝만 있을 땐 샛노란 목도리의 위장을 잘 간파하지만 그와 상관없이 주황 목도리에게 짝을 빼앗길 수 있다.
- 샛노란색, 좀도둑: 딱히 영역을 가지지 않는 대신 다른 도마뱀의 생활 반경을 포함해 가장 넓은 영역을 돌아다닌다. 성숙한 암컷과 비슷하게 생긴 덕에 다른 종류의 수컷들에게 들키지 않고 숨어 들어가 몰래 교미를 한다.
유도
$$ \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) $$
시뮬레이션
가위바위보rPS, Rock-Paper-Scissors 게임을 격자 모델로 시뮬레이션 해보자. 각 색상은 다음과 같은 패를 나타낸다. 컬러 매칭은 RGB 순으로 나타내는 것보다는 요즘 게임에서 많이 사용하는 불<물<풀 상성에 맞추고 파스텔 톤을 주었다:
- 적색 - Rock
- 청색 - Paper
- 녹색 - Scissors
위의 움짤은 20x20 격자 공간에서 세 집단의 경쟁을 보여준다. 잘 보면 공간 대부분을 차지하는 대세가 계속 바뀌는 것으로 보이는데, 가장 먼저 녹색이 흥하는 듯하다가 청색이 너무 적어지자 천적이 적어진 적색이 득세하는 등 우리가 예상한 대로의 추세를 보여준다. 그러나 공간이 너무 좁기 때문에 운이 너무 많이 작용하고, 녹색이 기회를 잡고 천통에 성공하고 만다.
해상도와 fps를 올려서 보면 위에서 보았던 격전이 곳곳에서 일어나며 전체적인 균형이 유지되는 것을 볼 수 있다.
코드
다음은 줄리아로 구현된 전체 코드다.
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
Allen. (2006). An Introduction to Mathematical Biology: p251. ↩︎
Barry Sinervo. (1996). The rock-paper-scissors game and the evolution of alternative male strategies ↩︎
https://en.wikipedia.org/wiki/Common_side-blotched_lizard ↩︎