Skip to content

Ecology simulator

Predator-Prey

The classic Lotka-Volterra oscillation, integrated by 4th-order Runge-Kutta. More prey feeds more predators; more predators crash the prey; the crashed prey starve the predators - and the cycle repeats, forever, with no fixed point.

How to read it: the prey curve (green) spikes first, then the predator curve (orange) chases it up a beat later. That phase lag is the cycle. The conserved quantity V drifts by only ~1e-9, proving RK4 tracked the true orbit.

Physics sanity check

Conserved quantity V = d*N - g*ln(N) + b*P - a*ln(P):

V(initial) at N=10.0000, P=5.0000
-3.8133155519
V(final) at N=15.0213, P=3.3588
-3.8133155509
drift over 50 time units
1.016752e-09

A drift near zero confirms RK4 stayed on the true closed orbit for the whole run.

One full cycle - populations at t = 0..12

tprey Npred PN (green) / P (orange)
010.0005.000
118.6353.109
235.3145.061
331.84619.704
410.07917.701
58.2937.419
613.5123.602
726.5783.414
840.56210.532
916.75022.885
108.00711.416
1110.2084.852
1219.1643.098

Prey peaks at t=8 (~40.6); the predator peak trails at t=9 (~22.9). Bars share one scale so the amplitude gap and the lag both read at a glance.

Raw program output (sampled every t=1, 5001 points)

Lotka-Volterra predator-prey simulation - OnlyCSharp.Biology.Ecology
======================================================================
prey0=10  pred0=5  alpha=1  beta=0.1  gamma=1.5  delta=0.075  tEnd=50  stepSize=0.01

Physics sanity check (conserved quantity V = delta*N - gamma*ln(N) + beta*P - alpha*ln(P)):
  V(initial) = V(N= 10.0000, P=  5.0000) = -3.8133155519
  V(final)   = V(N= 15.0213, P=  3.3588) = -3.8133155509
  difference = 1.016752E-009  (should be ~0 - confirms RK4 tracked the true orbit)

Sampled every 100th point (5001 total points, step=0.01):
  # = prey population   * = predator population   (1 char per unit, capped at 60)

t=  0.00  prey=  10.000  ##########
t=  0.00  pred=   5.000  *****

t=  1.00  prey=  18.635  ###################
t=  1.00  pred=   3.109  ***

t=  2.00  prey=  35.314  ###################################
t=  2.00  pred=   5.061  *****

t=  3.00  prey=  31.846  ################################
t=  3.00  pred=  19.704  ********************

t=  4.00  prey=  10.079  ##########
t=  4.00  pred=  17.701  ******************

t=  5.00  prey=   8.293  ########
t=  5.00  pred=   7.419  *******

t=  6.00  prey=  13.512  ##############
t=  6.00  pred=   3.602  ****

t=  7.00  prey=  26.578  ###########################
t=  7.00  pred=   3.414  ***

t=  8.00  prey=  40.562  #########################################
t=  8.00  pred=  10.532  ***********

t=  9.00  prey=  16.750  #################
t=  9.00  pred=  22.885  ***********************

t= 10.00  prey=   8.007  ########
t= 10.00  pred=  11.416  ***********

t= 20.00  prey=  15.905  ################
t= 20.00  pred=  22.631  ***********************

t= 30.00  prey=  40.164  ########################################
t= 30.00  pred=  11.924  ************

t= 40.00  prey=  28.755  #############################
t= 40.00  pred=   3.661  ****

t= 50.00  prey=  15.021  ###############
t= 50.00  pred=   3.359  ***

Done - look for prey bars (#) rising and falling, with predator bars (*) tracking
the same rhythm a little later: that lag is the predator-prey cycle.