我有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个列表然后合并它们但是我希望首先以正确的顺序输出到达时间。
更新。一个问题是,如果您只是从每个流程中抽取固定数量的到达次数,那么您只能从高流量流程中获得早期时间。所以我认为我需要从每个过程的固定时间间隔进行采样,因此样本数量会根据速率而变化。
答案 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)指数分布的,因此这实际上与前面的代码片段非常相似。
在我给出的两种方法中,我认为第一种方法更好:
此外,将所有上述Python语法都带上了一点点(我还没有运行它,我对Python很生疏),如果你愿意,可以删除临时列表。这实际上是“伪代码”;对于快速的蒙特卡罗模拟,无论如何你都可能使用C ++(和/或CUDA)。
我知道你可能已经过了需要这个答案的地步,但我希望这对找到这篇文章的人有所帮助。