📜  拼图 |启示录

📅  最后修改于: 2022-05-13 01:56:06.988000             🧑  作者: Mango

拼图 |启示录

谜:
在后世界末日的新世界中,世界女王非常关心出生率。因此,她下令所有家庭都应该确保他们有一个女孩,否则他们将面临巨额罚款。如果所有家庭都遵守这个政策——也就是继续生孩子,直到生了一个女孩,然后立即停止——新一代的性别比例会是多少? (假设某人在任何给定怀孕期间生男孩或女孩的几率是相等的。)从逻辑上解决这个问题,然后编写一个计算机模拟它。

提示:

  1. 请注意,每个家庭都会有一个女孩。
  2. 考虑将每个家庭写成 B 和 G 的序列。

解决方案

  • 如果每个家庭都遵守这个政策,那么每个家庭都会有零个或多个男孩后面跟着一个女孩的序列。
  • 也就是说,如果“G”表示女孩,“B”表示男孩,则孩子的序列看起来像 G 中的一个; BG;步步高; BBBG; BBBBG;等等。

数学上

  • 它可以计算出每个性别序列的概率。
    1. P(G) = 1/2-
      也就是说,50%的家庭会先生一个女孩。其他人将继续生更多的孩子。
    2. P(BG) = 1/4-
      在生二胎的人中(占 50%),其中 50% 的人下次会生女孩。
    3. P(BBG) = 1/8-
      在有第三个孩子的人中(占 25%),其中 50% 的人下次会生一个女孩。等等。
  • 假设每个家庭只有一个女孩。
  • 每个家庭平均有几个男孩?为了计算这个,让我们看一下男孩数量的期望值。
  • 男孩数量的期望值是每个序列的概率乘以该序列中男孩的数量。

下表说明了男孩人数的期望值:

SequenceNo of boysProbabilityNo of boys * Probability
G       0    1/2                 0
BG       1    1/4               1/4
BBG       2    1/8               2/8
BBBG       3    1/16              3/16
BBBBG       4    1/32              4/32
BBBBBG       5    1/64              5/64
BBBBBBG       6    1/128             6/128

  • 或者换句话说,这是 i 到 i 的无穷大除以 2 i的总和。

逻辑上

  • 考虑这一点的一种方法是想象我们将每个家庭的所有性别序列放入一个巨大的字符串中。所以如果家族 1 有 BG,家族 2 有 BBG,家族 3 有 G,那就是 BGBBGG。
  • 孩子一出生,就可以将其性别(B 或 G)附加到字符串中。
  • 下一个字符是 G 的几率是多少?好吧,如果生男孩和女孩的几率相同,那么下一个字符是 G 的几率是 50%。
  • 因此,大约一半的字符串应该是 Gs,一半应该是 Bs,从而给出一个均匀的性别比例。
  • 这实际上很有意义。生物学没有改变。
  • 新生婴儿中有一半是女孩,一半是男孩。
  • 遵守一些关于何时停止生育的规则并不能改变这一事实。
  • 因此,性别比例为 50% 的女孩和 50% 的男孩。

下面是计算家庭中有女孩的概率的伪代码-

double r unNFamilies (int n) 
{
    int boys = 0;
    int girls = 0;
    for (int i = 0; i < n; i++) 
    {
        int [] genders = runOneFamilY();
        girls += genders[0];
        boys += genders[1];
    }
    return girls / (double) (boys + girls);
}

int[] runOneFamily() 
{
    Random random = new Random();
    int boys = 0;
    int girls = 0;
    while (girls == 6) 
    {    
        // until we have a girl
        if (random.nextBoolean ()) 
        {    
            // girl
            girls += 1;
        } 
        else
        {  
            // boy
            boys += 1;
        }
    }
    int[] genders = {girls, boys};
    return genders;
}

如果这个伪代码在 n 的大值上执行,那么结果将非常接近 0.5。