Создайте разные семена для разных экземпляров "Случайные",
Люди обычно спрашивают, почему они всегда имеют одинаковые номера, когда они используют Random
. В своем случае они unintenionally каждый раз создают новый экземпляр Random
(вместо использования только одного экземпляра), что, конечно, все время приводит к одинаковым номерам. Но в моем случае мне нужно несколько экземпляров Random
, которые возвращают разные числовые потоки.
Использование жестко кодированных семян - это плохая идея, на мой взгляд, так как вы снова и снова получаете одинаковые значения после перезапуска программы. Что об этом:
int seed1 = (int)DateTime.Now.Ticks - 13489565;
int seed2 = (int)DateTime.Now.Ticks - 5564;
Я знаю, что это выглядит глупо и наивно, но после каждого перезапуска они избегают одинаковых значений, и оба семени должны отличаться. Или, может быть,
Random helper = new Random();
int seed1 = helper.Next(1, int.MaxValue);
int seed2 = helper.Next(1, int.MaxValue);
Как вы можете видеть, я здесь немного не творческий и нуждаюсь в вашей помощи. Спасибо.
Ответы
Ответ 1
Jon Skeet, предлагает использовать вторичный объект Random
и блокировку для создания объекта Random
factory. Например:
public static Random NewRandom()
{
lock (globalLock)
{
return new Random(secondaryRandom.Next());
}
}
Взгляните на полный исходный код в блоге Jon Skeet.
Ответ 2
Я бы использовал ваш второй подход:
int randomCount = 10;
Random seeder = new Random();
var randoms = Enumerable.Range(0, randomCount)
.Select(i => new Random(seeder.Next()))
.ToList();
Это использует linq для создания списка из 10 случайно выбранных случайных экземпляров. Поэтому вам понадобится using System.Linq;
для доступа к методу расширения Select
.
Вы также можете повторно использовать сеялку в качестве одного из ваших экземпляров:
int randomCount = 10;
Random seeder = new Random();
var randoms = Enumerable.Range(0, randomCount - 1)
.Select(i => new Random(seeder.Next()))
.Concat(new [] { seeder })
.ToList();
Ответ 3
Вы можете использовать криптографический генератор для создания ваших семян, например.
public static Random CreateRandom()
{
using (var rng = new System.Security.Cryptography.RNGCryptoServiceProvider())
{
byte[] bytes = new byte[4];
rng.GetNonZeroBytes(bytes);
int seed = BitConverter.ToInt32(bytes, 0);
return new Random(seed);
}
}
Конечно, если вам просто нужны int, вы можете использовать RNGCryptoServiceProvider
для их создания напрямую, хотя System.Random
, вероятно, быстрее.