流行病是一系列随机事件

流行病是一系列随机事件

如果进行了接触,那么感染是否被转移就好比扔了一枚(装有子弹的)硬币。模拟如何考虑所有这些不确定性?

比尔·卡塞尔曼
不列颠哥伦比亚大学

就在最近,我开始考虑自己制造流行病。当然,在一台拥有数字人口的计算机上。

我的想法并不复杂。我会聚集一群“人”,其中一些人感染了病毒,然后从一天到另一天,让病毒通过人群中的相互作用传播。每一刻,一个人都会处于几种可能的状态之一:

  • S公司未感染但易感染
  • E类已感染,但尚未感染(e(电子)暴露)
  • A类感染,但尚未出现症状(有症状的)
  • 有感染性且有症状
  • R(右)已被感染或无法感染(例如通过接种疫苗)

这并不能完全代表现实。例如,在当前的疫情中,极少数人再次感染。但这离正确不远。

一般来说,随着模拟的进行,一个人会从这个列表中的一个状态进入下一个状态,当然,接种疫苗是从第一个状态到最后一个状态的捷径除外。感染发生的原因是易感人群与传染性人群相互作用。即使发生相互作用,感染是否传播也取决于许多意外情况(例如,周围通风)以及感染者的传染性。

其中一些状态还有一些进一步的内部细节。一个人的感染程度随时间而变化,通常在几天后达到峰值,然后下降到零。因此,在模拟中,每个人除了(i)州的名称外,还附加了州的名称A类(ii)衡量传染性的数字。进一步的数据是(iii)一个人与他人接触的频率,特别是密切接触的频率。这可以随着时间而改变。例如,当一个人开始出现症状时,他可能会减少接触的频率。

数学在哪里?流行病是由随机事件驱动的。一个人从一个状态进入下一个状态的时刻不是由环境决定的,而是一个概率问题。一个人感染的严重程度是一个偶然的问题,从他被感染到他感染的时间长短也是一个偶然性的问题。即使我们知道感染者的平均接触率,一天内接触的确切人数也是一个机会问题。如果进行了接触,那么感染是否被转移就好比扔了一枚(装有子弹的)硬币。模拟如何考虑所有这些不确定性?

正在生成联系人

以联系人为例。控制联系人的最重要参数是一个人在一天中的平均联系人数量,但这并不意味着一天中联系人的数量是恒定的。它可能每天都在变化。相反,有理由假设个人互动是泊松过程,这意味着一天内建立$k$联系人的概率是$p{k}=c^{k}e^{-c}/k!$。注意,由于众所周知的公式,$p_{k}$的无限和是$1$

$$e^{c}=1+c+{c^{2}\超过2!}+{c^{3}\超过3!}+\光盘\$$

例如,以下是一些具有$c$两个值的示例的图形:

在模拟中,一个人将与大量的人打交道。他们每个人都有自己的互动方式。他们中的一些人将比其他人更具互动性。因此,我们可能会发现自己在模拟大量独立的泊松过程,每个过程都是一系列随机事件。如何做到这一点?在程序中,这将涉及到调用例程,调用它p_random(c)(随机)它在每次调用时返回一个随机非负整数,其分布与泊松过程的平均值$c$相匹配。

几乎每种编程语言都内置了一个例程随机()这有点像这样。每次调用时,它都返回一个实数,该实数均匀分布在开放区间$[0,1)$中以前的FC对其工作原理有一些了解。)我们想做的是使用该例程生成符合指定泊松分布的非负整数。为了让您对事情的发展有一些了解,我们可以看到此技术如何生成在任何整数范围$[0,n-1]$中均匀分布的整数:在$[0,1)$中获得一个随机数$x$,然后用$nx$的整数部分$\lfloor nx\rfloor$替换它。如果$n=2$,则提供抛硬币的模拟,如果$n=6$,则模拟掷骰子。

有一个相当众所周知的程序,可以实现我们想要的,而且非常普遍。这在Knuth的书中有解释经典文本假设我们得到了给定概率$p_{k}$的整数的任意概率分布。也就是说,我们正在研究一些类似抛硬币的重复事件,其中非负整数$k$发生的概率为$p_{k}$。程序如何生成根据这些统计数据分布的整数?

让$P(k)$成为累积分布

$$P(k)={\sum}_{i=0}^{k}P(i)$$

因此$P(k)$是整数$j$出现的概率$\le k$。原始分布具有每个$p_{i}\ge0$和${sum}p(i)=1$的属性,因此$p(k)$从$0$增加到$1$。例如,如果$c=2.5$和$p(k)=e^{-c}c^{k}/k!$那么$P$的图形看起来像下图。给定$[0,1)$中的一个随机数$t$,我们可以根据指示的配方确定一个整数-从点$(0,t)$向右画一条线,并选择它到达该图的点的$x$-坐标。

还有另一种具有启发性的方式来看待这一点。制作一个总高度为$1$的矩形,将其划分为多个框,其中一个框的高度为$p_{k}$,标记为$k$。给定数字$x$,在矩形中标记高度为$x$的点。选择包含它的框的标签。

从长远来看,您点击标有$k$的框的次数将与其面积成正比,因此为$p_{k}$。但是你怎么知道这个标签是什么?这个问题有一个简单的答案:

定义p_random():x=随机()#这是内置的随机数生成器s=0i=0而s<=x:i+=1s+=p[i]#出口p[0]+…+p[i-1]<=x<p[i]返回i-1

但这有点低效,因为每次调用平均涉及$n/2$个步骤。是否存在一种算法需要独立于$n$的多个步骤?答案是肯定的。一种聪明的方法,其基本思想显然是由于阿拉斯泰尔·沃克这样做,只需花费很小的成本建造一些初步结构。

沃克的诡计

据我所知,沃克从未解释过他是如何发现他的方法的,但他给出了一个优雅的解释基思·施瓦茨基本思想是我们已经看到的:

  1. 从某种盒子开始。将其划分为较小的带标签的框,使框$k$的面积与$p_{k}$成比例。
  2. 要生成具有给定概率分布的整数,请在框内随机选择点,并返回命中区域的标签。
  3. 安排一种方式,为$[0,1)$中的每个随机$x$分配方框中的一个点。

问题是要找出如何制作分区,以便能够有效地从分区的几何图形中计算出标签。

我将解释Walker的方法如何在一些简单的情况下工作,但首先我将概括这个问题,以便我们不局限于泊松分布。假设我们得到了$[0,n-1]$中$i$的概率$p_{i}$。我们现在需要一个方法来生成随机整数,这些整数遵循$p_{i}$分配的分布。也就是说,如果我们以这种方式生成大量整数,我们希望$i$的出现比例大致为$p_{i}$。

情况$n=2$就像抛出一枚有偏见的硬币,有一个简单的解决方案。在这种情况下,我们给出了两个概率$p_{0}$,$p_{1}$,其中$p_{0}+p_{1}=1$。以这种方式划分单元广场:

在方框中随机选择一个点$(x,y)$。事实上,我们不必关注$x$。如果$y\le p_{0}$,则返回$i=0$,否则返回$i=1$。

但现在,继基思·施瓦茨之后,我打算展示沃克算法在这个非常简单的情况下是如何工作的,我将以稍微不同的方式设置一个矩形区域。首先,将其维度设置为$2\乘以1$。把它分成两部分:一次分成两半,每一半是一个单位正方形…

…然后在每一半中构建一个维度为$1\乘以p_{i}$的方框,例如在第$i$-th一半中。给这些盒子贴上标签。除非$p_{0}=p_{1}$,否则其中一个将在顶部溢出:

因此,我们切断溢出部分,并将其(带标签)粘贴到另一个盒子中:

这显示了案例$p_{0}\lep_{1}$。如果$p_{1}<p_{0}$如下所示:

我们如何使用这些图表来生成我们想要的随机整数?选择随机统一编号$x$in$[0,1)$等于前面选择矩形中的一个点。但我们的做法不同,我们的解释也不同。给定$x$,设置$x=2x$。让$m$是$x$的整数部分,即$0$或$1$:$m=\lfloor x\rfloor$。让$y=x–m$,即$x$中的小数部分。与$m$-th框中的$x$点关联,高度为$y$。如果$y\ltp_{m}$,那么我们在标有$m$的框中,否则在另一个框中。在任何一种情况下,流程都会选择标签$m$。

现在看看$n=3$的情况,假设我们得到了概率$p_{0}、p_{1}和p_{2}$,其中$\sump_{i}=1$。我们从一个大小为$3\乘以1$的矩形开始,将其划分为$1\乘以1$box:

根据$p_{i}$的相对大小,还有不同的情况。最简单的情况是$p$的两个值,例如$p_{0}$和$p_}$,小于$1/3$,这意味着第三个值大于$1/3$。在$i$-th方块中绘制维度$1\times p_{i}$的$i$框,如下所示:

现在从大盒子上切下两块,贴在小盒子上,得到:

我稍后将解释如何使用它来生成随机数。

第二种情况下,$p_{i}$中有两个大于$1/3$:

在这里,我们想从顶部开始,填充第三个。很容易准确地切断大区域中的溢出并粘贴它们,但这会给第三个区域三个标签。这不是我们想要的。所以我们只从其中一个大区域填充。这将在其中留下一些空间。

我们从另一个大区域填补了新的空白。我们现在完成了:

如何使用我们构建的内容?在每种情况下,我们都将大小为$3\乘以1$的矩形分区。首先,分成三个单位正方形,然后依次将每个正方形变成一个或两个带标签的矩形。给定$[0,1)$中的一个随机$x$,我们想在$[0,3)$中得到一些整数。如何实现?我们首先将其缩放到$X=3x$。这将位于$m=\lfloor X\rfloor$的区间$[m,m+1)$。现在我们将注意力转向第$m$个单位正方形。我们返回的整数将是该正方形中的标签之一。设$y=X–m$,$X$的小数部分,将在$[0,1)$中。如果$y\lt p_{m}$(底部矩形的高度),p_随机返回$m$,否则返回该方块中的备用标签。

实际上,我们正在分配主要的候补将标签粘贴到框中。但如果盒子满了,就不会有替代标签。

在文献中,我称之为“alternate”的数组称为别名,这里描述的方法称为别名方法。

完整的算法

这种方法很好地推广了。最初的版本似乎是阿拉斯泰尔·沃克的作品。它之所以广为人知,是因为Knuth引起了人们的注意(尽管主要是在练习中)。迈克尔·沃斯(Michael Vose)随后提出了一个更高效的版本,并使其能够更稳定地处理舍入错误。

我在下面几乎一字不差地引用了最初在沃斯的论文它改进了Walker程序的运行时间,并纠正了它对舍入错误的处理。它有两部分。一个是设置数组的初始化问题别名来自概率数组$p$。这些在函数中使用兰特,返回范围为$[0,n-1]$的随机变量,其概率在第页长度为n个.呼叫随机的,随机的返回均匀分布在$[0,1)$中的变量。

程序中有几个循环。第一个函数将$[0,n-1]$范围内的整数赋给两个显式数组之一大的小的。中的那些小的是$i$,即$p{i}\le 1/n$。随着程序的进行,这些数组中的整数是那些尚未填充方框的整数。隐式是$[0,n-1]$的第三个子集,我将调用它已完成。它包含所有不需要进一步处理的索引。e.谁的盒子被填满。

在循环[0]中,两个数组小的大的初始化,并且子集已完成保留为空。在这个循环的每次运行中,都会从小的,则填充其正方形,并将其添加到FIN中。这是通过从中的一个盒子中移除填充材料来实现的大的,因此变得更小。它被添加到其中之一小的大的,根据还剩多少。在每个循环中大的小的是递减的。

定义初始化(p):l=0s=0[0]对于范围(n)内的i:如果p[i]>1/n:大[l]=il+=1其他:小[s]=is+=1[1]当s>0和l>0时:s-=1j=小[s]l-=1k=大[l]prob[j]=n*p[j]别名[j]=kp[k]+=(p[j]-b)如果p[k]>b:大[l]=kl+=1其他:小[s]=ks+=1[2]当s>0时:s-=1prob[small[s]]=1[3]当l>0时:l-=1prob[大[l]]=1定义p_random():x=n*随机(0,1)m=地板(x)如果(x-m)<prob[m]:返回melse:返回别名[m]

Vose代码的最后一个循环[2]和[3]对于处理舍入误差是必要的,我在不做进一步评论的情况下将其包括在内。

这里是平均$\mu=4$的泊松过程的典型运行。

模拟

让我们看看如何使用Walker的方法来模拟刚感染的人如何继续感染他人。假设他在第五天开始感染,并且感染接触者的概率如下表所示:

$$\矩阵{i=\hbox{感染后第二天}&1&2&3&4&5&6&7&8&9&ge10\crr{i}=\hbos{感染概率}&0&0&0&0.1&0.3&0.4&0.2&0\cr}$$

假设他每天平均接触$4$的亲密联系人,并且这些联系人遵循泊松分布。应用Walker的算法,我们得到了这样的联系人示例:

$$\矩阵{i=\hbox{感染后第二天}&1&2&3&4&5&6&7&8&10\\dots\crc{i}=\hbos{接触人数}&5&2&4&3&2&1&3\\dots\ cr}$$

这次,他感染了多少人?这个问题没有唯一的答案。这取决于每次接触时投掷硬币之类的东西。我们可以计算的是平均数。在第五天,他平均感染了$0.1/cdot 3$人,在第六天……等等。总之:

$$\hbox{平均感染人数}={\sum}c{i}r{i}=0.1\cdot3+0.3\cdot3+0.4\cdot2+0.4\cdot1+0.2\cdot3=3.0\$$

这远远低于他感染的平均人数,在本例中称为$R_{0}$值。这里是$(0.1+0.3+0.4+0.4+0.2)\cdot 4=5.6$。

进一步阅读

  • Keith Schwartz关于飞镖的别名算法。我从这个详尽的处理中获得了Walker算法的图形解释。
  • 阿拉斯泰尔·沃克,生成一般分布离散随机变量的一种有效方法,ACM数学软件交易, 1977.
  • 迈克尔·沃斯,生成给定分布随机数的线性算法IEEE软件工程汇刊17, 1991.
  • 唐纳德·科努特,计算机编程艺术,第二卷关于半数值算法。第3.4节讨论了生成具有给定概率分布的随机数的问题。
  • 大卫·奥斯汀, 没有任何机会解释计算机如何生成均匀分布(伪)随机数。
  • Python代码对于初始化p_随机

1条评论

  1. 有趣的帖子。我不知道这种从给定的离散分布生成随机变量的聪明算法。然而,上述帖子中有两个小错误。
    首先,在你对基本算法的分析中,你说它包含“平均n/2步”。假设(就像你对算法所做的那样)随机变量有值1,2,…,n,那么如果算法返回值i,它将运行i+1循环。因此,平均运行时间将为$mu$+1,其中$mu$是相关分布的预期值。
    第二个小问题是,您所讨论的算法仅适用于有限概率分布,但您讨论了如何将它们应用于泊松分布,而没有提到当然您必须真正生成截断的泊松分布(并且必须选择截断分布的位置)。

留下回复

您的电子邮件地址将不会被发布。 已标记必填字段*

不允许使用HTML标记。

49143封垃圾邮件简单注释