按Zipf分布生成随机数

17

最近的一篇论文(Maurizio Naldi,2015)提出了一种近似算法,其中包含一个参数,可以权衡时间和准确性。对于合理范围内的alpha值(0 <= alpha <= 2),误差从未超过0.1%。请参见https://arxiv.org/pdf/1511.01480.pdf。 - Paul Chernoch
5个回答

12
这是一个Python的Zipf分布生成器,用于生成具有参数alpha >= 0n个项目:
import random 
import bisect 
import math 

class ZipfGenerator: 

    def __init__(self, n, alpha): 
        # Calculate Zeta values from 1 to n: 
        tmp = [1. / (math.pow(float(i), alpha)) for i in range(1, n+1)] 
        zeta = reduce(lambda sums, x: sums + [sums[-1] + x], tmp, [0]) 

        # Store the translation map: 
        self.distMap = [x / zeta[-1] for x in zeta] 

    def next(self): 
        # Take a uniform 0-1 pseudo-random value: 
        u = random.random()  

        # Translate the Zipf variable: 
        return bisect.bisect(self.distMap, u) - 1

2
非常好的答案。对于Python 3.x,请添加“from functools import *”。 - Daniel Lemire
1
或者,from functools import reduce - Michael Mior
self.distMap = [math.pow(float(x), alpha) / zeta[-1] for x in zeta] 自我.distMap = [math.pow(float(x), alpha) / zeta[-1] for x in zeta] - xunzhang

11

对于VGAM加1。它的“dzipf”函数将为您提供每个等级的概率列表,您可以使用它来生成项目访问。 - Mihai Capotă

10

7
很不幸,它使用黎曼ζ函数,因此只适用于指数大于1的情况,而许多P2P人口最好采用指数小于1的模型。 - Mihai Capotă

4
最近为Apache Commons Math库的下一个版本(>= 3.6)开发了一种非常高效的算法来生成Zipf分布的随机变量(请参见此处的代码here)。它使用拒绝-反转采样,也适用于小于1的指数。它不需要预先计算CDF并将其保存在内存中。此外,生成一个样本的成本是恒定的,不会随着项目数量的增加而增加。

0
我们正在讨论这个帖子中@stanga的答案。对于他的算法,有一些不错的优化建议。

目前这几乎不能算作一个答案。你应该在这里包含你的解决方案,而不仅仅是提到它。 - Peter O.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接