2013-03-08 156 views
24

我试图在随机发生器中获得1或2的50/50几率。如何在随机发生器中获得50/50的机会

例如:

Random random = new Random(); 
int num = random.nextInt(2)+1; 

此代码将输出为1或2

比方说,我在一个循环中运行它:

for (int i = 0; i < 100; i++) { 
    int num = random.nextInt(2)+1 ; 
} 

我怎样才能使发电机在这种情况下为1和2做一个相同的数字?

所以我想这个循环产生1号的50倍,号码2的50倍

+8

其他许多人已经注意到,你在这里感到困惑我认为:如果你抛硬币100次,你的*期望*是50头,任何0到100之间的数字都是可能的, 'http://en.wikipedia.org/wiki/Gambler's_fallacy – 2013-03-08 11:16:54

+1

实际上你的期望值不应该是50个头,而应该是45到55个头...... D:它只是50个头是最有可能的(发生这种情况的可能性大约为8%) – SinisterMJ 2013-03-08 13:00:21

+5

@AntonRoth,[no](https://en.wikipedia.org/wiki/Expected_value)。 – Rotsor 2013-03-08 16:41:18

回答

52

方式一:填补ArrayList<Integer>五十1的五十2的,然后调用它Collection.shuffle(...)

+1

假设@Sulaiman实际上只需要50个1和2个,这是但它只是指出实际的随机性已经消失了(这可能导致47 1和53 2或类似) – Mercurybullet 2013-03-08 02:28:58

+6

@Mercurybullet:我同意100%,按照惯例,确切的解决方案完全取决于他的要求 – 2013-03-08 02:38:26

+0

为什么这么难产生一个随机序列? – Mikhail 2013-03-12 08:40:58

18

您无法通过random实现此目的。如果您需要正是 50 1S和2S 50,你应该尝试这样的事:

int[] array = new int[100]; 
for (int i = 0; i < 50; ++i) 
array[i] = 1; 
for (int i = 50; i < 100; ++i) 
array[i] = 2; 

shuffle(array); // implement shuffling algorithm or use an already existing one 
+0

+1简单实用。 – armandino 2013-03-19 01:37:00

2

,这样得到一个一个的概率降低,你得到更多的人可以调整沿途的概率。这样,你并不总是有得到一个50%的机会,但你可以得到你所期望的结果(各占50的):因为它产生的数字递增所以

int onesLeft = 50; 

for(int i=0;i<100;i++) { 
    int totalLeft = 100 - i; 
    // we need a probability of onesLeft out of (totalLeft) 
    int r = random.nextInt(totalLeft); 
    int num; 
    if(r < onesLeft) { 
    num = 1; 
    onesLeft --; 
    } else { 
    num = 2; 
    } 
} 

这个拥有超过洗牌优势它不需要内存来存储数字。

+1

但分布不均匀,你最有可能走到尽头都是相同的数字。 – 2013-03-08 07:59:59

+0

@lechlukasz,我想过,但我似乎无法证明或反驳。你可以吗? – Rotsor 2013-03-08 16:29:30

+0

@lechlukasz,实验反驳你的说法。 – Rotsor 2013-03-08 16:38:43

12

50/50是很容易与Random.nextBoolean()

private final Random random = new Random(); 

private int next() { 
    if (random.nextBoolean()) { 
    return 1; 
    } else { 
    return 2; 
    } 
} 

测试运行:

final ListMultimap<Integer, Integer> histogram = LinkedListMultimap.create(2); 
for (int i = 0; i < 10000; i++) { 
    nal Integer result = Integer.valueOf(next()); 
    histogram.put(result, result); 
} 
for (final Integer key : histogram.keySet()) { 
    System.out.println(key + ": " + histogram.get(key).size()); 
} 

结果:

1: 5056 
2: 4944 
+7

他想要(根据我的理解)50 1s和50 2s **完全**。你发布的内容与他已有的内容相同。 – 2013-03-08 14:56:27

0

您已经成功创建了一个随机发生器,返回12等概率。作为(许多)其他人提到的,你的下一个请求,在100次试验中强制执行一次,并不符合随机数的生成。如https://math.stackexchange.com/questions/12348/probability-of-getting-50-heads-from-tossing-a-coin-100-times所示,发生的现实期望仅为8%左右。所以即使你可能在期望每个50,那确切结果实际上是相当罕见的。

大数定律表明,随着试验次数的增加,您应该关注期望值。

所以对于您的实际问题:在这种情况下,如何让发生器为1和2生成相同的数字?

我能想到的最好的(幽默)答案是:“在无限循环中运行它。“