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

使用R语言deSolve包dede求解时滞SEIRVB ODE的问题排查

问题排查与解决方案

核心问题:未向dede告知延迟参数

deSolve的dede函数需要明确知晓模型中存在的时间延迟长度,否则求解器会直接忽略滞后项,按普通常微分方程求解,导致修改tau后结果无变化。此外,全局变量的使用也可能引发潜在的作用域问题。

具体修复步骤

1. 将所有参数(包括tau)放入parms列表

避免依赖全局变量,把模型用到的所有参数打包进parms列表,确保函数能正确获取参数:

# 参数定义改为列表形式
parms <- list(
  Lambda = 0.5,      
  beta1 = 1.13921549,    
  beta2 = 2.68228986,      
  beta3 = 2.9627036,      
  beta4 = 1.19686956,     
  beta5 = 0.5,    
  beta6 = 1.34496108,     
  beta7 = 3.40332936,   
  beta8 = 1.48249240,    
  beta9 = 0.04681161,     
  beta10 = 2.32555864,    
  alpha = 0.5,    
  kappa = 0.02933240,    
  d = 0.0047876,          
  r = 0.09871,        
  tau = 7  # 时间延迟
)

2. 修改模型函数,从parms中读取参数

调整模型函数,使用with(parms, {})包裹逻辑,不再依赖全局变量:

seirvb_model <- function(t, y, parms) {
  with(parms, {
    # 获取滞后的I值
    if (t < tau) {
      Ilag <- initial_conditions["I"]
    } else {
      # lagvalue第二个参数为变量索引,y[3]对应I,索引正确
      Ilag <- lagvalue(t - tau, 3)
    }
    
    # 计算各状态变量的导数
    dS <- Lambda - beta1 * y[1] * y[2] - (beta3 + alpha) * y[1]
    dE <- beta4 * y[5] * y[2] + beta6 * y[6] * y[2] + beta1 * y[1] * y[2] - beta2 * y[2] * y[3] - (kappa + alpha) * y[2]
    dI <- beta5 * y[5] * Ilag + beta7 * y[6] * y[3] + beta2 * y[2] * y[3] - (d + alpha + r) * y[3]
    dR <- beta9 * y[5] + beta8 * y[6] + r * y[3] + kappa * y[2] - alpha * y[4]
    dV <- beta3 * y[1] - (beta9 + alpha + beta10) * y[5] - beta4 * y[5] * y[2] - beta5 * y[5] * Ilag
    dB <- beta10 * y[5] - beta6 * y[6] * y[2] - beta7 * y[6] * y[3] - (beta8 + alpha) * y[6]
    
    return(list(c(dS, dE, dI, dR, dV, dB)))
  })
}

3. 调用dede时传递delays参数

必须通过delays参数告知求解器模型中的延迟时间,这样求解器才会处理滞后项:

# 求解模型,添加delays参数
ode_output <- dede(
  y = initial_conditions, 
  times = times, 
  func = seirvb_model, 
  parms = parms,
  delays = parms$tau  # 传递延迟参数
)

4. 验证修改效果

修改parms$tau的值(比如改为14),重新运行代码,观察输出结果的变化,此时时滞应该能正常发挥作用。

完整修复后的代码

library(deSolve)

# 参数定义(打包为列表)
parms <- list(
  Lambda = 0.5,      
  beta1 = 1.13921549,    
  beta2 = 2.68228986,      
  beta3 = 2.9627036,      
  beta4 = 1.19686956,     
  beta5 = 0.5,    
  beta6 = 1.34496108,     
  beta7 = 3.40332936,   
  beta8 = 1.48249240,    
  beta9 = 0.04681161,     
  beta10 = 2.32555864,    
  alpha = 0.5,    
  kappa = 0.02933240,    
  d = 0.0047876,          
  r = 0.09871,        
  tau = 7  # 时间延迟
)

# 带时滞的SEIRVB模型函数
seirvb_model <- function(t, y, parms) {
  with(parms, {
    # 获取滞后的I值
    if (t < tau) {
      Ilag <- initial_conditions["I"]
    } else {
      Ilag <- lagvalue(t - tau, 3)  # y[3]对应I变量
    }
    
    # 计算各状态变量导数
    dS <- Lambda - beta1 * y[1] * y[2] - (beta3 + alpha) * y[1]
    dE <- beta4 * y[5] * y[2] + beta6 * y[6] * y[2] + beta1 * y[1] * y[2] - beta2 * y[2] * y[3] - (kappa + alpha) * y[2]
    dI <- beta5 * y[5] * Ilag + beta7 * y[6] * y[3] + beta2 * y[2] * y[3] - (d + alpha + r) * y[3]
    dR <- beta9 * y[5] + beta8 * y[6] + r * y[3] + kappa * y[2] - alpha * y[4]
    dV <- beta3 * y[1] - (beta9 + alpha + beta10) * y[5] - beta4 * y[5] * y[2] - beta5 * y[5] * Ilag
    dB <- beta10 * y[5] - beta6 * y[6] * y[2] - beta7 * y[6] * y[3] - (beta8 + alpha) * y[6]
    
    return(list(c(dS, dE, dI, dR, dV, dB)))
  })
}

# 初始条件
initial_conditions <- c(
  S=0.3,
  E=0.1,
  I=0.006,
  R=0,
  V=0,
  B=0
)

# 时间向量
times <- seq(0, 120, by = 1)

# 求解模型(传递delays参数)
ode_output <- dede(
  y = initial_conditions, 
  times = times, 
  func = seirvb_model, 
  parms = parms,
  delays = parms$tau
)

# 绘图
plot(ode_output, xlab = "Time", ylab = "Population", main = "SEIRVB Model for COVID-19")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 14:04:55