(58)
Итак, перепробовав разные подходы (в том числе, расчет CRC32 в запросе), я пришел к очень простому заключительному выводу: для расчета хэш-функции в запросе на основе нумерации строк лучше всего подойдет функция
либо функция
Любопытно, что это преобразование, фактически, является расчетом одного из коэффициентов ДПФ. То есть у него есть логическая основа.
Чтобы убедиться, что функция подходит, нужно рассчитать вероятность коллизий и убедиться, что она меньше заданной.
Для этого используем центральную предельную теорему теории вероятностей, которая говорит, что
Цитата |
---|
что сумма достаточно большого количества слабо зависимых случайных величин, имеющих примерно одинаковые масштабы (ни одно из слагаемых не доминирует, не вносит в сумму определяющего вклада), имеет распределение, близкое к нормальному. |
Это как раз наш случай.
То есть значение ХЭШ функции СУММА(SIN(НомерПП)) как случайная величина будет иметь нормальное распределение.
Математическое ожидание µ случайной величины СУММА(SIN(НомерПП)) будет равно нулю. И, исходя из формы графика плотности распределения вероятности (перевернутый колокол), ноль будет самым частым значением ХЭШ функции. Дисперсия σ^2 итогового распределения будет равна сумме дисперсий исходных распределений.
Дисперсия σ^2 случайной величины SIN(X) равна 0.5.
Потому, что рассчитывается как СРЕДНЕЕ(sin^2(x)) и известно, что СРЕДНЕЕ(sin^2(x)) = СРЕДНЕЕ(cos^2(x)) и sin^2(x) + cos^2(x) = 1.
Значит, дисперсия σ^2 случайной величины СУММА(SIN(НомерПП)) будет равна 0.5 N, а среднее квадратичное отклонение σ равно √(0.5 N), где N - число членов суммы.
Проверка показала, что значение СУММА(SIN(НомерПП)) считается в запросе с точностью девяти десятичных знаков.
Также у нас есть функция ошибок Гаусса erf(x), которая позволяет рассчитать вероятность того, что значение суммы будет отклоняться от математического ожидания (нуля) на вес младшего разряда ε = 10^(-9). А это и есть удвоенная вероятность того, что ХЭШ функция будет принимать значение ноль с точностью девяти десятичных знаков.
Таким образом, максимальная вероятность коллизий будет равна
0.5 erf (ε / (σ * √2 ) ).
Есть разложение
erf(x) = ( 2 / √π ) ( x - x^3 / 3 + x^5 / 10 - ... ).
Учитывая, что x в нашем случае x очень мало, формулу можно предельно упростить, оставив только первое слагаемое.
В итоге максимальная вероятность коллизий окажется равной
ε / ( √(0.5 N) * √(2 π)) = ε / √( π N) = 10^(-9) / √( π N),
и, значит, укладывается в заданные пределы. А в среднем будет еще меньше.