Сумма прогрессии квадратична по отношению к числу членов, и выражение растёт достаточно быстро, чтобы появились дубли, даже если число испытаний крайне мало сравнительно с общим числом возможных чисел. Собственно, это известный "парадокс дней рождения".
Но повторюсь - требуется "истинная случайность". Обычный ГСЧ даст либо гарантированную бесповторность, либо гарантированный повтор,
Спасибо. Если интересно о практической цели данной задачи, о цель такая..
У меня переборная задача. Есть "позиция" ( игры), у которой одна стратегия перебора.
Из корневой позиции, последуют
позиций, в дереве перебора "на
1-м этаже".
Из этих
позиций, последуют
позиций, в дереве перебора "на
2-м этаже".
И так далее, перебор ведём в ширину, выстраивая слой за слоей, это дерево, до тех пор пока не будет найдено кратчайшее решение.
Но позиции часто возникают такие, какие ранее уже встречались, и если для таких не делать отсечение, то дерево перебора, будет расти очень быстро, и решение скорее всего найдено не будет. Потому делаю хэш-сет, и туда записываю все ранее встретившиеся позиции. Если при очередном переходе, вижу, что позиция ранее встречалась (а в хэш-сете очень быстрый поиск) - то позиция заново не записывается на текущий этаж дерева перебора.
Такой достигается выигрыш по памяти. Позиция занимает
байта. Это полная информация, которую надо хранить на последнем этаже дерева перебора, чтобы строить следующий этаж. В среднем, каждый следующий этаж больше по числу позиций всего лишь в
раза от предыдущего.
Позже подумал - а зачем на все этажи выше - хранить полную информацию о каждой позиции, т.е. все
байта?
Можно преобразовать это в некий более короткий хэш-код, который будет например,
байт (а значит и позиций сможем хранить в
раза больше, и углубится дальше по дереву перебора). Хэш-код - некая укороченная информация о позиции, которая вообще говоря, может дать коллизии, т.е. для разных позиций выдать одинаковый хэш-код. Но если этот хэш-код
байт, то количество его возможных значений, равно
, и даже если в процессе перебора встретятся
миллиардов позиций, то вероятность хотя бы одной коллизии, как выше выяснилось, очень малая,
при генерации
миллиардов случайных чисел, если отрезок
, (это мат.языком примерно
ундециллионов), то искомая вероятность, что найдётся хотя бы одна пара чисел которые совпадут, будет равна примерно :
.
Значит, можно не опасаться, что мы словим ошибку (вероятность этого меньше чем выиграть в лотерею, даже если запустить миллиард подобных анализов для разных корней) - в большинстве случае программа корректно осуществит перебор, и выдаст правильный результат, оперируя бОльшим количеством значений в хэш-сете.
Но преобразование
байт в хэш-код
байт - должно иметь , так сказать, равновероятное распределение по всем возможным
-байтовым значениям.
-байтные значения могут совсем чуть-чуть отличаться, и недопустимо чтобы для двух таких значений,
-байтный хэш-код часто, тоже чуть-чуть отличался. Это вносит большое увеличение вероятности коллизий.
Поэтому, для этого, я планирую рассмотреть исходное
-байтное значение, просто как
-байтное длинное число.
Затем линейно-конгруэнтным методом, построить из него другое
-байтное длинное число. (уже здесь при небольшом отличии 2-х исходных чисел, допустим будут отличаться лишь в нескольких битах - два числа после преобразования линейно-конгруэнтным методом будут сильно отличаться ).
И затем каким нибудь
- м , получу из них
- байтное число, которое и может иметь
разных значений.
Это и будет "extended hash Code" .