May-Leonard Competition Model
Overview
The May-Leonard competition model is a population dynamics model in the state of competition involving three groups, depicting a triangular relationship where each group preys on and is preyed on by the others. These three parties could be political parties, companies, or actual competing species with natural advantages and disadvantages.
Model1
$$ \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*} $$
Variables
- $x_{1}(t)$: represents the population of group $x_{1}$ at time $t$.
- $x_{2}(t)$: represents the population of group $x_{2}$ at time $t$.
- $x_{3}(t)$: represents the population of group $x_{3}$ at time $t$.
Parameters
- $0<a<1$: the competitive coefficient from the relatively advantageous group.
- $b>1$: the competitive coefficient from the relatively disadvantageous group.
Explanation
The May-Leonard model is a $3$-dimensional system with only two parameters, focusing solely on the competition among the three groups. All actual population-related parameters are normalized by being abstracted away. The values on the axes of $x_{1}$, $x_{2}$, and $x_{3}$ are confined within $[0,1]$.
The term “May-Leonard competition model” is not frequently used since there’s a more general form, the Lotka-Volterra competition model. However, for a simplistic representation of just three species with relatively straightforward parameter setting, the May-Leonard model may be more mathematically appealing.
In reality, tripartite oppositions can be observed in examples such as:
- Pokémon: Historically, the starting Pokémon in the numbered series have been of three types: Grass, Fire, Water. Despite factors like the Grass-type’s defensive system being the weakest or evolution changing the type advantage, their inherent type advantage relationship of consuming and being consumed has remained unchanged.
- Side-blotched lizard: Male side-blotched lizards, despite being of the same species, are divided into three types based on the color of the throat fan (referred to as a “collar”) which determines their mating strategy. 2 3
- Orange, ultra-dominant: Largest and most aggressive, with a wide home range containing many females. Capable of stealing mates from blue-collared lizards but vulnerable to the sneak tactics of yellow-collared lizards.
- Blue, dominant: Medium size, less aggressive, with a smaller home range and monogamous pairing. Good at detecting yellow-collared lizards’ sneak mating attempts but susceptible to mate theft by orange-collared lizards regardless.
- Yellow, sneaker: Lacks a territory but roams the widest area. Mimics the appearance of a mature female to sneak into other males’ territories for clandestine mating.
Derivation
$$ \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*} $$
The derivation is straightforward, being an extension of the Lotka-Volterra competition model with the addition of one group and setting the intrinsic growth rates and the carrying capacity to 1.
■
Generalization
- The generalization of the Lotka-Volterra competition model for $n$ groups can be represented as follows for $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) $$
Simulation
Let’s simulate a Rock-Paper-Scissors (RPS) game in a grid model. Each color represents the following elements, and color matching follows the common in-game pattern of Fire<Water<Grass with a pastel tone rather than the RGB sequence:
- Red - Rock
- Blue - Paper
- Green - Scissors
The gif above shows the competition among the three groups in a 20x20 grid space. Notably, the dominant group keeps changing: green seems to thrive first, but as the blue population decreases, the red population, having lost its predator, gains dominance. However, due to the limited space, chance plays a significant role, and green eventually finds an opportunity for a breakthrough.
Increasing the resolution and fps, one can observe fierce battles occurring at various points, with an overall balance being maintained throughout the simulation.
Code
Below is the complete code implemented in 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
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 ↩︎