Почему Random.Next () всегда возвращает один и тот же номер

Рассмотрим этот метод:

private static int GenerateRandomNumber(int seed, int max) { return new Random(seed).Next(max); } 

На моей машине выполнение этого цикла дает одинаковое число через 1500 итераций:

  for (int i = 0; i < 1501; i++) { int random = GenerateRandomNumber(100000000, 999999999); Console.WriteLine(random.ToString()); Console.ReadKey(); } 

Я получаю 145156561, за каждую итерацию.

У меня нет насущной проблемы, мне было просто интересно это поведение, потому что .Next (max) говорит: «Возвращает неотрицательное случайное число меньше указанного максимума. Возможно, я не понимаю что-то основное.

Вы всегда высеваете новый экземпляр с тем же семенем, а затем захватываете первый макс. Используя семена, вы гарантируете одинаковые результаты.

Если вы хотите создать статическое, случайное число, которое выполняет разные результаты, вы должны немного переработать его. Однако, поскольку Random не является streamобезопасным, для его использования требуется статическая синхронизация. Что-то вроде:

 private static Random random; private static object syncObj = new object(); private static void InitRandomNumber(int seed) { random = new Random(seed); } private static int GenerateRandomNumber(int max) { lock(syncObj) { if (random == null) random = new Random(); // Or exception... return random.Next(max); } } 

В 2001 году Дилберт столкнулся с той же проблемой:

http://dilbert.com/strips/comic/2001-10-25/

Совпадение?

Я так не думаю.

И random.org соглашается: http://www.random.org/analysis/

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

Генерация случайных чисел не является действительно случайной, см. Эту статью в Википедии для более подробной информации.

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

В .NET есть «всего» 2 ^ 32 различных случайных последовательности.

Не знаете, как работают внутренние элементы. Проверьте вики на это, но это очень просто.

 public class MathCalculations { private Random rnd = new Random(); public Int32 getRandom(Int32 iMin, Int32 iMax) { return rnd.Next(iMin, iMax); } } public class Main { MathCalculations mathCalculations = new MathCalculations(); for (int i = 0; i < 6; i++) { getRandom(0,1000); } } 

будет генерировать Number1, Number2, Number3, Number4, Number5, Number6 (1 семя, 1 последовательность из многих чисел, random * не очень, но приблизительно *)

если вы это сделаете:

 public class MathCalculations { public Int32 getRandom(Int32 iMin, Int32 iMax) { Random rnd = new Random(); return rnd.Next(iMin, iMax); } } public class Main { MathCalculations mathCalculations = new MathCalculations(); for (int i = 0; i < 6; i++) { getRandom(0,1000); } } 

Теперь вы получите Number1, Number1, Number1, Number1, Number1, Number1 (1 семя, 6 равных последовательностей из многих чисел, всегда выбирайте одинаковый стартовый номер из каждой одинаковой последовательности). В какой-то момент Number1 будет отличаться, потому что семя меняется со временем .. но вам нужно подождать некоторое время для этого, тем не менее, вы никогда не выбираете номер2 из последовательности.

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

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

Салам для всех, ну это тоже сбило меня с ума. Ответ прост. Измените семя, прежде чем создавать случайные.

Пример: я хочу создать случайное число от 1 до 10

 Random rnd = new Random(DateTime.Now.Seconds); int random_number = rnd.Next(10); 

Поместите его внутри цикла и запустите его три раза. Он выдаст случайные числа ниже 10.

В случае, если кто-то ищет «быстрое и грязное» решение (и я использую этот термин с осторожностью), этого будет достаточно для большинства.

 int secondsSinceMidnight = Convert.ToInt32(DateTime.Now.Subtract(DateTime.Today).TotalSeconds); Random rand = new Random(secondsSinceMidnight); var usuallyRandomId = rand.Next(); 

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

  • Уникальное генерирование случайных строк
  • Как получить случайную запись из базы данных MS Access
  • linq: порядок по случайным
  • Почему этот код использует случайные строки для печати «hello world»?
  • Rand ()% 14 генерирует только значения 6 или 13
  • Выберите случайное значение из enums?
  • Создать случайную дату рождения
  • Случайное число между двумя двойными номерами
  • Случайный взвешенный выбор в Java
  • Как я могу генерировать случайные буквенно-цифровые строки в C #?
  • Обратимый генератор псевдослучайных последовательностей
  • Давайте будем гением компьютера.