2

显然,我实际上是想创建一个在许多试验(5000)中随机分配生日的数组。然后假设每次至少有 2 个生日为 2 - 50 人计数,并将结果除以 5,000 以获得近似概率。我相信我的循环搞砸了,希望得到一些反馈。不是代码,我想确切地了解出了什么问题以及我是如何搞砸的。

int main()
{
    const int trials(5000);
    double total;
    int count(0), birthdays[49];

    srand(time(NULL));

    for (int i = 2; i <= 50; i++)
    {
        for (int k = 0; k < trials; k++)
        {
            fillUp(birthdays, 49);
            for (int j = i + 1; j <= 50; j++)
            {
                if (birthdays[i] == birthdays[j])
                {
                    count += 1;
                }
            }
        }
        total = count / 5000.0;
        cout << "For " << i << " the probability is " << total << endl;
    }
    return 0;
}

void fillUp(int birthdays [], int size)
{
    for (int i = 0; i < size; i++)
    {
        birthdays[i] = rand() % 365 + 1;
    }
}

输出:

For 2 the probability is 0.1286
For 3 the probability is 0.2604
...
...
For 49 the probability is 3.9424
For 50 the probability is 3.9424

任何帮助将非常感激。

4

4 回答 4

2

问题不在于 C++ 代码。你只是在你的数学中有一个错字。它应该是:

power = (num * (num - 1.0) / 2.0);
chance = 1.0 - pow(constant, power);
于 2013-09-16T02:58:44.697 回答
1

您可能知道公式,但您的代码没有正确实现它。下面是一些正确实现公式的 C 代码:

#include <stdio.h>

int main(void) {
  double p;
  int ii;
  int people;
  for (people = 3; people < 50; people++) {
    p = 1;
    for (ii = 1; ii < people; ii++) {
      p *= (365.0 - ii) / 365.0;
    }
    printf("for %d people, probability is %.4f\n", people, 1 - p);
  }
  return 0;
}

这将产生以下输出:

for 1 people, probability is 0.0000
for 2 people, probability is 0.0027
for 3 people, probability is 0.0082
for 4 people, probability is 0.0164
for 5 people, probability is 0.0271
for 6 people, probability is 0.0405
for 7 people, probability is 0.0562
for 8 people, probability is 0.0743
for 9 people, probability is 0.0946
for 10 people, probability is 0.1169
for 11 people, probability is 0.1411
for 12 people, probability is 0.1670
for 13 people, probability is 0.1944
for 14 people, probability is 0.2231
for 15 people, probability is 0.2529
for 16 people, probability is 0.2836
for 17 people, probability is 0.3150
for 18 people, probability is 0.3469
for 19 people, probability is 0.3791
for 20 people, probability is 0.4114
for 21 people, probability is 0.4437
for 22 people, probability is 0.4757
for 23 people, probability is 0.5073
for 24 people, probability is 0.5383
for 25 people, probability is 0.5687
for 26 people, probability is 0.5982
for 27 people, probability is 0.6269
for 28 people, probability is 0.6545
for 29 people, probability is 0.6810

导致熟悉的结果“只有 23 人的机会 > 50%”。

于 2013-09-16T02:56:25.580 回答
1

您正在计算 364/365 ≈ 0.0027 的某个大数的幂,这导致一个数字仅略高于零。当四舍五入到要求的输出精度时,结果为零。

于 2013-09-16T02:57:43.770 回答
0

本质上,您创建了一个新问题,所以我将创建一个新答案。现在,您在循环遍历生日时不断更改生日;这就是为什么事情不起作用的原因。您需要两个嵌套循环来测试相同的生日(或者如果您很聪明,您可以对它们进行排序,然后只检查相邻的。n = 50 可能更快。)

您还需要在第一个生日时开始测试(您的数组以 0 为基数 - 但您从 i = 2 开始)。对于每次试验,您都可以看到在比赛之前需要比较多少人。正确的代码看起来像这样(请注意,我为房间中的每个人数运行 5000 次试验;当您有 3、4、5 人时,您可以通过检查匹配来提高效率......样本,但随后在抽样中会有一些相关性)。

已编辑- 测试了这段代码,似乎可以编译并运行正常。结果看起来接近预期值。

#include <iostream>

void fillUp(int birthdays [], int size)
{
    for (int i = 0; i < size; i++)
    {
        birthdays[i] = rand() % 365 + 1;
    }
}

int main(void) {
int birthdays[50];
int trials = 5000;
int flag;
double total;
int collisions[50];
   // number of people "in the room"
   for (int i = 2; i < 50; i++)
      {
      collisions[i] = 0;
      // do 5000 trials:
      for (int t = 0; t < trials; t++)
       {
        fillUp(birthdays, i);
        flag = 0;
        // compare all pairs (j,k):
        for (int j = 0; j < i - 1 && flag == 0; j++)
        {
          for (int k = j + 1; k < i && flag == 0; k++ )
          {
            if (birthdays[k] == birthdays[j])
            {
              collisions[i]++;
              flag = 1;
            }
          }
        }
      }
    total = collisions[i] / 5000.0;
    std::cout << "For " << i << " people in the room the probability is " << total << std::endl;
    }
return 0;
}

注意 - 我没有机会编译/测试它;“本质上”应该是正确的。让我知道它是否有问题。

于 2013-09-18T20:37:53.180 回答