使用概率分布扩展整数的随机范围

Expand random range of integers using probability distribution

我试图解决生成 1 到 7 之间的随机整数的经典问题,给定一个生成 1 到 5 之间的随机整数的函数。 我的方法是将 2 次调用的结果添加到 rand5(),有效地将其转化为 "sum of dice rolls" 问题。骰子总和的概率很容易计算,所以我在这里使用它。对此的解释在代码

之后

我的问题是:如何计算计数器的值应该是多少?经实验验证,当前值不正确。是否存在满足概率的整数值?并且有没有更好的办法用这种方法来解决这个问题?

def rand5():
    return random.randint(1,5)

def rand7():
    counter = [1,2,3,4,5,4,3]
    while 0 not in counter:
        sum = rand5() + rand5() - 2
        if sum <= 6:
            counter[sum] -= 1
    return counter.index(0) + 1

作为参考,出现以下代码以创建随机分布。

test_counter = [0,0,0,0,0,0,0,0,0,0,0,0]
for i in range(500000):
    test_counter[rand5() + rand5() - 2] += 1

test_counter[0] *= 60
test_counter[1] *= 30
test_counter[2] *= 20
test_counter[3] *= 15
test_counter[4] *= 12
test_counter[5] *= 15
test_counter[6] *= 20
test_counter[7] *= 0
test_counter[8] *= 0

print(test_counter)

概率说明:可以通过列出可能的骰子组合来计算掷骰子的概率。对于这个问题,每个 die(rand5 函数)生成的数字将是:

{(1,1), (1,2), (1,3), (1,4), (1,5), (2,1), (2,2), .. ., (5,5)}

每个和的概率是该和在列表中出现的方式数除以列表中的项目总数。该列表总共有 5^2 = 25 个元素。例如和为4可以通过以下组合{(1,3), (2,2), (3,1)},所以和为4的概率是3/25.

则每个结果的概率为:

  1. 1/25
  2. 2/25
  3. 3/25
  4. 4/25
  5. 5/25
  6. 4/25
  7. 3/25
  8. 2/25
  9. 1/25

我尝试使用此分布来生成统一分布,方法是必须多次生成更常见的分布,并将其存储在计数器中。

不确定通过骰子分配是个好主意。通常,如果您有随机位源,但序列较短,则最好将位组合并切碎以组成更长的随机位序列。沿线

import random

def rand5():
    return random.randint(1, 5)

def twobits():
    q = rand5() - 1 # [0...5) range
    while q == 4: # dropping high bit
        q = rand5() - 1
    return q # [0...3) range, two random bits

def onebit():
    return twobits() & 1

def rand7():
    q = onebit() << 2 | twobits() # here we have [0...8) range
    while q == 0:                 # and dropping 0
        q = onebit() << 2 | twobits()
    return q

counter = 8*[0]

for i in range(500000):
    counter[rand7()] += 1

print(counter)

在 [1...8) 抽样中生产制服

[0, 71592, 71352, 71071, 71543, 71600, 71388, 71454]

从一个样本中取出两位,从另一个样本中取出一位,将它们组合起来,一些拒绝,瞧!