在Python中使用Runge-Kutta的Lotka-Volterra方程(捕食者猎物)

时间:2015-04-21 01:52:01

标签: python numpy runge-kutta

我正在尝试使用Lotka-Volterra方程编写一个用于捕食者 - 猎物相互作用的程序。使用ODE解决:

dx/dt = a*x - B*x*y
dy/dt = g*x*y - s*y

使用4阶Runge-Kutta方法

我需要绘制一个图表,显示从t = 0到t = 30时x和y都是时间的函数。

  

a = alpha = 1
  b = beta = 0.5
  g =γ= 0.5
  s = sigma = 2
  初始条件x = y = 2

到目前为止,这是我的代码,但未在图表上显示任何内容。一些帮助会很好。

#!/usr/bin/env python

from __future__ import division, print_function
import matplotlib.pyplot as plt
import numpy as np

def rk4(f, r, t, h):
        """ Runge-Kutta 4 method """
        k1 = h*f(r, t)
        k2 = h*f(r+0.5*k1, t+0.5*h)
        k3 = h*f(r+0.5*k2, t+0.5*h)
        k4 = h*f(r+k3, t+h)
        return (k1 + 2*k2 + 2*k3 + k4)/6

def f(r, t):
        alpha = 1.0
        beta = 0.5
        gamma = 0.5
        sigma = 2.0
        x, y = r[2], r[2]
        fxd = x*(alpha - beta*y)
        fyd = -y*(gamma - sigma*x)
        return np.array([fxd, fyd], float)


tpoints = np.linspace(0, 30, 0.1)
xpoints = []
ypoints = []

r = np.array([2, 2], float)
for t in tpoints:
        xpoints += [r[2]]
        ypoints += [r[2]]
        r += rk4(f, r, t, h)

plt.plot(tpoints, xpoints)
plt.plot(tpoints, ypoints)
plt.xlabel("Time")
plt.ylabel("Population")
plt.title("Lotka-Volterra Model")
plt.savefig("Lotka_Volterra.png")
plt.show()

2 个答案:

答案 0 :(得分:4)

运行脚本后对变量tpoints进行简单检查即表明它是空的:

In [7]: run test.py

In [8]: tpoints
Out[8]: array([], dtype=float64)

这是因为您错误地使用了np.linspace。第三个参数是输出中所需的元素数。您已请求长度为0.1的数组。

查看np.linspace的文档字符串。您在确定如何调整代码时遇到了问题。

答案 1 :(得分:0)

1)定义“ h”变量。

2)使用

z-index: 1;

不是

tpoints = np.arange(30) #array([0, 1, 2, ..., 30])

并且不要忘记将时间步长设置为等于h:

np.linspace()

3)注意索引:

h=0.1
tpoints = np.arange(0, 30, h)
def f(r,t):
    ...
    x, y=r[0], r[1]
    ...

最好使用.append(x):

for t in tpoints:
    xpoints += [r[0]]
    ypoints += [r[1]]
    ...

这是经过测试的python 3.7代码(我将h = 0.001设置为更多预大小)

for t in tpoints:
    xpoints.append(r[0])
    ypoints.append(r[1])
    ...

您也可以尝试绘制“周期”:

import matplotlib.pyplot as plt
import numpy as np

def rk4(r, t, h):                    #edited; no need for input f
        """ Runge-Kutta 4 method """
        k1 = h*f(r, t)
        k2 = h*f(r+0.5*k1, t+0.5*h)
        k3 = h*f(r+0.5*k2, t+0.5*h)
        k4 = h*f(r+k3, t+h)
        return (k1 + 2*k2 + 2*k3 + k4)/6

def f(r, t):
        alpha = 1.0
        beta = 0.5
        gamma = 0.5
        sigma = 2.0
        x, y = r[0], r[1]
        fxd = x*(alpha - beta*y)
        fyd = -y*(gamma - sigma*x)
        return np.array([fxd, fyd], float)

h=0.001                               #edited
tpoints = np.arange(0, 30, h)         #edited
xpoints, ypoints  = [], []
r = np.array([2, 2], float)
for t in tpoints:
        xpoints.append(r[0])          #edited
        ypoints.append(r[1])          #edited
        r += rk4(r, t, h)             #edited; no need for input f
plt.plot(tpoints, xpoints)
plt.plot(tpoints, ypoints)
plt.xlabel("Time")
plt.ylabel("Population")
plt.title("Lotka-Volterra Model")
plt.savefig("Lotka_Volterra.png")
plt.show()

https://i.stack.imgur.com/NB9lc.png