随机数生成器在循环内运行时始终选择相同的值

问题描述 投票:4回答:5

代码的问题是,当我尝试生成一个数字时,如果自旋等于1,它会在范围(1,2,3)内生成值,如果尝试使用循环对相同范围内的随机值进行求和则随机在循环中,数字gerated始终相同,

例如,如果我使用:spind3 = 4运行循环,则值从4,8,12 spind3 = 5开始,值从5,10,15开始

这意味着RandomNumber第一次在循环内生成一个值,它永远不会改变,直到循环完成。

if (toggled3.Checked)
   {
    if (spind3.Value != 1)
        {           
         for (int i = 1; i <= spind3.Value; i++)
              {
               diceCalc[1] += RandomNumber(1, 4);
              }
        }
     else
     diceCalc[1] = RandomNumber(1, 4);
     }
c# random for-loop
5个回答
26
投票

您可能正在Random方法中创建一个新的RandomNumber对象。 default constructorRandom使用系统时间作为种子。如果在紧密循环中创建多个Random对象,则每次调用之间的时间可能不会发生变化,因此它们将使用相同的种子进行初始化。

要修复代码,您应该只创建一个Random对象并重用它。


来自documentation

默认种子值源自系统时钟并具有有限的分辨率。因此,通过调用默认构造函数紧密连续创建的不同Random对象将具有相同的默认种子值,因此将生成相同的随机数集。使用单个Random对象生成所有随机数可以避免此问题。您还可以通过修改系统时钟返回的种子值,然后将此新种子值显式提供给Random(Int32)构造函数来解决此问题。有关更多信息,请参阅Random(Int32)构造函数。


5
投票

问题是你在时间上创建的随机生成器太近了。随机生成器构造函数使用当前时间为生成器播种,当您创建它们的时间太近时,它们将全部使用相同的时间播种。

创建一个随机生成器并在循环中使用:

Random rnd = new Random();
for (int i = 1; i <= spind3.Value; i++) {
  diceCalc[1] += rnd.Next(1, 4);
}

1
投票

您需要初始化Random对象,然后在循环中调用Next()。

if (toggled3.Checked)
{
  // initialize your total and the random number generator
  int diceTotal = 0;
  Random rand = new Random();

  for (int i = 0; i < spind3.Value; i++)
  {
    // add the next random number between 1 and 3
    diceTotal += rand.Next(1, 4); 
  }
}

1
投票

你可以使用Random(seed)构造函数。

Random rand = new Random(Guid.NewGuid().GetHashCode());

0
投票

一个技巧是通过将DateTime.Now.Ticks添加到变量i来手动创建种子:

Random r = new Random((int)DateTime.Now.Ticks + i);
© www.soinside.com 2019 - 2024. All rights reserved.