[Tutor] Lotka-Volterra Model Simulation Questions

Alan Gauld alan.gauld at btinternet.com
Sat Sep 29 03:23:38 CEST 2012

On 28/09/12 21:32, Jim Apto wrote:

> I'm relatively new to python, and was asked to program a lotka-volterra
> model (predator and prey relation) simulator.

No idea what that means in practice but commenting purely on the code 

> x represents prey population
> y represents predator population

so use names that say so, like preyPop and predatorPop
Its only a few extra letters typing but makes things much more readable.

> dy/dt and dx/dt represents growth rate of the two populations over time
> t represents time
> a is the growth rate of prey

so call it preyGrowth?

> b is the rate at which predators kill prey

or killRate?

you get the idea...

> g is the death rate of predators
> d is the rate at which the predators population increases by consuming prey
> The equation:
> dx/dt = x(a-by)
> dy/dt = -y(g-dx)
> The code I have for this section is:
> def deltaX(a,b,x,y):
>      dx = x*(a-b*y)

Normally you define a function such that it returns a value. Here you 
simply define a local variable(dx), assign a value then throw it way 
when the function finishes. You probably want:

def deltaX(a,b,x,y):
      return x*(a-b*y)

> def deltaY(g,d,x,y):
>      dy = -y*(g-d*x)

same here

> The simulation function is where I am having trouble.

possibly because of some of the things above?

> For the simulation function, I need to ask the user for the number of
> runs and then save it in a variable, create a list for prey and
> predator.

> For each run, i need to calculate the increment of change in
> prey and predator populations by calling the deltaX and deltaY
> functions, then save these in a variable, and then update the population
> information.

 > The newly calculated populations then need to be added to
> the existing lists.  After this is completed, a function for the graph
> is called.

So three basic blocks of code required? Is your function structured like 
that? Which blocks work? Which ones don't? Can you test (eg print) each 
block separately? Hint: Can each block be a function?

> The following is my current simulation function:
> def simulation():
>      a=eval(input("Growth rate of prey:"))
>      b=eval(input("Rate at which predators eat prey:"))
>      g=eval(input("Death rate of predators:"))
>      d=eval(input("Rate at which predators increase by consuming prey:"))
>      x=eval(input("Current prey population:"))
>      y=eval(input("Current predator population:"))

Don't use eval.... convert types directly using int() or float()

Convert the above to a standalone function getSimulationData() or 
somesuch that returns the validated and converted input values.
Test it.

> deltaX(a,b,x,y)
> deltaY(g,d,x,y)

Here are the calls with no return values and so have no effect.
They are effectively wasted space. You need something like

dx = deltaX(a,b,x,y)
dy = deltaY(g,d,x,y)

after adding return statements as described above.

> n=eval(input("Number of runs:")
>      r = 0

The indentation suggests you are missing a loop structure somewhere?

>      count=0
>      yList = [0]
>      while r <= n:
>          r = r + 1
>          count = count + 1
>          yList.append(dx + dx)

dx does not exist as you wrote it, you need the changes above...
But even then you are adding the same value (2dx) each time,
is that right?

>      zList= [0]
>         while r <= n:
>         r = r + 1
>         count = count +1
>         zList.append(dy + dy)

Same applies for dy.

> It seems terribly wrong.

Yep, I'm pretty sure it is wrong. Also I'd try putting it into a 
separate function, populateData() maybe?

The simulate looks like:

def simulate:
    a,b,g,d,x,y = getSimulationData()
    xList,YList = populateData(a,b,g,d,x,y)

The following is my graph function:
> def drawCurve(yList,zList,n):
>      x = pylab.arange(n)
>      pylab.title("Foxes and Rabbits")
>      pylab.ylabel("Number of predator (Foxes)")
>      pylab.xlabel("\nNumber of prey  (Rabbits)")
>      pylab.plot(x, yList, 'b')
>      pylab.plot(x, zList, 'r')
>      pylab.legend(('Rabbits','Foxes'),loc='upper left')
>      pylab.show()

I don't use pyLab so will assume that is all OK...

> The issue i'm having is the logic in the lists.

The biggest issue is the naming and location of your variables and how 
you assign values to them (via returns from functions). Fix that first 
and things will start to improve.

Alan G
Author of the Learn to Program web site

More information about the Tutor mailing list