Чому найкраще використовувати просте число як мод у функції хешування?


57

Якщо у мене є список ключових значень від 1 до 100 і я хочу організувати їх у масиві з 11 відер, мене вчили формувати модову функцію

H=kmod 11

Тепер усі значення будуть розміщені одне за одним у 9 рядках. Наприклад, у першому відрі буде 0,11,22 . У другій буде 1,12,23 тощо.

Скажімо, я вирішив бути поганим хлопчиком і в якості функції хешування застосував непрості - візьміть 12. Використання функції хешингу

H=kmod 12

в результаті вийде хеш-таблиця зі значеннями 0,12,24 у першому відрі, 1,13,25 тощо у другому тощо.

По суті вони одне і те ж. Я не зменшував зіткнень і не поширював нічого краще, використовуючи хеш-код простого числа, і я не бачу, як це корисно.


Відповідне питання, чому ми використовуємо XOR в хеш-функція stackoverflow.com/questions/5889238 / ...
Шува

Відповіді:


62

Розглянемо набір ключів K={0,1,...,100} та хеш-таблицю, де кількість відра m=12 . Оскільки 3 є коефіцієнтом 12 , клавіші, кратні 3 будуть розміщені у відра, кратні 3 :

  • Ключі {0,12,24,36,...} будуть відмічені до відра 0 .
  • Ключі будуть розміщені у відро .{3,15,27,39,...}3
  • Ключі будуть розміщені у відро .{6,18,30,42,...}6
  • Ключі будуть розміщені у відро .{9,21,33,45,...}9

Якщо розподілено рівномірно (тобто, кожен ключ у однаковою мірою трапляється), то вибір не є настільки критичним. Але що станеться, якщо не рівномірно розподілений? Уявіть, що ключі, які, найімовірніше, трапляються - кратні . У цьому випадку всі відра, не кратні будуть порожніми з великою ймовірністю (що дійсно погано з точки зору продуктивності хеш-таблиці).KKmK33

Ця ситуація більш поширена, як може здатися. Уявіть, наприклад, що ви відстежуєте об’єкти залежно від місця їх зберігання в пам'яті. Якщо розмір слова вашого комп’ютера становить чотири байти, то у вас будуть хеширующие ключі, кратні . Зайве говорити, що вибір для кратності був би жахливим вибором: у вас відра повністю порожні, а всі ваші ключі стикаються в решті відра.4m43m/4m/4

Загалом:

Кожна клавіша яка поділяє загальний коефіцієнт із кількістю відра буде хеширована до відра, кратного цього коефіцієнта.Km

Тому, щоб звести до мінімуму зіткнень, важливо , щоб зменшити кількість загальних факторів між і елементами . Як цього можна досягти? Вибравши число, яке має дуже мало факторів: просте число .mKm


Я щойно побачив, що мій запит відповідає вашій відповіді. Чи вважаєте ви, що хеш-функція в моєму запиті справна?
переобмінний обмін

@overexchange: я відповів на ваше запитання. Ця відповідь може також зацікавити вас.
Маріо Червера

чому так, що вибір m має значення лише в тому випадку, коли K перекошений? чи не правда, що ми матимемо гірші показники з поганою m, навіть якщо K рівномірно розподілений?
vorou

Це залежить від того, що ви маєте на увазі під «поганим ». Якщо ви маєте на увазі "малий порівняно з кількістю елементів у хеш-таблиці" (тобто високий коефіцієнт навантаження ), то продуктивність буде низькою. Однак якщо ви маєте на увазі "не просто", то цей факт не настільки важливий, якщо всі ключі однаково ймовірні, оскільки вони будуть розподілятися рівномірно в хеш-таблиці. Саме запитання подає приклад. m
Маріо Червера

16

Чи менше зіткнення з використанням праймерів менше, залежить від розподілу ваших ключів.

Якщо багато ваших ключів мають вигляд а ваша хеш-функція , ці ключі переходять до невеликої підмножини відра, якщо iff ділить . Тож вам слід мінімізувати кількість таких , чого можна досягти, вибравши простим.a+kbH(n)=nmodmbnb

Якщо ви хочете мати від до відер, і ви знаєте, що різниці, кратні , швидше, ніж різниці, кратні і , ви можете обрати для своєї спеціальної програми.1112112312


1
Але якщо мої ключі не мають форми то не має значення? Це так? a+k×bm
CodyBugstein

1
@lmray, якщо ваші клавіші розподілені рівномірно, не має значення. Якщо їх немає, це буде залежати від точності розподілу до матерії чи ні. mm
AProgrammer

Щойно повернув останню редакцію, я забув, що . 12>11
frafl

3
Ви мали на увазі, що «перейдіть до невеликої підмножини відра iff ділить »? bm
Михайло Дубов

8

Чи має це вплив (також), залежить від того, як ви ставитесь до зіткнень. При використанні деяких варіантів відкритого хешування , використання прайменів гарантує, що порожні слоти будуть знайдені до тих пір, поки таблиця буде достатньо порожньою.

Спробуйте показати, наприклад, таке:

Припустимо, ми хочемо вставити елемент, який має хеш для вирішення та вирішення зіткнень, намагаючись згодом позицій для .aa+i2i=1,2,

Покажіть, що ця процедура завжди дає порожню позицію, якщо хеш-таблиця розміром , a простим розміром більше , і принаймні половина всіх позицій вільна.pp3

Підказка: Використовуйте той факт, що кільцевий модуль залишків класу є полем, якщо є простим, і тому має щонайбільше рішення.ppi2=c2


2

Якщо хеш - функція має вигляд , де є простим і вибирається випадковим чином , то ймовірність того, що 2 різних ключів хеш з тим же відро . Тож для , що дуже мало.h(k)=a×kmodmma1mm=1009Pr{h(x)=h(y),xy}=0.00099108027

Ця схема відома як: Універсальний хешинг.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.