У меня есть следующий код внутри статического метода в статическом классе:
Random r = new Random();
int randomNumber = r.Next(1,100);
У меня это внутри цикла, и я продолжаю получать те же randomNumber
!
Любые предложения здесь?
У меня есть следующий код внутри статического метода в статическом классе:
Random r = new Random();
int randomNumber = r.Next(1,100);
У меня это внутри цикла, и я продолжаю получать те же randomNumber
!
Любые предложения здесь?
Вы не должны создавать новый экземпляр 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);
Хорошее семеноводство для меня:
Random rand = new Random(Guid.NewGuid().GetHashCode());
Это очень случайный случай. Семена всегда разные, потому что семя также генерируется случайным образом.
Если вы по какой-то причине не можете использовать один и тот же Random
снова и снова, попробуйте инициализировать его тем, что изменяется все время, например, само время.
new Random(new System.DateTime().Millisecond).Next();
Помните, что это плохая практика.
EDIT: конструктор по умолчанию уже берет свое семя из часов и, вероятно, лучше, чем мы. Цитата из MSDN:
Random(): Инициализирует новый экземпляр класса Random, используя временное начальное значение по умолчанию.
Код ниже, вероятно, ваш лучший вариант:
new Random().Next();
Бит поздно, но реализация, используемая 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
это работает для меня:
private int GetaRandom()
{
Thread.Sleep(1);
return new Random(DateTime.Now.Millisecond).Next();
}
public static Random rand = new Random(); // this happens once, and will be great at preventing duplicates
Обратите внимание, что это не должно использоваться для криптографических целей.
Хорошая инициализация семян может быть выполнена следующим образом
Random rnd = new Random((int)DateTime.Now.Ticks);
Тики будут уникальными, и приведение в int с вероятным отсутствием значения будет ОК.
Я использую это для большинства ситуаций, сохраняю семя, если есть необходимость повторить последовательность
var seed = (int) DateTime.Now.Ticks;
var random = new Random(seed);
или
var random = new Random((int)DateTime.Now.Ticks);