Возможно ли реализовать универсальное хеширование для полного диапазона целых чисел?

Я читаю о универсального хеширования на целых. The обязательное условие и обязательным условием кажется, что мы выбираем простое число p больше, чем набор всех возможных ключей.

Я не совсем ясно по этому вопросу.

Если наш набор ключей типа int тогда это означает, что простое число должно быть больше тип данных, например,long.

но в конечном итоге все, что мы получаем поскольку хэш должен быть понижен до int, чтобы индексировать хэш-таблицу. Разве это не влияет на качество универсального хэширования (я имею в виду распределение ключей по ведрам) каким-то образом?

1 ответов


если наш набор ключей целые числа, то это означает, что простое число должен быть следующего большего типа данных, например long.

это не проблема. Иногда это необходимо, иначе семейство hash не может быть универсальным. См. ниже для получения дополнительной информации.

но в конечном итоге все, что мы получим, как хэш, должно быть низведен до int индекс хэш-таблицы.

не так ли down-литье влияет на качество универсального хеширования (Я имею в виду распределение ключей по ведрам) почему?

ответа нет. Я попытаюсь объяснить.

ли p имеет другой тип данных или нет, не важно, чтобы семейство хэшей было универсальным. Важно, что p равна или больше, чем u (максимальное число Вселенной целых чисел). Важно, что p is большой достаточно (т. е. >= u).

семейство хэшей универсально, когда вероятность столкновения равна или меньше, чем 1/m.

так что идея провести это ограничение.

значение p, теоретически, может быть как long или больше. Это просто должно быть целое число и простое число.

  • u - размер домена / Юниверса (или количество ключей). С учетом Вселенная!--10-->, u обозначает размере |U|.
  • m это количество бункеров или ведер
  • p - простое число, которое должно быть равно или больше n
  • семейство хэшей определяется как H = {h(a,b)(x)} С h(a,b)(x) = ((a * x + b) mod p) mod m. Примечание это a и b случайных чисел (из всех возможных целых чисел, так что теоретически может быть больше, чем p) по модулю простого p (что может сделать их либо больше или меньше m, количество ящиков/ведер); но и здесь тип данных (домен значения не имеет). См.хеширования целых чисел в Википедии для обозначения.
  • следуя доказательство в Википедии и вы заключаете, что вероятность столкновения _p/m_ * 1/(p-1) (подчеркивания означают усечение десятичных знаков). Для p >> m (p значительно больше, чем m) вероятность имеет тенденцию к 1/m (но это не значит, что чем больше вероятность, тем лучше!--1--> is).

иными словами, отвечая на ваш вопрос: p быть большим типом данных здесь не проблема и может даже потребоваться. p должно быть равно или больше, чем u и a и b должны быть случайным образом выбраны целые числа по модулю p, независимо от количества сегментов m. С помощью этих ограничений вы можете построить универсальный хэш семья.


может быть, математический пример может помочь

  • пусть U-Вселенная целых чисел, соответствующих unsigned char (например, в C). Тогда U = {0, ..., 255}
  • пусть p быть (следующим возможным) простым равным или большим, чем 256. Примечание это p может быть любой из этих типов (short, int, long будет он подписан или нет). дело в том, что тип данных не играет роли (В программировании тип в основном обозначает область значений.). Ли 257 is short, int или long на самом деле не имеет значения здесь ради правильности математического доказательства. Кроме того, мы могли бы выбрать больший p (т. е. больший тип данных); это не меняет правильности доказательства.

    1. следующее простое число будет 257.
    2. мы говорим, что у нас есть 25 ведра, то есть m = 25. Это означает хэш семейство будет универсальным, если вероятность столкновения равна или меньше 1/25, т. е. примерно 0.04.
    3. введите значения для _p/m_ * 1/(p-1): _257/25_ * 1/256 = 10/256 = 0.0390625 меньше, чем 0.04. Это универсальное семейство хэшей с выбранными параметрами.

мы могли бы выбрать m = u = 256 ведра. Тогда у нас была бы вероятность столкновения 0.003891050584, который меньше, чем 1/256 = 0,00390625. Хэш-семья все-таки универсальный.

с m больше, чем p, например,m = 300. Вероятность столкновения равна 0, что меньше, чем 1/300 ~= 0.003333333333. Тривиально, у нас было больше ведер, чем ключей. Все так же универсально, никаких столкновений.

пример реализации

мы имеем следующее:

  • x типа int (элемент |U|)
  • a, b, p тип long
  • m мы увидим позже в Примеру

    1. выбрать p Так что он больше, чем max u (элемент |U|), p типа long.
    2. выбрать a и b (по модулю p) случайным образом. Они относятся к типу long, но всегда < p.
    3. на x (типа int с U) расчета ((a*x+b) mod p). a*x типа long, (a*x+b) тоже типа long и ((a*x+b) mod p тоже типа long. Обратите внимание, что ((a*x+b) mod p) результат < p. Обозначим этот результат h_a_b(x).
    4. h_a_b(x) теперь modulo m, что означает, что на данном этапе это зависит от типа данных m будет ли downcasting или нет. Впрочем, это не имеет значения. h_a_b(x) is < m, потому что мы принимаем это modulo m. отсюда значение h_a_b(x) modulo m подходит 'ы. В случае, если это должно быть downcasted не будет потери стоимости. и поэтому вы сопоставили ключ с бункером / ведром.