2013-02-16 2 views
3

, если у меня есть это: (я уже объявлял переменные)Как работают случайные числа от случайного объекта?

random1 = new Random(); 
Console.WriteLine(random1.Next(1, 100)); 
Console.WriteLine(random1.Next(1, 100)); 

Когда у меня есть, что она будет генерировать различное количество каждый раз, когда я называю Console.WriteLine, так что это будет генерировать отл. 10, 55, и если вы сделаете это снова 20,60, то в основном случайные числа каждый раз, хорошо. Но когда я добавляю это:

random2 = new Random(); 
Console.WriteLine(random1.Next(1, 100)); 
Console.WriteLine(random1.Next(1, 100)); 
Console.WriteLine(random2.Next(1, 100)); 
Console.WriteLine(random2.Next(1, 100)); 

Random1 будет генерировать те же числа, что и вкось! Так будет. 5,54,5,54, и если я сделаю это снова 70,34,70,34. Но это random2 - новый объект, так почему он генерирует те же цифры, что и random1 ??

Другой пример: Если у меня есть класс, как этот

class RandomNumber 
    { 
     Random random = new Random(); 
     public int getrandomnumber { get { return random.Next(1, 5); } } 
    } 

После выполнения этого

randomnumberobject = new RandomNumber(); 
randomnumberobject2 = new RandomNumber(); 
Console.WriteLine(randomnumberobject.getrandomnumber); 
Console.WriteLine(randomnumberobject2.getrandomnumber); 

Они генерируют случайное число, но оба они будут генерировать точно такое же случайное число , Так что в первый раз я получу это 5,5 секунды, это 3,3 и так далее. Но если изменить класс этого

class RandomNumber 
    { 
     Random random; 
     public int getrandomnumber { get { return random.Next(1, 5); } } 
     public RandomNumber(Random random) { this.random = random; } 
    } 

И сделать это вместо того, чтобы

random = new Random(); 
    randomnumberobject = new RandomNumber(random); 
    randomnumberobject2 = new RandomNumber(random); 
    Console.WriteLine(randomnumberobject.getrandomnumber); 
    Console.WriteLine(randomnumberobject2.getrandomnumber); 

Внезапно оба они генерируют различные случайные числа! Так почему это происходит? В чем причина? Имейте в виду, я все еще новичок.

+3

Посмотрите на [Docs] (http://msdn.microsoft.com/en-us/library/system.random.aspx), в частности, второй абзац раздела замечает: «По умолчанию, безразмерный конструктор класса Random использует системные часы для генерации своего начального значения, тогда как его параметризованный конструктор может принимать значение Int32 в зависимости от количества тиков в текущее время. Однако, поскольку часы имеют конечное разрешение, использование конструктора без параметров создавать разные случайные объекты в непосредственной последовательности создает генераторы случайных чисел, которые производят идентичные последовательности случайных чисел » – RobH

+0

Посмотрите на случайные числа посева. Там все. Бывают случаи, когда вы хотите получить одну и ту же последовательность случайных чисел каждый раз, и есть моменты, когда вы этого не делаете. –

ответ

5

Что вы видите «по дизайну» - то есть это происходит из-за того, как реализуется класс ... Алгоритм, который он использует, требует «семени» (типа начального состояния), который в этом случае основан на часы ... как указано на MSDN:

Генерация случайных чисел начинается с начального значения. Если же одно и то же число используется повторно, генерируется такая же серия чисел. Один способ создания различных последовательностей состоит в том, чтобы сделать начальное значение зависящим от времени, тем самым создавая различную серию с каждым новым экземпляром случайных чисел . По умолчанию безразмерный конструктор класса Random использует системные часы для генерации своего начального значения, а его параметризованный конструктор может принимать значение Int32, основанное на числе тиков в в текущее время. Однако, поскольку часы имеют конечное разрешение, используя конструктор без параметров для создания разных случайных объектов в непосредственной последовательности создает случайное число генераторы, которые производят идентичные последовательности случайных чисел. Пример, приведенный ниже, иллюстрирует, что два случайных объекта, которые являются , инстанцированные с близкой последовательностью, генерируют идентичные серии случайных чисел .

Это означает, что в принципе, что если два Random объектов создаются в почти то же самое время, используя конструктор без параметров, они будут производить ту же последовательность случайных чисел, так как они были инициализированы с тем же «исходным состоянием», основанной на часах ,

+0

Извините, мой интернет пошел вниз. Можете ли вы прояснить это для меня? Поэтому позвольте мне понять это, третий пример не будет работать, потому что, хотя это два разных объекта одного и того же класса, когда вы создаете новый объект из двух из них одновременно, «случайный» в классе для оба объекта получат одинаковое «начальное состояние»? – CsharpFrustration

+0

@CsharpFrustration да точно ... вы можете изменить это, используя другой contructor и снабдив его другим «семенем» (то есть начальным состоянием), которое является только Int32. – Yahia

+0

О, я вижу. Спасибо большое! – CsharpFrustration

0

Генерация случайных чисел основана на начальном значении на большинстве языков программирования. Это семя обычно берется из текущего значения времени. Поэтому, если вы объявляете два случайных объекта близко друг к другу, скорее всего, они получат одно и то же семя из CLR. Вот почему они будут генерировать одинаковые числа.

Когда вы используете один и тот же экземпляр, первые два числа будут уже получены из случайной последовательности, поэтому следующие два не будут одинаковыми.

Используйте явное семя в таких ситуациях (конструктор Random, который перегружен значением int).

0

Поскольку вы каждый раз пересаживаетесь в последнем примере, если вы не перегружаете случайный объект, каждый раз вытаскивайте из одного пула случайных чисел.

 var random1 = new Random(DateTime.Now.Millisecond); 
     Console.WriteLine(random1.Next(1, 100)); 
     Console.WriteLine(random1.Next(1, 100)); 
     Console.WriteLine(random1.Next(1, 100)); 
     Console.WriteLine(random1.Next(1, 100)); 

     var random2 = new Random(DateTime.Now.Millisecond); 
     Console.WriteLine(random2.Next(1, 100)); 
     Console.WriteLine(random2.Next(1, 100)); 
Смежные вопросы