Сначала я нахожусь на телефоне, поэтому, пожалуйста, простите плохое форматирование!
Я много раз искал и не нашел окончательного ответа на этот вопрос. Если нет, честно, но я уверен, что кто-нибудь умнее, чем должен иметь хороший ответ!
Я использую поставщика криптоваторов RNG для генерации чисел в диапазоне поистине наивным способом:
byte[] bytes = new byte[4];
int result = 0;
while(result < min || result > max)
{
RNG.GetBytes(bytes);
result = BitConverter.ToInt32(bytes);
}
Это здорово, когда диапазон достаточно широк, так что есть достойный шанс получить результат, но ранее сегодня я попал в сценарий, где диапазон достаточно мал (в пределах 10 000 номеров), что может занять возраст.
Итак, я пытаюсь думать о лучшем способе, который обеспечит достойное распространение, но будет быстрее. Но теперь я углубляюсь в математику и статистику, которые я просто не делал в школе, или, по крайней мере, если бы я это сделал, я забыл все это!
Моя идея:
- получить наивысшие заданные битовые позиции min и max, например. для 4 это было бы 3, а для 17 было бы 5
- выберите количество байтов из prng, которые могут содержать по крайней мере высокие биты, например, в этом случае для 8 бит
- проверьте, установлены ли какие-либо из верхних бит в допустимом диапазоне (3-5)
- если да, включите это число до и включите высокий бит
- если это число находится между min и max, return.
- Если какой-либо из предыдущих тестов завершился с ошибкой, начните снова.
Как я уже сказал, это может быть чрезвычайно наивным, но я уверен, что он вернет матч в узком диапазоне быстрее, чем текущая реализация. Я не нахожусь перед компьютером на данный момент, так что не могу проверить, будет делать это завтра утром в Великобритании.
Но, конечно, скорость не является моей единственной заботой, иначе я бы просто использовал Random (вам нужно несколько галочек, чтобы правильно отформатировать, если кто-то будет достаточно любезен - они не на клавиатуре Android!).
Самая большая проблема, с которой я сталкиваюсь с вышеприведенным подходом, заключается в том, что я всегда отбрасываю до 7 бит, которые были сгенерированы prng, что кажется плохим. Я думал о способах их включения (например, простое добавление), но они кажутся ужасно ненаучными хаками!
Я знаю о трюке мод, где вам нужно только создать одну последовательность, но я также знаю о ее слабостях.
Это тупик? В конечном счете, если лучшее решение будет состоять в том, чтобы придерживаться текущей реализации, я просто чувствую, что должен быть лучший способ!