我挠了头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();
此代码返回预期结果
答案 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
仅适用于您的过程一次,否则您将获得不稳定的结果。