使用自定义参数

时间:2018-10-18 17:33:41

标签: algorithm probability

我正在尝试解决以下问题:

我有一个函数以相等的概率= 0.5 生成0或1,并且我想使用前面的函数和基本的数学操作来实现另一个函数,该函数执行相同的操作但具有给定的概率< em> p ( 0 <= p <= 1

这不是我的作业或工作,我只是偶然发现而已,非常感谢任何提示!

2 个答案:

答案 0 :(得分:2)

这实际上与Patrick87提出的算法大致相同,但是它一次生成一位,并在找到答案后立即停止。它本质上与arithmetic encoding有关。

我已经在Python中实现了

>>> # Create a function which returns 0 or 1 with equal probability.
>>> from random import random
>>> f = lambda: int(random()<0.5)

>>> # Check
>>> sum(f() for i in range(1000000))
500251
>>> # Use that to create a biased function. You can use this
>>> # either with a rational number expressed as numerator, denominator
>>> # or with a value of p between 0 and 1. Python doesn't care whether
>>> # numbers are integers but other languages might.
>>> def biased(numer, denom = 1):
...    while True:
...      numer += numer
...      if numer >= denom:
...        numer -= denom
...        if f(): return 1
...      else:
...        if f(): return 0
... 
>>> sum(biased(0,19) for i in range(1900000))
0
>>> sum(biased(1,19) for i in range(1900000))
100096
>>> sum(biased(5,19) for i in range(1900000))
500255
>>> sum(biased(18,19) for i in range(1900000))
1799988
>>> sum(biased(19,19) for i in range(1900000))
1900000

实际上,该循环通过将分子的当前值加倍并与分母进行比较,一次一次构造分子/分母的二进制表示形式。然后将其与延迟生成的随机二进制分数进行比较,直到可以确定该随机分数是大于还是小于。

尽管从理论上讲,对基本函数f的调用次数是不受限制的,但是biased调用f的预期次数是2,无论偏向参数如何。 (这是因为随机的比特流匹配k二进制数字的概率为2 -k 与二进制数字的实际值无关。)

答案 1 :(得分:1)

在许多情况下应可行的简单解决方案如下:

  1. 用最少的术语将 p 解释为有理数 a / b 。如果 p 只是0到1之间的浮点数,则 b 只是10的幂,零和小数点后的位数一样多,而 a 是通过将小数点后的数字字符串除去前导零而形成的数字。
  2. 生成长度为 ceiling(log(b-1))的随机位字符串,其中对数的底数为2, ceiling 将所有非整数向上取整到下一个整数。为此,请调用提供的函数并记录答案。
  3. 如果不包括前导零的随机位字符串表示介于0到 b-1 (含)之间的整数,则继续;否则,如果该数字大于 b ,请返回到步骤2,生成随机位字符串,直到获得有效的字符串为止。
  4. 如果不包括前导零的随机位字符串表示介于0到 a-1 (含)之间的整数,则返回0;否则,返回0。否则返回1。

这应该在有限的预期时间内返回,但在最坏的情况下是无限制的,概率为 p = a / b 的数字0和概率为 p =(b-a )/ b ,确切地说,假设 p 是一个有理数(请注意,如步骤1中所述,双精度数都是有理数)。