logo

Logistic Growth Model: The Limits of Population Growth 📂Dynamics

Logistic Growth Model: The Limits of Population Growth

Model

$$ \dot{N} = {{ r } \over { K }} N ( K - N) $$

Variables

  • $N(t)$: Represents the population size of a group at time $t$.

Parameters

  • $r \in \mathbb{R}$ : Intrinsic Rate of Increase, growth occurs if it is greater than $0$, and decline occurs if it is less than $0$. It can also be defined by the difference $r:=b-d$ between the Birth Rate $b$ and Death Rate $d$.
  • $K$: Carrying Capacity, describes the size of the environment that can support the population.

Description

This differential equation is also known as the Logistic Equation or Verhulst’s Equation.

The logistic growth model was designed to improve on the Malthusian growth model, which only predicts unrealistic perpetual increase in population. The more significant the population, the more it penalizes population growth, akin to adding a sort of Malthusian Trap to the equation. If the population size $N$ exceeds the carrying capacity $K$, then $(K-N) < 0$, resulting in a negative change $n '$ in population size, meaning the population will decrease. This idea is not merely speculative; let’s directly examine the derivation to understand how such a penalty works.

Derivation

Malthusian Growth Model: $$ \dot{N} = r N $$

In such a simple model, the average growth rate per individual can be obtained by dividing both sides by $N$. Since the growth rate in the exponential growth model is constant regardless of how large the population grows, it remains a constant like this:

$$ {{ \dot{N} } \over { N }} = r $$

Now, let’s modify the RHS. We want the growth rate to decrease as the population increases, but there’s no clear consensus on how exactly it should decrease, so let’s assume it decreases linearly for simplicity. That means the individual growth rate will be depicted by a straight line, not a constant function.

20201206_192422.png

As shown in the figure, modifying the RHS so that the equation of the line with the y-intercept of $K$ and the $N’/N$ intercept of $r$ results in

$$ {{ \dot{N} } \over { N }} = {{ r } \over { K }} ( K - N) $$

Multiplying both sides by $N$ gives us

$$ \dot{N} = {{ r } \over { K }} N ( K - N) $$

Fixed Points

The logistic growth model has two fixed points, $N=0, N=K$, with $N=K$ being Lyapunov stable1.

Visual Understanding

Let’s visually understand the logistic growth model through a grid-based simulation.

Actions

(In every cell, each turn)

  • Calculation: Count how many elements there are in the up, down, left, right of each cell. Let the number calculated in the $i$ row $j$ column be $n_{ij}$.
  • Diffusion: Each cell has a probability of $1-(1-\beta)^{n_{ij}}$ to contain an element.

Using only the simple action of diffusion in a grid space, one can see natural limits to growth due to the grid space being finite.

logistic_growth_lattice.gif

Here is the comparison with the theoretical growth trend.

logistic_growth_time_evolution.gif

As seen, the simulation does not match the theory exactly; it tends to grow linearly rather than curving, with initial growth too steep. However, it’s essential to notice the inflection point where it starts to fill the environmental capacity. If we compare this to real life, it can be like bacteria growing in a petri dish. Even if they want to keep growing, they can’t grow indefinitely beyond the confines of the dish.

The reason for the discrepancy between theory and simulation is that the simulation isn’t sophisticated enough, and the model is too simple. Perhaps it was just bad luck in the simulation, but the impact of the grid cannot be ignored. However, in this case, it’s not merely about luck.

gompertz.png

In fact, when comparing theoretical trends, this visualization appears closer to the Gompertz growth model. Considering tumor growth in grid space, the ratio of volume to surface area appears smaller, and although cell numbers increase, the cells actually capable of increasing the size of the tumor gradually diminish.

Code

Here is the Julia code to create the GIFs.

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

@time using Plots
@time using Random
@time using DifferentialEquations

row_size = 20
column_size = 20
β = 0.1 # 번식률
γ = 0.1 # 사망률

#---
K = row_size*column_size

function logistic_growth!(du,u,p,t)
  N = u[1]
  r = p
  du[1] = dN = r/K*N*(K-N)
end

u0 = [1.0]
p = 0.8

tspan = (0.,18)
prob = ODEProblem(logistic_growth!,u0,tspan,p)
sol = solve(prob; saveat=(0.0:0.1:18))

compare = plot(sol,vars=(0,1),
  linestyle = :dash,  color = :black,
  size = (400,300), label = "Theoretical", legend=:topleft)


#---
max_iteration = 180

Random.seed!(0);
time_evolution = Int64[]

stage_lattice = zeros(Int64, row_size, column_size)
stage_lattice[rand(1:row_size), rand(1:column_size)] = 1

let colormap_SI = cgrad([colorant"#EEEEEE", colorant"#111111"])
  anim1 = @animate for t = (0:max_iteration)/10
    heatmap(reverse(stage_lattice,dims=1), color=colormap_SI,
      xaxis=false,yaxis=false,axis=nothing, size = [400,400], legend = false)

    I_lattice = (stage_lattice .== 1)
    count_lattice =
      vcat(I_lattice[2:end, :], zeros(Int64, 1, column_size)) +
      vcat(zeros(Int64, 1, column_size), I_lattice[1:end-1, :]) +
      hcat(I_lattice[:, 2:end], zeros(Int64, row_size, 1)) +
      hcat(zeros(Int64, column_size, 1), I_lattice[:, 1:end-1])
    probability_lattice = 1 .- (1-β).^count_lattice
    hit_lattice = probability_lattice .> rand(row_size, column_size)
    stage_lattice[hit_lattice] .= 1
    if sum(stage_lattice) ≥ row_size*column_size
      colormap_SI = cgrad([colorant"#111111", colorant"#EEEEEE"])
    end

    push!(time_evolution, sum(stage_lattice))
  end; gif(anim1, "logistic_growth_lattice.gif", fps = 12)
end

anim2 = @animate for t = 1:max_iteration
  compare = plot(sol,vars=(0,1),
    linestyle = :dash,  color = :black,
    label = "Theoretical", legend=:bottomright)
  plot!(compare, 0.1:0.1:(t/10), time_evolution[1:t],
    color = colorant"#111111", linewidth = 2, label = "Simulation",
    size = [400, 300])
end; gif(anim2, "logistic_growth_time_evolution.gif", fps = 12)

  1. From the diagrams used in the derivation, we can see that to the left of the fixed point, the population increases and moves to the right, while to the right, it decreases, moving to the left. ↩︎