Какие именно предложения вы ищете? эффективность? правильности? Вы упоминаете модульное тестирование ... Я думаю, что там, безусловно, может быть улучшение.
Я действительно помог разработать онлайн-игру и их механизм перетасовки. Я действительно не подозреваю, что производительность - это большая проблема, так как большинство алгоритмов, которые вы находите, по большому счету одинаковы. Я бы предложил следующие, но
a. создать случайный интерфейс
public interface IRandom
{
byte NextRandomByte();
}
Все, что в настоящее время потребляет этот интерфейс теперь может быть издевался \ протестировано в управляемом режиме или окружающей среде. Вы действительно не хотите быть модульным тестированием по-настоящему случайных алгоритмов - вы не сможете проверить свои данные!
Что касается причины возврата байта, то байт, скорее всего, является наименьшей единицей случайности, которую вы могли бы захотеть. И не только это, но и при условии создания одного случайного байта, генерация последовательности из них и объединение их вместе - это простой способ создания еще более широкого диапазона случайных данных.
Конечно, вы должны быть осторожной introduing предвзятости к данным ...
б. Обеспечение качества данных путем уменьшения смещения в течение произвольных интервалов. Предполагая, что базовые данные являются равномерно случайными, любой интервал, который НЕ является фактором в 256, приведет к смещению.Рассмотрим это,
// 250 is not a factor of 256!
byte a = random.NextRandomByte() % 250; // values 0-5 are biased!
В предыдущем фрагменте значения 0-5 имеют 2/255 вероятность прийти вверх, в то время как значения 6-249 имеют 1/255 вероятность придумать. Это значительное смещение с течением времени. Один из подходов состоит в проверке количества, поступающего из генератора, и отбросить его, если он превышает допустимый диапазон
// continually generate random data until it is satisfactory
for (byte r = random.NextRandomByte(); r > 250; r = random.NextRandomByte())
{
}
byte a = r % 250; // r is guaranteed to be on [0, 250], no longer bias
«Допустимый диапазон», может быть определено путем нахождения наибольшего кратного вашего интервала, который может быть представлен вашим значением тип. Более обобщенная форма
byte modulo; // specified as parameter
byte biasThreshold = (byte.MaxValue/modulo) * modulo;
for (; unbiasedValue >= biasThreshold;)
{
// generate value
unbiasedValue = random.NextRandomByte();
}
И если вы хотите значения больше байт, просто сцепить значения вместе,
int modulo; // specified as parameter
int biasThreshold = (int.MaxValue/modulo) * modulo;
for (; unbiasedValue >= biasThreshold;)
{
// generate value
byte a = random.NextRandomByte();
byte b = random.NextRandomByte();
...
int unbiasedValue = a << 24 + b << 16 + c << 8 + d;
}
гр. Потребляйте! Поместите свои алгоритмы или помощник в безгосударственном расширении или статических классах, как
// forgive my syntax, recalling from memory
public static class IRandomExtensions
{
public int GetUnbiasedInteger (this IRandom random, int modulo) { }
public int GetUnbiasedUnsignedInteger (this IRandom random, uint modulo) { }
public int GetUnbiasedLong (this IRandom random, long modulo) { }
public int GetUnbiasedUnsignedLong (this IRandom random, ulong modulo) { }
...
}
public static class IEnumerableExtensions
{
public IEnumerable<T> Shuffle<T>(this IEnumerable<T> items, IRandom random)
{
// shuffle away!
...
}
}
Принятия решения или не выполнять их в качестве методов на интерфейсе или в качестве внешних методов [как я сделал] до вас - но сохранить в виду, что их методы-члены заставляют разработчиков повторять или дублировать код. Лично мне нравятся расширения. Они очень чисты. И сексуально.
int randomNumber = random.UnbiasedInteger (i - 1);
List<int> shuffledNumbers = numbers.Shuffle (random);
Очевидно все предшествующему не является обязательным, но облегчает модульное тестирование и улучшает общее качество ваших случайных данных.
Случайные и «честные» кости - очень интересная тема в целом. Если вас вообще интересует, я настоятельно рекомендую вам его когда-нибудь и проводить некоторые исследования. :)
Просто вне интереса, как бы вы проверили метод, когда результат должен быть случайным? –
интерфейсы конечно! –
@simonn: в этом случае, если вы пройдете в одном семени, вы получите тот же самый заказ. –