无偏随机列表生成

时间:2018-05-15 13:26:41

标签: python-3.x random shuffle sampling

问题陈述

我需要模拟100 Prisoner Problem的过程,其中100号橱柜的每个抽屉包含0到99之间的唯一编号。我按如下方式初始化抽屉数量:

def arrange_event(n_prisoners=100):
    if (n_prisoners % 2) != 0 or n_prisoners <=0:
        raise ValueError("Number of prisoners must be a postive and even number.")
    drawer = list(range(n_prisoners))
    random.shuffle(drawer)
    return drawer

但我怀疑这种实现(例如从特定列表中移动)会在采样期间对某些特定模式产生偏差。需要正确实现列表初始化。对此实现中引入的偏差(如果存在)的任何解释也将有所帮助。

注意

我不是简单地询问如何使每个初始化随机化,关键是每个排列的概率应该等于在被驱逐的实现中,这与{{3完全不同}}。

这是我在this question中找到的内容,这表明使用random.shuffle()在我的实现中对排列的概率分布存在偏差。

  

random.shuffle(x [,random])

     

将序列x随机移动到位。可选参数random是一个0参数函数,在[0.0,1.0)中返回随机浮点数;默认情况下,这是函数random()。

     

注意,即使相当小的len(x),x的排列总数也大于大多数随机数生成器的周期;这意味着永远不会产生长序列的大多数排列。

1 个答案:

答案 0 :(得分:0)

我使用一种天真的方法使每个排列的概率相等,通过采样而无需替换,同时保持采样数量的顺序。实施如下:

def arrange_event(n_prisoners=100):
    if (n_prisoners % 2) != 0 or n_prisoners <=0:
        raise ValueError("Number of prisoners must be a postive and even number.")
    drawer = list(range(n_prisoners))
    for i in range(n_prisoners, 1, -1):
        random_index = random.choice(range(i))
        swap_a, swap_b = drawer[random_index], drawer[i-1]
        drawer[random_index], drawer[i-1] = swap_b, swap_a
    return drawer