沿概率分布生成随机数的模块
random-gen的Python项目详细描述
随机发电机
一种随机数生成器,它将从给定的输入列表和概率分布中随机生成数字。 E、 g
>>fromrandom_genimportRandomGen>>>>r=RandomGen((1,2,3),(0.5,0.1,0.4))# input number list, probability distribution>>generated_numbers=[r.next_num()for_inrange(0,11)]>>>>importcollections>>collections.Counter(generated_numbers)# See distribution of numbers generatedCounter({1:7,2:1,3:3})
如您所见,数字的分布与传递给RandomGen的概率分布大致一致。 这个实现来自cpython随机选择()-https://github.com/python/cpython/blob/master/Lib/random.py#L397 并针对已知累积重量和k进行了优化
这是通过使用随机数列表的累积概率来实现的。随机产生的概率(使用random.random
)
乘以概率总和。然后将这个概率插入到累积的列表中
使用bisect.bisect
和用于返回相对随机数的插入位置的概率(来自输入random_nums
)。
因为概率是沿着概率分布成比例的(因为它乘以
它更有可能返回概率更大的数字。在
先决条件
- Python 3.6
跑步
^{pr2}$测试
- 运行测试:
pytest tests/test_random_gen.py
如何让RandomGen更“Python”
我们可以将标准Python Generator
类的子类化,并使用dunder方法提供next_num
__next__
或者简单地提供一个称为random_gen
的生成器函数,该函数在调用时生成每个结果。
如果用例少于10000个,我还建议直接使用random.choices
,而不是包装在一个类中
输入(否则性能会受到影响)。这将更简单,更易读。在
性能
# input numbers provided | # output numbers generated | speed (secs) | function calls | memory consumption for next_num (mb) |
---|---|---|---|---|
100 | 100 | 0.005 | 304 | 11 |
1000 | 1000 | 0.002 | 3004 | 11 |
10000 | 10000 | 0.018 | 30004 | 12.4 |
100000 | 100000 | 0.172 | 300004 | 33 |
100000 | 1000000 | 1.95 | 3000004 | 199 |
进一步优化
- 内存消耗需要调查。有没有其他有效的方法来分割累积概率阵列 不用单子?在
- 阵列/在需要时为大组数字提供高效存储。在
- 研究平分的性能。在
- 项目
标签: