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

Posted

技术标签:

【中文标题】使用概率分布扩展整数的随机范围【英文标题】:Expand random range of integers using probability distribution 【发布时间】:2019-05-18 07:02:48 【问题描述】:

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

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

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/25 2/25 3/25 4/25 5/25 4/25 3/25 2/25 1/25

我试图通过多次生成更常见的分布来生成均匀分布,并将其存储在计数器中。

【问题讨论】:

澄清一下,这不是作业问题。在查找“正确”解决方案之前,我只是想尝试自己解决这个问题。 如果你能解释一下它背后的理论,那就太好了,只是为了让其他读者更清楚这个问题。 【参考方案1】:

不确定通过骰子分发是个好主意。一般来说,如果你有随机比特源,但序列很短,最好组合和切割比特来组成更长的随机比特序列。顺势而为

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]

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

【讨论】:

很有趣,但你的程序可能永远不会结束,因为 while 循环依赖于随机条件。我的意思是没有正式的证据表明你的程序会结束,所以这不是算法。正如***所说,“通常,如果程序最终停止,它只是一种算法”(en.m.wikipedia.org/w/…) @AlexandreFenyo 嗯?!?你是说en.wikipedia.org/wiki/Metropolis%E2%80%93Hastings_algorithm 不是算法吗?整个马尔可夫链抽样?高斯的 Box-Muller?我认为你错了 这是一个词汇问题:我理解你不同意 Knuth 对算法的描述(“算法必须总是在有限的步数之后终止......一个非常有限的数字,一个合理的数字”)和与斯通对算法的描述(“我们将算法定义为一组规则,这些规则精确地定义了一系列操作 [...] 使得该序列在有限时间内终止”)。算法有许多不同的特征。这就是***写“一般”的原因。或者你的意思是你的程序/算法在有限的时间内终止? @AlexandreFenyo Or do you mean your program/algorithm terminates in a finite time? Lebesgue 测度为零的不终止概率。 程序的迭代次数没有绝对上限(具有 null 度量的集合可能不为空,在这种特定情况下,它不为空)。我想知道您的答案是否是可以表达的最佳答案,或者是否存在其他一些对迭代次数有绝对上限的正确答案。我不知道如何证明这一点,但我怀疑迭代次数没有绝对上限的有效答案。你认为这样的算法是否存在,或者你认为你的答案是最初问题的最佳答案?

以上是关于使用概率分布扩展整数的随机范围的主要内容,如果未能解决你的问题,请参考以下文章

第三部分 概率_2 一维随机变量的分布

第三部分 概率_3 多维随机变量的分布

随机变量及其分布

统计学入门级:常见概率分布+python绘制分布图

如何理解概率分布的分位数和上侧分位数?

联合概率分布怎么做?