Проблема с min = 0 и max = 1 заключается в том, что min является включающим, а max исключающим. Таким образом, единственное возможное значение для этой комбинации - 0.
Эта перегрузка Next () возвращает:
32-битное целое число со знаком, которое больше или равно minValue и меньше maxValue; то есть диапазон возвращаемых значений включает minValue, но не MaxValue. Если minValue равно maxValue, возвращается minValue.
0 - единственное возможное значение для возврата. Возможно, вам нужен random.NextDouble (), который вернет значение типа double от 0 до 1.
Не создавать метод оболочки для Next. Он тратит циклы на создание нового экземпляра класса Random. Просто используйте одно и то же!
Random myRand = new Random();
for(int i = 0; i < 10; i++)
{
Console.WriteLine(myRand.Next(0, 10).ToString());
}
Это должно дать вам десять случайных значений.
Как уже было сказано, Random является псевдослучайным (как и все реализации), и если вы создаете 100 экземпляров с одним и тем же начальным значением, вы получу 100 экземпляров тех же результатов. Убедитесь, что вы повторно используете класс.
Кроме того, как говорили люди, остерегайтесь того, что MinValue является включающим, а MaxValue - эксклюзивным. Если хотите, сделайте myRand.Next (0, 2).
random = new Random();
Запускает генератор случайных чисел с текущим временем (в секундах). Когда вы вызываете свою функцию много раз до изменения системных часов, генератор случайных чисел запускается с тем же значением, поэтому он возвращает ту же последовательность значений.
Минимум является включенным, но максимальный - исключительным. Ознакомьтесь с API
Вы всегда получаете 0, потому что Random.Next
возвращает целые числа. Вам нужно вызвать Random.NextDouble
, который вернет число от 0 до 1. Также вам следует повторно использовать свой случайный экземпляр, например:
[ThreadStatic]
static Random random;
public static Random Random {
get {
if (random == null) random = new Random();
return random;
}
}
public static int RandomInteger(int min, int max)
{
return Random.Next(min, max);
}
public static double RandomDouble() //Between 0 and 1
{
return Random.NextDouble();
}
Если вы хотите криптографически безопасные случайные числа, используйте класс RNGCryptoServiceProvider
; см. эту статью
РЕДАКТИРОВАТЬ: безопасность потоков
Помимо проблемы 0-1, уже отмеченной в других ответах, ваша проблема является реальной, когда вы ищете диапазон 0-10 и получаете идентичные результаты 50 раз подряд.
new Random ()
должен возвращать случайное число с начальным значением, инициализированным таймером (текущая секунда), но, очевидно, вы вызываете этот код 50 раз в секунду. MSDN предлагает: «Для повышения производительности создайте одно случайное число для генерации множества случайных чисел с течением времени, вместо того, чтобы многократно создавать новое случайное число для генерации одного случайного числа». Если вы однажды создадите свой генератор случайных чисел вне метода, это должно решить вашу проблему «неслучайности», а также улучшить производительность.
Также рассмотрите этот пост для лучшего генератора псевдослучайных чисел, чем системный,
Как уже упоминали другие, Random, который создается несколько раз в секунду, использует ту же секунду, что и начальное число, поэтому я бы поместил конструктор Random за пределы вашего цикла и передал его как параметр, например:
public static int RandomNumber(Random random, int min, int max)
{
return random.Next(min, max);
}
Также, как упоминалось другими, max является исключительным, поэтому, если вы хотите 0 или 1, вы должны использовать [0,2] в качестве своего [min, max] или некоторого большего максимума, а затем выполнить двоичное И с 1.
public static int RandomOneOrZero(Random random)
{
return random.Next(0, int.MaxValue) & 1;
}
Это дополнение к любым ответам, как ответ на этот конкретный вопрос в том, что границы должны быть (0, 2), а не (0, 1).
Однако, если вы хотите использовать метод статической оболочки, тогда вы должны помнить, что Random
не является потокобезопасным, поэтому вам нужно либо предоставить свой собственный механизм синхронизации, либо предоставить экземпляр для каждого потока. Вот в значительной степени неблокирующая реализация, которая использует один генератор для заполнения каждого генератора потока:
public static class ThreadSafeRandom
{
private static readonly Random seed = new Random();
[ThreadStatic]
private static Random random;
public static int Next(int min, int max)
{
if (random == null)
{
lock (seed)
{
random = new Random(seed.Next());
}
}
return random.Next(min, max);
}
// etc. for other members
}
Several posters have stated that Random() uses a seed based on the current second on the system clock and any other instance of Random created in the same second will have the same seed. This is incorrect. The seed for the parameterless constructor of Random is based on the tick count, or number of milliseconds since boot time. This value is updated on most systems approximately every 15 milliseconds but it can vary depending on hardware and system settings.
в VB я всегда начинаю с функции Randomize (). Просто вызовите Randomize () и запустите случайную функцию. Я также делаю следующее:
Function RandomInt(ByVal lower As Integer, ByVal upper As Integer) As Integer
Return CInt(Int((upper - lower + 1) * Rnd() + lower))
End Function
Надеюсь, это поможет! :)