创建一个使用另一个随机函数作为种子生成随机数的函数

时间:2016-01-05 09:15:33

标签: algorithm probability

你有一个函数f1()以相等的概率生成0或1。编写一个函数f200(),使用f1()生成介于1到200之间(包括两者)的数字。

有人建议采用以下方法:投掷硬币并根据结果确定数字是否超过一半或少于一半。每半个递归一次。选择一半是以2的幂完成的。

选择2的权力的原因是我们可以实现所有数字吗?

import random as rd 

def prob200(half):
    if half >= 200:
        return 0    
    #f1 can be replaced by this rd.randint(0, 1)
    toss_value = f1() 
    # check if toss falls in this current half and then change the half for next recursion. 
    # we change half from 1, 2, 4, 8, 16, 36, 64, 128
    result = toss_value*half + prob200(half<<1)
    if result > 200:
        return prob200(1)
    else:
        return result

for i in range(0, 10):
    print(prob200(1))

3 个答案:

答案 0 :(得分:1)

使用随机位生成器创建一个带有n位的数字x(例如n = 32或更高,如果需要更高的精度=更均匀的分布),您可以将其转换为所需的范围r(例如r = 200),如下所示:result = floor(x / 2 ^ n * r)+1

例如,如果使用n = 8,则使用随机位生成器(函数f1)生成一个8位数,该生成器的范围为0-255(含)。然后你将它除以2 ^ 8 = 256,所以我们将得到一个0到255/256之间的数字。然后我们乘以200,所以我们将得到0到199.2之间的结果。最后,我们将其向下舍入并添加1以获得1到200之间的数字。

但是因为我们只使用了8个randoms位(n = 8),所以unifrmity并不是那么好。我们有效地生成了0-255(源范围)的数字,并将其转换为1-200(目标范围)的数字。目标范围中的大多数数字在源范围中具有一个对应的数字,但是其他数字(例如数字1)具有两个对应的源编号(0和1)。因此,有些数字的概率为1/256,而其他数字的概率为2/256。

为了改善这一点,我们可以使用n = 16,然后概率差异最多为1/2 ^ 16。

这是一个首先尝试使用8位生成随机数的程序,但如果它溢出4次,则会使用我描述的方法生成32位数并将其转换为输出范围:

import math
import random

def f1():
  return random.randint(0,1)

def rand_by_bits(n):
  v=0
  for i in range(n):
    v=(v<<1)+f1()
  return v

def rand_by_range(r):
  n=0
  t=r
  while t>0:
    t>>=1
    n+=1

  for i in range(4):
    v=rand_by_bits(n)
    if v<r:
      break

  if v>=r:
    n=32
    v=math.floor(float(rand_by_bits(n))/(1<<n)*r)

  return v+1

def main():
  random.seed()
  print(rand_by_range(200))

答案 1 :(得分:0)

非常简短的答案

选择2的幂来均匀分布生成的随机数。

更长的答案

让我们首先明确一个数字是2的幂是否无关紧要。我们总能“实现所有数字”。

每次你有2个半数时,你有相同的概率选择一半(因为 f1()生成0或1,概率相等)。这显然意味着我们不会选择2个中的一半,因此我们总能实现所有数字

现在问题是为什么那么我应该选择2的力量?
我会回答说,如果你不选择2的幂,那么你会得到随机数,但概率不等

该案例的一个简短例子应该清楚,我在这里: 让我们假设你必须生成1到3范围内的数字。现在,当你将它的一半时,你将它切成1 2。 3或1 | 2 3.让我们说你做的就像1 | 2 3.
因此,选择1的概率将变为1/2 = 0.5,选择2或3的概率将变为1/2 * 1/2 = 0.25

问题的根源在于,当大小范围不等于2的幂时,将该范围(1到3分成1 | 2 3)分成2组。你得到2组不等的大小(组1的大小为1,组2的大小为2)。这种群体规模的变化将导致这些群体中数字选择概率的变化。

但是如果数字的幂为2,则可以保证您将始终获得相同大小的组。所以,它总会给你一个概率相等的随机数。

Q.E.D。

答案 2 :(得分:-1)

这是我怎么做的。 给定f(0,1),您可以为任何x生成随机数f(0,2 ^ x - 1)。 对于n = 200,生成函数f(0,255)。 然后r = f(0,255),如果r < 200返回r。 否则,重新运行算法,例如重新生成r直到r小于200.