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

У меня есть следующий код внутри статического метода в статическом классе:

Random r = new Random();
int randomNumber = r.Next(1,100);

У меня это внутри цикла, и я продолжаю получать те же randomNumber!

Любые предложения здесь?

Ответ 1

Вы не должны создавать новый экземпляр Random в цикле. Попробуйте что-то вроде:

var rnd = new Random();
for(int i = 0; i < 100; ++i) 
   Console.WriteLine(rnd.Next(1, 100));

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

Для полноты, если вам действительно нужно выполнить перезагрузку Random, вы создадите новый экземпляр Random с новым семенем:

rnd = new Random(newSeed);

Ответ 2

Хорошее семеноводство для меня:

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

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

Ответ 3

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

new Random(new System.DateTime().Millisecond).Next();

Помните, что это плохая практика.

EDIT: конструктор по умолчанию уже берет свое семя из часов и, вероятно, лучше, чем мы. Цитата из MSDN:

Random(): Инициализирует новый экземпляр класса Random, используя временное начальное значение по умолчанию.

Код ниже, вероятно, ваш лучший вариант:

new Random().Next();

Ответ 4

Бит поздно, но реализация, используемая System.Random, Environment.TickCount:

public Random() 
  : this(Environment.TickCount) {
}

Это позволяет избегать бросать DateTime.UtcNow.Ticks из длинного, что является рискованным, так как оно не представляет тики с момента запуска системы, а "число 100-наносекундных интервалов, прошедших с 12:00 до полуночи, 1 января 0001 года (0:00:00 UTC 1 января 0001 года в григорианском календаре)".

Ищет хорошее целое семя для TestApi StringFactory.GenerateRandomString

Ответ 5

это работает для меня:

private int GetaRandom()
    {
        Thread.Sleep(1);
        return new Random(DateTime.Now.Millisecond).Next();
    }

Ответ 6

public static Random rand = new Random(); // this happens once, and will be great at preventing duplicates

Обратите внимание, что это не должно использоваться для криптографических целей.

Ответ 7

Хорошая инициализация семян может быть выполнена следующим образом

Random rnd = new Random((int)DateTime.Now.Ticks);

Тики будут уникальными, и приведение в int с вероятным отсутствием значения будет ОК.

Ответ 8

Я использую это для большинства ситуаций, сохраняю семя, если есть необходимость повторить последовательность

    var seed = (int) DateTime.Now.Ticks;
    var random = new Random(seed);

или

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