注解
此笔记本可从此处下载: Lotka_Volterra_model.ipynb
Lotka-Volterra方程
%matplotlib notebook
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy import integrate
import ipywidgets as ipw
也称为 predator-prey equations ,描述了通过捕食相互作用的两个物种的种群变化。例如,狼(捕食者)和鹿(猎物)。这是一个代表两个种群动态的经典模型。
让我们 \(\alpha>0\) , \(\beta>0\) , \(\delta>0\) 和 \(\gamma>0\) 。该系统由以下方式提供
\[\begin{split}\左\{
\BEGIN{array}{ll}
\点{x}=x(\alpha-\beta y)\\
\点{y}=y(-\增量+\Gamma x)
\end{数组}
\对。\end{split}\]
哪里 \(x\) 代表猎物数量和 \(y\) 捕食者种群。它是一个一阶非线性常微分方程组。
问题重述
我们摆姿势,
\[ \begin{align}\begin{aligned}\begin{split}x=\Begin{pMatrix}x\\
y\end{pMatrix}\end{split}\\并将上面的问题重写为\end{aligned}\end{align} \]
\[\begin{split}\点{X}=\BEGIN{pMatrix}x(\alpha-\beta y)\\
y(-\δ+\Gamma x)\end{pMatrix}=f(X)\end{split}\]
备注 :这是一个自主的问题。
数值模拟
设置
alpha = 1. #mortality rate due to predators
beta = 1.
delta = 1.
gamma = 1.
x0 = 4.
y0 = 2.
def derivative(X, t, alpha, beta, delta, gamma):
x, y = X
dotx = x * (alpha - beta * y)
doty = y * (-delta + gamma * x)
return np.array([dotx, doty])
解算方式 odeint
Nt = 1000
tmax = 30.
t = np.linspace(0.,tmax, Nt)
X0 = [x0, y0]
res = integrate.odeint(derivative, X0, t, args = (alpha, beta, delta, gamma))
x, y = res.T
(2, 1000)
plt.figure()
plt.grid()
plt.title("odeint method")
plt.plot(t, x, 'xb', label = 'Deer')
plt.plot(t, y, '+r', label = "Wolves")
plt.xlabel('Time t, [days]')
plt.ylabel('Population')
plt.legend()
plt.show()
<IPython.core.display.Javascript object>
import random
import matplotlib.cm as cm
betas = np.arange(0.9, 1.4, 0.1)
nums=np.random.random((10,len(betas)))
colors = cm.rainbow(np.linspace(0, 1, nums.shape[0])) # generate the colors for each data set
fig, ax = plt.subplots(2,1)
for beta, i in zip(betas, range(len(betas))):
res = integrate.odeint(derivative, X0, t, args = (alpha,beta, delta, gamma))
ax[0].plot(t, res[:,0], color = colors[i], linestyle = '-', label = r"$\beta = $" + "{0:.2f}".format(beta))
ax[1].plot(t, res[:,1], color = colors[i], linestyle = '-', label = r" $\beta = $" + "{0:.2f}".format(beta))
ax[0].legend()
ax[1].legend()
ax[0].grid()
ax[1].grid()
ax[0].set_xlabel('Time t, [days]')
ax[0].set_ylabel('Deer')
ax[1].set_xlabel('Time t, [days]')
ax[1].set_ylabel('Wolves');
<IPython.core.display.Javascript object>
相图
相图是动力系统在相空间(对应于状态变量的轴)中的轨迹的几何表示 \(x\) 和 \(y\) )。它是一个可视化和分析动态系统行为的工具。特别是在像Lotka-Volterra方程这样的振荡系统的情况下。
plt.figure()
IC = np.linspace(1.0, 6.0, 21) # initial conditions for deer population (prey)
for deer in IC:
X0 = [deer, 1.0]
Xs = integrate.odeint(derivative, X0, t, args = (alpha, beta, delta, gamma))
plt.plot(Xs[:,0], Xs[:,1], "-", label = "$x_0 =$"+str(X0[0]))
plt.xlabel("Deer")
plt.ylabel("Wolves")
plt.legend()
plt.title("Deer vs Wolves");
<IPython.core.display.Javascript object>
这些曲线说明系统是周期性的,因为它们是封闭的。
1/alpha
1.0
显式欧拉法求解
def Euler(func, X0, t, alpha, beta, delta, gamma):
"""
Euler solver.
"""
dt = t[1] - t[0]
nt = len(t)
X = np.zeros([nt, len(X0)])
X[0] = X0
for i in range(nt-1):
X[i+1] = X[i] + func(X[i], t[i], alpha, beta, delta, gamma) * dt
return X
Xe = Euler(derivative, X0, t, alpha, beta, delta, gamma)
plt.figure()
plt.title("Euler method")
plt.plot(t, Xe[:, 0], 'xb', label = 'Deer')
plt.plot(t, Xe[:, 1], '+r', label = "Wolves")
plt.grid()
plt.xlabel("Time, $t$ [s]")
plt.ylabel('Population')
plt.ylim([0.,3.])
plt.legend(loc = "best")
plt.show()
<IPython.core.display.Javascript object>
plt.figure()
plt.plot(Xe[:, 0], Xe[:, 1], "-")
plt.xlabel("Deer")
plt.ylabel("Wolves")
plt.grid()
plt.title("Phase plane : Deer vs Wolves (Euler)");
<IPython.core.display.Javascript object>
使用RK4
def RK4(func, X0, t, alpha, beta, delta, gamma):
"""
Runge Kutta 4 solver.
"""
dt = t[1] - t[0]
nt = len(t)
X = np.zeros([nt, len(X0)])
X[0] = X0
for i in range(nt-1):
k1 = func(X[i], t[i], alpha, beta, delta, gamma)
k2 = func(X[i] + dt/2. * k1, t[i] + dt/2., alpha, beta, delta, gamma)
k3 = func(X[i] + dt/2. * k2, t[i] + dt/2., alpha, beta, delta, gamma)
k4 = func(X[i] + dt * k3, t[i] + dt, alpha, beta, delta, gamma)
X[i+1] = X[i] + dt / 6. * (k1 + 2. * k2 + 2. * k3 + k4)
return X
Xrk4 = RK4(derivative, X0, t, alpha, beta, delta, gamma)
plt.figure()
plt.title("RK4 method")
plt.plot(t, Xrk4[:, 0], 'xb', label = 'Deer')
plt.plot(t, Xrk4[:, 1], '+r', label = "Wolves")
plt.grid()
plt.xlabel("Time, $t$ [s]")
plt.ylabel('Population')
plt.legend(loc = "best")
plt.show();
<IPython.core.display.Javascript object>
plt.figure()
plt.plot(Xrk4[:, 0], Xrk4[:, 1], "-")
plt.xlabel("Deer")
plt.ylabel("Wolves")
plt.grid()
plt.title("Phase plane : Deer vs Wolves (RK4)");
<IPython.core.display.Javascript object>