随机选择0或1相同的次数?

4
我想迭代100个值并随机选择0或1,但最终得到相等数量的0和1。
下面的代码打印计数:
import random
c_true = 0
c_false = 0

for i in range(100):
    a = random.getrandbits(1)
    if a == 1:
        c_true += 1
    else:
        c_false += 1

print "true_count:",c_true
print "false_count:",c_false

输出结果为:
true_count: 56
false_count: 44

我希望计数相等

true_count: 50
false_count: 50

我该如何修改代码才能获得所需的结果?

3个回答

8
  1. Create numbers with 50 0's and 50 1's,

    >>> numbers = [0, 1] * 50
    
  2. Import shuffle from random

    >>> from random import shuffle
    
  3. shuffle them

    >>> shuffle(numbers)
    

注意:shuffle会就地打乱列表,因此numbers现在已经被打乱了。


1
这里有一个基于生成器的解决方案,使用O(1)内存:
import random

def gen_boolean_seq(true_count, false_count):
   while true_count or false_count:
      val = (random.random() >= false_count / float(true_count + false_count))
      if val:
         true_count -= 1
      else:
         false_count -= 1
      yield val

print sum(gen_boolean_seq(50, 50))

4
虽然这个方案符合原帖的限制,所以给它点赞👍,但它并不能对所有可能的序列进行均匀分布,因此在某些情况下可能不太合适。 - DSM
@DSM:这让我想知道是否有已知的O(1)算法可以在所有序列上给出均匀分布? - NPE
2
我认为使用(random.random() >= 1.0*false_count / (true_count+false_count))就足够了。 - DSM
@DSM:看起来是这样(通过我刚做的一些蒙特卡罗模拟来验证)。谢谢。 - NPE

-1

好吧,那就不是真正的随机了,但如果你想得到50个1和50个0,那么可以根据剩余可用空间的权重进行加权。例如,在40个1和45个0的情况下,0的概率应为5/15,而1的概率应为10/15。


这是一个有偏差的算法,因为它很可能会在结尾生成一长串0或1。我最初认为它也是不确定性的,但在50个零或一个后,生成另一个值的几率将达到100%,所以这不是情况。 - Maarten Bodewes
是的,它是基于剩下的内容而偏向某一方面,这就是为什么它不是随机的原因。如果你有一个装有100个球(50个1和50个0)的篮子,那么它在现实世界中的工作方式就是这样。你不能真正要求完全没有偏见的随机性,但是又添加一个前提条件,即结果应该分成50%。这两件事是不兼容的。我相信这个问题的所有3个答案在逻辑上都是相同的。 - Phil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接