我正在使用一种方法来创建两个带有随机数的新int
数组,
但是这两个数组包含完全相同的数字。为什么会这样?
static void Main(string[] args)
{
int[] Foo1= Foo(1000);
int[] Foo2= Foo(1000);
}
static int[] Foo(int length)
{
int[] Array = new int[length];
Random r = new Random();
for (int i = 0; i < length; i++)
{
Array[i]=r.Next(1, 101);
}
//Thread.Sleep(6);
return Array;
}
答案 0 :(得分:6)
你不是seeding Random但你可能在调用之间使用它足够接近默认种子在两种情况下相同:
默认种子值派生自 系统时钟并且有限 解析度。结果,不同 在中创建的随机对象 通过致电来接近接班人 默认构造函数将具有 相同的默认种子值, 因此,将产生相同的集合 随机数。这个问题可以 通过使用单个随机避免 对象生成所有随机数。 你也可以解决它 修改返回的种子值 系统时钟然后明确 为这个新的种子价值提供 随机(Int32)构造函数。更多 信息,请参阅随机(Int32) 构造
答案 1 :(得分:5)
这是因为你的随机数被初始化了两次,时间差太小而没有种子。
试试这个:
static void Main(string[] args)
{
Random r = new Random();
int[] Foo1= Foo(1000,r);
int[] Foo2= Foo(1000,r);
}
static int[] Foo(int length, Random r)
{
int[] Array = new int[length];
for (int i = 0; i < length; i++)
{
Array[i]=r.Next(1, 101);
}
//Thread.Sleep(6);
return Array;
}
答案 2 :(得分:5)
“你正在使用具有相同种子的两个Random实例”的其他答案是正确的。但是,他们曾经使用静态变量来引用Random
的实例。如果您尝试从多个线程使用它,这可能会导致问题,因为Random
不是线程安全的。
有各种解决方法(例如为每个线程创建一个Random
实例,使用静态方法安全地访问它) - 我写了quite a long article on this topic,你可能会发现它很有用。< / p>
答案 3 :(得分:3)
这是因为Random类不是真正的随机数,而是伪随机数。因此,每次在短时间内初始化新的Random
实例时,它将再次以相同的数字开头。如果时间跨度越大,你就会有不同的种子,所以它会起作用。我建议在Random
中声明Main
个实例并将其交给Foo
方法,所以它看起来像这样:
static void Main(string[] args)
{
Random r = new Random();
int[] Foo1= Foo(1000, r);
int[] Foo2= Foo(1000, r);
}
static int[] Foo(int length, Random r)
{
int[] Array = new int[length];
for (int i = 0; i < length; i++)
{
Array[i]=r.Next(1, 101);
}
//Thread.Sleep(6);
return Array;
}
编辑:我在Jon Skeet的建议之后修改了上面的代码。现在他提到的问题应该消失了。
答案 4 :(得分:3)
您可以使用全局Random
对象,也可以使用像
new Random(Guid.NewGuid().GetHashCode());
答案 5 :(得分:1)
因为你使用的是几乎相同的种子。尝试在该方法之外移动Random r = new Random();
。