随机不工作

时间:2012-01-18 22:59:04

标签: c# random

为了澄清,多个学生对象和所有对象都获得了相同的价值。

我知道之前已经问过这个问题,但我对其他关于他话题的帖子没有运气。我有一个1-3的随机数发生器。我然后我们%2使bool值为true或false。每次我运行程序时,我要么全部都是真的,要么都是假的。这是我的代码。我知道随机并不是随机的。我该怎么做才能获得更多的随机数字。

Random random = new Random();

public Student()
{
    int randomLevel=random.Next(1,3);
    level = (randomLevel % 2 == 0);
}

public bool readingLevel()//this always returns one value for the entire program.
{
    return level;
}

11 个答案:

答案 0 :(得分:7)

在构造函数中,您只是将一个随机值赋值给'level',因此它始终具有初始值。 试试:

public bool readingLevel()
{
     return (random.Next(1,3) % 2 == 0);
}

编辑:

Static Random random = new Random();
...

答案 1 :(得分:3)

  

看起来你正试图获得一个随机数!   Clippy

你可以尝试这样的事情:

static Random random = new Random();

public Student()
{
    lock (random)
    {
        int randomLevel=random.Next(1,3);
        level = (randomLevel % 2 == 0);
    }
}
public bool readingLevel()//this always returns one value for the entire program.
{
    return level;
}

您的代码段的问题似乎是您正在为每个类实例实例化一个新的Random类。 这不是应该使用Random的方式,而是应该使用单个 Random类实例来获取多个随机数。

基本原理是.Net中的Random使用基于状态(种子)的伪随机算法,每当您要求新的随机数时,该算法都会发生变化。通过在相对较短的时间跨度内实例化多个随机类,很有可能所有这些类都将使用相同的种子启动(基于系统时间),并且所有类都将提供相同的随机数。

答案 2 :(得分:3)

看起来您的随机生成器是Student的实例变量。由于生成器使用当前时间作为种子,如果您在短时间内创建了一堆学生,他们将拥有一个具有相同种子和相同结果的生成器。您可以使随机生成器成为静态变量,或者更好的是,使用构造函数注入并将该级别传递给Student的构造函数。

class Student
{
  private static Random random = new Random();

  public Student()
  {
    level = random.NextDouble() < 0.5;
  }

  public bool readingLevel()
  {
    return level;
  }
}

或使用constructor injection,因此您的学生班级是确定性的。

class Student
{
  private boolean level;

  public Student(boolean readingLevel)
  {
    this.level = readingLevel;
  }
  public boolean readingLevel()
  {
    return level;
  }
}

答案 3 :(得分:2)

public Student()
{
    int randomLevel=random.Next(1,3);
    level = (randomLevel % 2 == 0);
}

看起来非常像Student类的构造函数。在这个构造函数中,您基本上计算一个随机数并将其存储在level字段中。因此,如果您在整个程序中使用相同的Student实例并在此实例上多次调用readingLevel()方法,则显然会返回相同的值 - &gt;在构造此实例期间完成的并且存储在level字段中的那个。

因此,您可以考虑将随机数生成逻辑移到readingLevel()方法中,而不是简单地一遍又一遍地返回相同的值:

public class Student
{
    private Random random = new Random();

    public bool readingLevel()
    {
        int randomLevel = random.Next(1,3);
        return (randomLevel % 2 == 0);
    }
}

现在每次在同一个实例上调用此方法时,都应该得到一个随机数的新计算。

答案 4 :(得分:2)

仅创建Random的一个实例并重复使用它。在快速连续种子中创建多个随机种子实例到相同的值,从而产生相同的序列。

如果您的代码采用单线程,则只需使用静态属性来保存Random的实例。

  

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

http://msdn.microsoft.com/en-us/library/h343ddh9.aspx

答案 5 :(得分:1)

其他一些人已经这样说了,但我认为这一点值得用一个例子来强调。

public class Student
{
    Random random = new Random(); 

    public Student() 
    { 
        int randomLevel=random.Next(1,3); 
        level = (randomLevel % 2 == 0); 
    } 

    public bool readingLevel()//this always returns one value for the entire program. 
    { 
        return level; 
    } 
}

public class Program
{
    public static void Main()
    {
        var students = new List<Student>();
        for (int i = 0; i < 10; i++)
            students.Add(new Student());

        //Now you have 10 Students; each Student has its own random number generator
        //The generators were created within microseconds of each other, so they most likely have THE SAME SEED
        //Because they have the same seed, they will generate identical sequences of numbers
        //Each student's reading level is calculated from the first call to .Next(1, 3) on its own RNG.
        //The RNGs have the same seed, so each will return the same value for the first call to .Next(1, 3)
        //Therefore, all students will have the same reading level!
    }
}

答案 6 :(得分:0)

您正在使用随机模拟真/假情况,因此您试图将结果限制为1或2.鉴于您正在对结果进行奇数/偶数测试,您可能会做得更好:< / p>

int randomLevel = random.Next();
level = (randomLevel % 2 == 0);

此外,如果您快速连续创建所有学生,那么您当前的代码很可能会为后续调用返回相同的值。

答案 7 :(得分:0)

好。

考虑一下这里发生了什么。构造Student后,会得到一些随机数,然后将其设置为成员变量level

然后,在某个其他方面,您调用一个函数readingLevel,该函数返回此先前设置的值。

然后,你可能会思考自己:这个函数究竟何时给出不同的值?好吧,只有当level获得不同的值时才会这样做。那什么时候发生的?好吧,它只发生在构造函数中,所以,这意味着它永远不会再发生在对象的生命周期中....

答案 8 :(得分:0)

这是因为您在类的构造函数中使用random.Next()和级别评估,请记住构造函数仅在您创建对象的新实例时执行,因为它已执行多次创建一种不同的方法,你可以调用随机和级别评估,这样你每次都会获得不同的值或使用像这样的东西:

public bool Level()
{
     int randomLevel=random.Next(1,3); 
     level = (randomLevel % 2 == 0); 
     return level;
}

答案 9 :(得分:0)

尝试以下方法。将随机级别的选择移动到readingLevel函数。

Random random = new Random(); 
public Student() 
{ 
}

public bool readingLevel()//this always returns one value for the entire program. 
{ 
  int randomLevel=random.Next(1,3); 
  level = (randomLevel % 2 == 0); 
  return level; 
} 

答案 10 :(得分:-1)

Random random = new Random(DateTime.Now.Ticks);