模拟多个泊松过程

时间:2013-07-05 14:40:04

标签: python math

我有N个进程,每个进程有不同的泊松率。我想模拟所有N个进程的到达时间。如果N = 1,我可以这样做

t = 0
N = 1
for i in range(1,10):
   t+= random.expovariate(15)
   print N, t

但是如果我有N = 5和费率列表

rates =  [10,1,15,4,2]

我想以某种方式让循环以正确的顺序输出所有N个进程的到达时间。也就是说,我仍然希望每行只有两个数字(流程的ID和到达时间),但全球按到达时间排序。

我可以制作N个列表然后合并它们但是我希望首先以正确的顺序输出到达时间。

更新。一个问题是,如果您只是从每个流程中抽取固定数量的到达次数,那么您只能从高流量流程中获得早期时间。所以我认为我需要从每个过程的固定时间间隔进行采样,因此样本数量会根据速率而变化。

2 个答案:

答案 0 :(得分:3)

如果我理解正确的话:

import random
import itertools

def arrivalGenerator(rate):
    t = 0
    while True:
        t += random.expovariate(rate)
        yield t

rates = [10, 1, 15, 4, 2]
t = [(i, 0) for i in range(0, len(rates))]
arrivals = []
for i in range(len(rates)):
    t = 0
    generator = arrivalGenerator(rates[i])
    arrivals += [(i, arrival) \
                 for arrival in itertools.takewhile(lambda t: t < 100, generator)]


sorted_arrivals = sorted(arrivals, key=lambda x: x[1])
for arrival in sorted_arrivals:
    print arrival[0], arrival[1]

请注意,您的初始逻辑为每个进程生成了固定数量的到达。你真正想要的是一个特定的时间窗口,并在你超过那个时间窗口之前继续为给定的过程生成。

答案 1 :(得分:1)

关注http://www.columbia.edu/~ks20/4703-Sigman/4703-07-Notes-PP-NSPP.pdf我认为答案会更有效。

你粗略地做了:

total_rate = sum(rates)
probabilities = [ r/total_rate for r in rates ]

arrivals = []
t = 0
while t < T:
   t += random.expovariate(total_rate)
   i = weighted_random(probabilities)
   arrivals += (i, t)

这种方法消除了为大量不同的到达过程保持协程状态的需要。只有一个“净”到达过程。分配将是相同的。

请注意,我没有给出上面的weighted_random实现,但我认为我的意图很明确。它留给读者练习;-) - 或参见例如http://eli.thegreenplace.net/2010/01/22/weighted-random-generation-in-python

你也可以这样做:

arrivals = []
t = 0
while t < T:
    dt_list = [ random.expovariate(r) for r in rates ]
    (dt,i) = min((tau,i) for i,tau in enumerate(dt_list))
    t += dt
    arrivals += (i, t)

即,您实际上为所有进程生成单独的到达间隔时间,但您不需要“记住”进程的状态。请注意,速率为r1和r2的两个独立指数分布随机变量的最小值本身是以速率r1 + r2(每http://ocw.mit.edu/courses/mathematics/18-440-probability-and-random-variables-spring-2011/lecture-notes/MIT18_440S11_Lecture20.pdf)指数分布的,因此这实际上与前面的代码片段非常相似。

在我给出的两种方法中,我认为第一种方法更好:

  • 第一个是O(len(到达)* log(len(费率)))而第二个是O(len(到达)* len(费率))
  • 第一个要求每个到达时来自基础发电机的2个随机数,而第二个要求每个到货时使用len(费率)随机数。
  • 第一个要求每次到达时对log进行1次评估(我假设这是指数随机变量的生成方式),而第二次要求每次到达日志的O(len(率))评估。

此外,将所有上述Python语法都带上了一点点(我还没有运行它,我对Python很生疏),如果你愿意,可以删除临时列表。这实际上是“伪代码”;对于快速的蒙特卡罗模拟,无论如何你都可能使用C ++(和/或CUDA)。

我知道你可能已经过了需要这个答案的地步,但我希望这对找到这篇文章的人有所帮助。