我正在尝试实施SIR epidemic model。基本上,我理解模型的方式是,在每个时间步骤,它告诉我们有多少节点被感染以及有多少节点被恢复。我现在正试图将其转换为离散事件模拟,并且在某一点上感到困惑。
该模型通常使用欧拉方法求解。现在,当我将其转换为离散事件模拟时,我正在做这样的事情(数字用于清晰):
Initialize 100 members
At every time step t,
//Determine how many get infected
for i = 1 to 100
let i pass a message to its neighbors
When the neighbor receives the message from an infected member, it generates a random number and if it is less than beta*(infected/total), where beta is the infection rate, then the member gets infected
Update the count for infected, recovered, susceptible
//Determine how many are recovered
for i = 1 to 100
Generate a random number from a uniform distribution and check if it is less than gamma*infected. If it is, then this member is recovered.
Update the count for infected, recovered, susceptible
我基本上想知道上述方法是否正确。有什么建议吗?
答案 0 :(得分:4)
作为一个开始看起来相当不错,除了对于第一个循环你需要记住只有易感个体可以被感染,而对于第二个循环,只有受感染的个体才能被恢复。我也相信每个事件的转换概率(易受感染的邻居接收消息,感染可能正在恢复)是不当前受感染个体数量的函数 - 它们是常数(我认为你“误导”质量效应“的概率在一个时间步骤应用于每个单独的剧集 - 他们没有。”
有点微妙的是你如何进行第一次循环(对我来说,从SIR模型来看并不明显):我想你要确定所有“消息”首先,然后哪些导致过渡易感 - >感染 - 即两个循环而不是一个 - 因为在这个时间步骤刚被感染的个体不能感染其他在同一时间步但仅在将来;此外,过渡感染 - >对于刚刚在这个阶段被感染的人来说,恢复是不可能的,所以你必须以不同的方式安排你的循环!
考虑使用两个“状态”属性为每个人建模:
-- nummsgs, number of "messages" received this time step
-- compartment (susceptible, infected or recovered)
以及一组固定的邻居。然后:
for each individual:
if individual.compartment != infected:
continue
for each neighbor of the individual:
neighbor.nummsgs += 1
if (random number says so):
individual.compartment = recovered
for each individual:
if individual.compartment != susceptible:
continue
maybe (depending on random number & nummsgs):
individual.compartment = infected
for each individual:
individual.nummsgs = 0
这似乎更好地捕获整体流量(收集和记录整体计数的净值,您可以在概念上将其作为最后一个循环的一部分)。
答案 1 :(得分:2)
我在这里至少看到两个问题,都源于同样的根本原因。
1)如果您介绍某种社区结构,那么beta*(infected/total)
应该只是beta
。
2)gamma*infected
仅限受感染个人申请的行,您不需要gamma*infected
- 它应该只是gamma
。
也许还有更多问题 - 很难从伪代码中说出来。欢迎您稍微改进一下,我会再看看。
答案 2 :(得分:2)
首先,这种方法通常不称为离散事件模拟,而是时间步模拟。严格来说,这并不是错误的,但在实践中,“离散事件”一词用于模拟,事件之间的时间是可变的。例如,如果每个受感染的节点在随机时间内向随机邻居生成“感染”消息。
其次,您的代码错过了消息的优先级或权重。如果节点收到感染和恢复消息怎么办?在受感染的blob中间,隔离节点和节点的恢复概率是否真的相同?这将导致受感染和健康状态之间的内部节点的抖动。
实际上,我没有理由在这里使用消息。每个节点的感染概率只是它被感染的邻居数量的函数 - 为什么不使用它呢?根据您的目标,用数学期望替换概率可能更好。
最后,问题与着名的“生命游戏”密切相关。看看各种实现。