从数组中选择特定数字的概率

时间:2014-11-26 19:37:49

标签: c# .net math probability

我挠了头2天,无法弄清楚我的代码有什么问题。让我们说我有2个阵列:

Array1[33]: 0..31 (it has 2 fives)
Array2[32]: 0..31 (it has one five)

现在我想计算从第一个数组中随机选取5的概率和从第二个数组中随机选择5的概率。我用这个公式做到了这一点:

(2M / 33) * (1M / 32)

大致是0.001894。现在,如果我运行的周期足够长,比如1000,000,0我应该期待' 5' ' 5'大约18940次,但是当我运行测试时,这不会发生。这是代码:

public class Program
{
    private static List<int> numbers1 = new List<int>();
    static Random random = new Random(Guid.NewGuid().GetHashCode());
    private static List<int> numbers2 = new List<int>();

    static void Main(string[] args)
    {
        for (int i = 0; i < 33; i++)
        {
            numbers1.Add(i);
            numbers2.Add(i);
        }

        numbers1.Add(5);

        while (true)
        {
            var counter = 0;
            for (int i = 0; i < 10000000; i++)
            {
                var num1 = numbers1[random.Next(0, 33)];
                var num2 = numbers2[random.Next(0, 32)];

                if (num1 == 5 && num2 == 5) counter++;
            }

            Console.Write(counter + ": " + (decimal) counter / 10000000 + " - " + (2M / 33) * (1M / 32));
            Console.ReadLine();
        }
    }
}

模式&#39; 5&#39; &#39; 5&#39;它应该出现在9300-9500次,而它应该出现两次。

所以我的问题是,我的数学/代码出了什么问题?

由于

编辑:

请注意,如果我在第一个数组中只留下五个,那么一切都按预期工作。

    //numbers1.Add(5);

    while (true)
    {
        var counter = 0;
        for (int i = 0; i < 10000000; i++)
        {
            var num1 = numbers1[random.Next(0, 33)];
            var num2 = numbers2[random.Next(0, 32)];

            if (num1 == 5 && num2 == 5) counter++;
        }

        Console.Write(counter + ": " + (decimal) counter / 10000000 + " - " + (1M / 33) * (1M / 32));
        Console.ReadLine();

此代码返回预期结果

3 个答案:

答案 0 :(得分:5)

解决方案非常简单:您向阵列添加了太多元素。

for (int i = 0; i < 33; i++)
{
    numbers1.Add(i);
    numbers2.Add(i);
}

33 元素添加到数组而不是32。

Random.Next(a, b)生成[a, b)(半开区间)之间的随机数。因此random.Next(0, 33)将生成0到32之间的数字(包括0和32)。您添加到numbers1的附加5将永远不会被检索,因为它在索引33处。

在创建数据时如此简单地将33更改为32,它将起作用。

答案 1 :(得分:3)

好吧,看看代码我也没有看到它。打开调试器并检查一些我注意到的事情:

numbers1.Count == 34

您认为它是33。双五是最后一个元素。它从未被绘制过。

这就是为什么你不应该写random.Next(0, 33)中的幻数。请改用random.Next(0, numbers1.Count)。这也适用于代码中的其他内容。重复的常量是容易出错的位置。

答案 2 :(得分:0)

将您的语句var random = new Random(Guid.NewGuid().GetHashCode());移到while循环之外。

在非常接近的时间间隔内重复播种Random会产生偏差的结果。

种子Random仅适用于您的过程一次,否则您将获得不稳定的结果。