2010-02-27 58 views
3

我试图执行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

我知道这已经很晚了,但是有没有不使用Gillespie算法的原因?你正在使用的不是离散事件相当于ODE公式(至少我认为)。 http://en.wikipedia.org/wiki/Gillespie_algorithm – MHH 2014-05-15 20:40:40

回答

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 

这似乎更好地捕捉整体流程(收集和记录总数量,你可以做概念作为最后一个循环的一部分后的净额)。

+0

谢谢你的解释。我会稍微考虑一下,并尽快回复修订。编辑:刚才看到你的修改后的帖子。现在就看看这个......非常感谢...... – Legend 2010-02-27 03:08:48

2

我在这里看到至少有两个问题,都源于相同的根本原因。

1)如果你引入某种邻域结构,那么beta*(infected/total)应该只是beta

2)具有gamma*infected苹果只有感染个人的行,而且你不需要gamma*infected - 它应该只是gamma

也许还有更多的问题 - 这很难从伪代码中说出来。欢迎您细化一下,我会再看一次。

+0

谢谢......我会尽快回复修改后的版本。我希望stackoverflow有一种方法来ping成员:)再次感谢。 – Legend 2010-02-27 03:09:16

+0

@传奇:Ping! (只是一个测试)。 – 2010-02-27 04:38:10

+0

@Moron:大声笑..我不知道你为什么试图对我:P在任何情况下,猜你的ping工作..! – Legend 2010-02-27 19:37:45

2

首先,这种方法通常不称为离散事件模拟,而是时间步模拟。严格来说,这并不正确,但实际上,“离散事件”术语用于事件之间的时间可变的模拟。例如,如果每个受感染节点在随机时间内生成一次“感染”消息给随机邻居。

其次,您的代码会漏掉消息的优先级或权重。如果节点接收到感染和恢复消息,该怎么办?感染的blob中间的孤立节点和节点的恢复概率是否应该相同?这会导致感染者和健康人之间的内部节点抖动。

其实,我在这里没有看到使用消息的理由。每个节点的感染概率只是感染邻居数量的一个函数 - 为什么不使用它?根据你的目标,用数学期望代替概率可能会更好。

最后,问题与着名的“生命游戏”密切相关。看看各种实现。