You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用GEKKO拟合两类种群至测量数据并优化初始点

种群总和时间序列拟合优化:引入初始比例变量f

模型定义

种群动态变化的微分方程模型如下:

dS/dt = (a - b) * S
dR/dt = (a - b - c)* R
X(t) = S(t) + R(t)

优化需求

现有代码中种群初始值为固定值,需调整为引入取值范围在0到1之间的变量f,用其表示两类种群的初始比例:

S0 = x_meas[0] * f
R0 = x_meas[0] * (1-f)

修改后的完整代码

from gekko import GEKKO
m = GEKKO(remote=False)

# 时间与测量数据
m.time = [0,0.1,0.2,0.3,0.4,0.5,0.8,0.85,0.9,0.95,1]
x_meas = [1.1,1.2,1.56,1.77,1.89,2.1,2.3,2.5,2.7,2.2,2.1]

# 待优化参数a、b、c,取值范围0.5到10
p = m.Array(m.FV,3,lb=0.5,ub=10); a,b,c = p
# 开启参数优化状态
for fv in p:
   fv.STATUS=1

# 初始比例变量f,取值范围0到1,初始值设为0.01
f0 = m.FV(value=0.01, lb=0, ub=1)
f0.STATUS=1

# 定义状态变量S、R、X,下限为0
S,R,X = m.Array(m.Var,3,lb=0)

# 根据f设置初始条件
S0 = x_meas[0] * f0
R0 = x_meas[0] * (1 - f0)
# 绑定初始值到状态变量(确保求解器可优化f0)
m.fix(S, pos=0, val=S0)
m.fix(R, pos=0, val=R0)
X.value = x_meas[0]

# 测量值参数
Xm = m.Param(x_meas)

# 建立微分方程与总和方程
m.Equations([S.dt()==(a-b)*S,
             R.dt()==(a-b-c)*R,
             X==S+R])

# 目标:最小化拟合值与测量值的平方差
m.Minimize((X-Xm)**2)

# 设置求解器模式与配置
m.options.IMODE = 5   # 动态估计模式
m.options.NODES = 3   # 配置配点节点数
m.solve(disp=False)   # 求解,关闭输出

# 打印优化后的参数
print(f'a: {a.value[0]:.4f}, b: {b.value[0]:.4f}, c: {c.value[0]:.4f}, f: {f0.value[0]:.4f}')

# 绘图展示结果
import matplotlib.pyplot as plt
plt.figure(figsize=(7,3))
plt.plot(m.time,S.value,'b:',linewidth=3,label='S种群')
plt.plot(m.time,R.value,'r--',linewidth=2,label='R种群')
plt.plot(m.time,X.value,'k--',label='拟合总和X')
plt.plot(m.time,Xm.value,'kx',label='测量值Xm')
plt.legend(); plt.grid(); plt.xlabel('时间')
plt.tight_layout()
plt.savefig('fit.png',dpi=300)
plt.show()

关键修改说明

  • 移除原代码中固定的初始值S0,R0 = [0.35,0.65],替换为基于f0和测量初始值x_meas[0]计算的动态初始条件
  • 使用m.fix()方法绑定状态变量S、R的初始值,确保求解器可通过优化f0调整初始比例(直接赋值S.value=S0会因S0为变量而非数值报错)
  • 新增打印优化后的f值,便于查看最优初始比例

内容的提问来源于stack exchange,提问作者Giovanni Conti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 23:33:31