Для яких типів застосовуються операції з хеш-таблицею O (1)?


18

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

Однак, з точки зору програміста, я не знаю заздалегідь, якими будуть мої дані: вони часто надходять із якогось зовнішнього джерела. І я рідко маю всі дані одразу: часто вставки та видалення трапляються зі швидкістю, що не нижче швидкості пошуку, тому попередня обробка даних для точної настройки хеш-функції вимкнена.

Отже, зробивши крок: з огляду на деякі знання про джерело даних, як я можу визначити, чи є хеш-таблиця шансів виконати операції та, можливо, які методи використовувати для моєї хеш-функції?O(1)


Так, і таблиці Hash порівняно з бінарними деревами пов'язані, але тут я зосереджуюсь на хеш-таблицях і коли вони (або не є) в їх кращих випадках.
Жил "ТАК - перестань бути злим"

Найкращий випадок для будь-якої хеш-функції - це коли рівномірно розподіляються дані.
0x0

@Sunil: Неправда. Ви можете мати спеціальні хеш-функції.
Рафаель

Я думаю, що це питання занадто широке. Зокрема, чи можете ви конкретизувати, як виглядатимуть знання про джерела даних?
Рафаель

@Raphael Наприклад, якщо ключі є рядками: імена людей, назви файлів у каталозі, теги XML, хеші файлів,…
Жил 'ТАК - перестань бути злим'

Відповіді:


4

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

Як я можу визначити, чи може хеш-таблиця мати операції O (1) і, можливо, які методи використовувати для моєї хеш-функції?

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

Після того, як ви вибрали якусь конкретну функцію хешу, мабуть, надмірно оптимістично вважати, що Маллорі ніколи не дізнається, яку саме функцію ви вибрали. Після того, як Mallory виявить, яку вибрану хеш-функцію ви дозволите, якщо ви дозволите Mallory видавати багато даних, які потрібно вставити в вашу хеш-таблицю за допомогою цієї хеш-функції, тоді ви приречені: Mallory може внутрішньо швидко створювати мільярди елементів даних, хешувати їх своїми хеш-функція, щоб знайти, які елементи даних можуть зіткнутися, а потім подати вам мільйони тисяч на тисячу елементів, які можуть зіткнутися, що призводить до пошуку, які працюють набагато повільніше, ніж O (1).

Усі методи, які гарантують "O (1) пошук навіть у гіршому випадку", уникають цієї проблеми, зробивши трохи додаткової роботи над кожною вставкою, щоб гарантувати, що в майбутньому кожен можливий пошук може досягти успіху в O (1) час . Зокрема, ми припускаємо (в гіршому випадку), що Меллорі рано чи пізно виявить, яку хеш-функцію ми використовуємо; але він отримує лише можливість вставити декілька даних даних, перш ніж вибрати іншу хеш-функцію - хешування таблиць або інший універсальний хеш - той, який ми спеціально вибираємо таким, щоб усі дані, які ми маємо дотепер, можна було переглянути 2 або 3 зонди - тобто O (1). Оскільки ми вибираємо цю функцію випадковим чином, ми можемо бути досить впевнені, що Меллорі не знатиме, яку функцію ми вибрали на деякий час. Навіть якщо Меллоріодразу дає нам дані про те, що навіть за допомогою цієї нової хеш-функції зіштовхується з попередніми даними, ми можемо вибрати ще одну нову нову хеш-функцію, щоб після повторного перегляду всі попередні дані, які він та всі інші годували нас, тепер можна було переглянути в 2 або 3 зонди в гіршому випадку - тобто, O (1) пошуку в гіршому випадку.

Досить легко випадковим чином вибрати нову хеш-функцію та повторно переробити всю таблицю досить часто, щоб гарантувати, що кожен пошук завжди є O (1). Хоча це гарантує, що кожен пошук завжди є O (1), ці методи під час вставки N-го елемента в хеш-таблицю, яка вже містить елементи N-1, можуть періодично вимагати часу O (N) для цієї вставки. Однак можна спроектувати систему таким чином, що навіть коли Меллорі навмисно надає вам нові дані, які, використовуючи нову хеш-функцію, стикаються з попередніми даними, система може приймати безліч предметів від Маллорі та інших, перш ніж їй потрібно зробити повне відновлення (N). Прийоми таблиці хешу, які вибирають нову функцію і повторно переробляють, щоб гарантувати пошук (1) пошуку, навіть у гіршому випадку, включають:

  • хешування зозулі гарантує, що пошук кожної клавіші досягає щонайменше 2 хеш-обчислень та 2 пошукових таблиць.
  • хеш-пам'ять hopscotch гарантує, що пошук кожного ключа буде успішним після огляду послідовних записів у таблиці невеликої кількості H (можливо H = 32).
  • динамічне ідеальне хешуваннявання - папір Дітцфельбінгера 1994 року - це перший, який я прочитав, який зазначив, що, хоч і переробляє "часто", щоб гарантувати, що кожен пошук ключів завжди досягає 2 хеш-обчислень та 2 пошукових запитів, це можливо робити повну повторну операцію так рідко, що навіть незважаючи на те, що кожна повна повторна операція використовує O (n) час, очікувана середня вартість вставки та видалення амортизується O (1).

Структури даних / Хеш-таблиці



5

O(1)

O(1)O(n2W)

O(logn/loglogn)O(1)


5

ha,b(x)=ax+bmodp

Раніше, згідно з документом Usenix Crosby і Wallach , звичайні мови програмування нічого подібного не робили, залишаючи багато веб-додатків (та інших серверів) відкритим для DoS-атаки на основі виробничих зіткнень. (Документ зроблений з 2003 року, але це говорить про те, що Дан Бернштейн виявив цю ідею трохи раніше.)

Швидкий пошук в Google надає твердження, що стан техніки з точки зору реалізацій покращився і не покращився .

Ще одна сторона полягає в тому, що у світі з високою пропускною здатністю тимчасові атаки не дуже важко знайти зіткнення в Інтернеті (на відміну від офлайн, як підказує посилання Кросбі-Валах). Здається, я пам’ятаю, що Даніель Головін кілька років тому мав результати щодо структур даних, не вразливих до атак часу, але я не знаю, чи широко застосовуються вони.


0

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

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

Звичайно, складність випливає з того, що нерівномірний аналіз аварійного випадку "важко зробити. І ваше «знання» може бути не виразно виражене як розподіл, який легко використовувати в такому аналізі.

Очевидно, найпростіше це зробити симуляції. Реалізуйте хеш-таблиці та спостерігайте за їх виконанням для вашого типового набору входів.


8
Я повинен не погодитися з першим реченням. Стандартне припущення полягає в тому, що хеш-функція є випадковою, а не вхідними даними. Припускаючи, що рівномірно розподілені дані підштовхують аналіз у сферу фантазії - дані реального світу ніколи не є рівномірними! Але є методики з підручника, щоб зробити хеш-функції достатньо однаковими. Див. Універсальний хешинг та конкретно хешування таблиць .
JeffE

@JeffE Подивіться на аналіз середнього випадку у відповіді Рафаеля, він констатує це припущення про однаковість. Ви не можете зробити аналіз середнього випадку без розподілу. Ви повинні вибрати одну, і якщо вона не надана, бритви Ocam пропонують рівномірний.
uli

6
Звичайно, у вас є розподіл; це розподіл, який ви використовуєте для вибору хеш-функції. Вибір розподілу для вхідних даних - це як пошук втрачених ключів під стовпом світильника; звичайно, світло краще, але це, мабуть, не те, де ви їх упустили.
JeffE

@JeffE Ось так робиться аналіз в середньому випадку, виберіть розподіл і починайте обчислювати. Як завжди вибір дискусії є дискусійним. Ви можете зробити нерівномірний аналіз середнього рівня.
uli

4
Так, я знаю, як це робиться. (Перевірте мій профіль.) Якщо ви хочете, щоб ваш аналіз був передбачуваним (у чому полягає вся суть аналізу), ви повинні рандомізувати хеш-функцію. Тоді ви знаєте точний розподіл, бо ви його вибрали.
JeffE

-1

nn!. Але я міг би це зробити, тому що мені врешті-решт була потрібна кожна перестановка; якщо ви використовуєте лише підмножину, вам знадобиться функція, пристосована до цього підмножини або ефективний розріджений масив.

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