1632
правки
Изменения
м
'''Add''' — добавляет элемент с ключом Выберем <tex>2</tex> хэш-функции <tex>h_1(x)</tex> и <tex>h_2(x в )</tex> (из [[Универсальное семейство хеш-функций | универсального семейства хэш-таблицуфункций]]).
# Если одна из ячеек ===='''Add'''==== Добавляет элемент с индексами ключом <mathtex>h_1(x)</math> или <mathtex>h_2(x)</math> свободна, кладем в нее элемент. Переходим к шагу 7.# Иначе произвольно выбираем одну из этих ячеек, вытаскиваем оттуда элемент, помещаем туда новый.# Смотрим в ячейку, на которую указывает другая хешхэш-функция от только что вытащенного элемента, если она свободна, помещаем его в нее. Переходим к шагу 7.# Иначе вытаскиваем из этой ячейки элемент, кладем туда старый. Проверяем, не зациклились ли мы.# Если не зациклились, переходим к шагу 3.# Иначе выбираем 2 новые хеш-функции и перехешируем все добавленные элементы.# Помечаем ячейку, в которую только что добавили элемент, как занятую.таблицу
'''Delete''' — удаляет элемент # Если одна из ячеек с ключом индексами <tex>h_1(x)</tex> или <tex>h_2(x )</tex> свободна, кладем в нее элемент. # Иначе произвольно выбираем одну из этих ячеек, запоминаем элемент, который там находится, помещаем туда новый.# Смотрим в ячейку, на которую указывает другая хеш-функция от элемента, который запомнили, если она свободна, помещаем его в нее. # Иначе запоминаем элемент из хэшэтой ячейки, кладем туда старый. Проверяем, не зациклились ли мы.# Если не зациклились, то продолжаем данную процедуру поиска свободного места пока не найдем свободное место или зациклимся.# Иначе выбираем <tex>2</tex> новые хеш-функции и перехешируем все добавленные элементы.# Также после добавления нужно увеличить размер таблицыв случае если она заполнена.
Один из способов доказательства третьего утверждения использует теорию случайных графов. Это делается через неориентированный "кукушкин граф"Есть другие алгоритмы, где каждой ячейке которые используют несколько хеш-таблицы соответствует ровно одна вершинафункций, а каждому добавленному элементу — ребро в частности [[Фильтр Блума|фильтр Блума]], эффективная по памяти структура данных для нечётких множеств. Альтернативная структура данных для задач с концами в вершинахтеми же нечёткими множествами, основанная на кукушкином хешировании, соответствующих ячейкамназываемая кукушкиным фильтром, использует даже меньшую память и (в которые указывают хеш-функции отличие от классических фильтров Блума) позволяет удаление элемента, не только вставку и проверку существования. При этом элемент будет добавлен без перехеширования тогда и только тогдаОднако теоретический анализ этих методов проведён существенно слабее, чем анализ фильтров Блума<ref>''Bin Fan, когда после добавления нового ребра граф будет оставаться псевдолесомMichael Kaminsky, то есть каждая его компонента связности будет содержать не более одного циклаDavid Andersen'' Cuckoo Filter: Better Than Bloom // ;login:. — USENIX, 2013. — Т. 38, вып. 4. — С. 36–40.</ref>.
Таким образом Исследования, проведённые Жуковским, Хеманом и Бонзом<ref>''Marcin Zukowski, Sandor Heman, Peter Boncz'' Architecture-Conscious Hashing. — Proceedings of the International Workshop on Data Management on New Hardware (DaMoN), 2006.</ref>, показали, что кукушкино хеширование кукушки является одним из самых быстрых способов существенно быстрее метода цепочек для малых хеш-таблиц, находящихся в кэше современных процессоров. Кеннет Росс<ref>''Kenneth Ross'' Efficient Hash Probes on Modern Processors. — IBM Research Report RC24100, 2006.</ref> показал блочную версию кукушкиного хеширования(блок содержит более одного ключа), который работает быстрее обычных методов для больших хеш-таблиц в случае высокого коэффициента загрузки. Скорость работы блочной версии кукушкиной хеш-таблицы позднее исследовал Аскитис по сравнению с другими схемами хэширования. Обзор Мутцемахера<ref>''M. Mitzenmacher.'' Proceedings of of the 17th Annual European Symposium on Algorithms (ESA). — 2009.</ref> представляет открытые проблемы, связанные с кукушкиным хешированием. Самый большой минуc {{---}} потраченная память. Чтобы гарантировать <tex>O(n)</tex> по времени, нужно чтобы пары ключ/значение занимали не более <tex>50\%</tex> памяти, потому что вытеснение старых элементов становится трудоемким. Также, добавление каждой новой хеш-функции значительно увеличивает среднюю скорость заполнения таблицы. ==См. также==* [[Хеш-таблица]]* [[Разрешение коллизий]]* [[Идеальное хеширование]] ==Примечания==<references/> ==Источники информации==* [http://en.wikipedia.org/wiki/Cuckoo_hashing Wikipedia — Cuckoo hashing]* [http://www.cs.cmu.edu/afs/cs.cmu.edu/project/aladdin/wwwlocal/hash/PaRo01.pdf Cuckoo hashing — Pagh, Rasmus; Rodler, Flemming Friche (2001) (PDF, PS)] == Примеры ==* [https://github.com/efficient/libcuckoo Concurrent high-performance Cuckoo hashtable written in C++]* [http://sourceforge.net/projects/cuckoo-cpp/ Cuckoo hash map written in C++]* [http://www.theiling.de/projects/lookuptable.html Static cuckoo hashtable generator for C/C++]* [https://github.com/joacima/Cuckoo-hash-map/blob/master/CuckooHashMap.java Generic Cuckoo hashmap in Java]* [http://hackage.haskell.org/packages/archive/hashtables/latest/doc/html/Data-HashTable-ST-Cuckoo.html Cuckoo hash table written in Haskell]* [https://github.com/salviati/cuckoo Cuckoo hashing for Go]
==Источники==
* [http://en.wikipedia.org/wiki/Cuckoo_hashing Wikipedia, the free encyclopedia]
* [http://www.cs.cmu.edu/afs/cs.cmu.edu/project/aladdin/wwwlocal/hash/PaRo01.pdf Pagh, Rasmus; Rodler, Flemming Friche (2001) (PDF, PS)]
rollbackEdits.php mass rollback
[[Image:cuckoo.png|thumb|Пример хеширования кукушки. Стрелки показывают второе возможное место элементов. Если нам надо будет вставить новый элемент на место А, то мы поместим А в его вторую ячейку, занятую В, а В переместим в его вторую ячейку, которая сейчас свободна. А вот помещение нового элемента на место Н не получится: так как Н — часть цикла, добавленный элемент будет вытеснен после прохода по циклу.]]
'''Хеширование кукушки''' — (англ. ''Cuckoo hashing'') {{---}} один из способов [[Разрешение коллизий|борьбы с коллизиями ]] при создании [[Хеш-таблица|хеш-таблицы]].
==Алгоритм==
Основная идея хеширования кукушки — использование двух хеш-функций вместо одной (далее <mathtex>h_1(x)</mathtex> и <mathtex>h_2(x)</mathtex>). Так же Также есть вариант алгоритма, в котором используются две хеш-таблицы, и первая хеш-функция указывает на ячейку из первой таблицы, а вторая — из второй. Рассмотрим алгоритмы функций <tex>add(x), deleteremove(x) </tex> и exists<tex>contains(x)</tex>.
===='''Remove'''====Удаляет элемент с ключом <tex>x</tex> из хэш-таблицы. # Смотрим ячейки с индексами <mathtex>h_1(x)</mathtex> и <mathtex>h_2(x)</mathtex>.
# Если в одной из них есть искомый элемент, просто помечаем эту ячейку как свободную.
===='''ExistsContains''' — проверяет ====Проверяет на наличие элемента <tex>x </tex> в хэш-таблице
# Смотрим ячейки с индексами <mathtex>h_1(x)</mathtex> и <mathtex>h_2(x)</mathtex>.
# Если в одной из них есть искомый элемент, возвращаем true.
# Иначе возвращаем false.
== Зацикливание ==
Зацикливание может возникнуть при добавлении элемента. Пусть мы добавляем элемент <tex>x</tex>. И обе ячейки <tex>h_1(x)</tex> и <tex>h_2(x)</tex> заняты. Элемент <tex>x</tex> положили изначально в ячейку <tex>h_i(x)</tex>. Если в ходе перемещений элементов в таблице на очередном шаге мы опять хотим переместить элемент <tex>x</tex> в ячейку <tex>h_i(x)</tex>, чтобы в ячейку <tex>h_j(x) ~(i \ne j) </tex> мы смогли поместить какой-то <tex>y</tex> (это может произойти, если в ходе перемещений элемент <tex>x</tex> был перемещен в ячейку <tex>h_j(x)</tex>), то произошло зацикливание.
Например, зацикливание возникнет, если добавить в хэш-таблицу <tex>3</tex> элемента <tex>x,y,z</tex> у которых <tex>h_1(x)=h_1(y)=h_1(z)</tex> и <tex>h_2(x)=h_2(y)=h_2(z)</tex> .
Одним из способов решения проблемы зацикливания является смена хэш-функции, что было доказано Джоном Трампом<ref>https://eprint.iacr.org/2014/059.pdf</ref>
==Время работы алгоритма==
Удаление и проверка происходят за <tex>O(1)</tex> (что является основной особенностью данного типа хеширования), добавление в среднем происходит за <tex>O(1)</tex>. Первые два утверждения очевидны: требуется проверить всего лишь <tex>2 </tex> ячейки таблицы. {{ Утверждение|id = Cuckoo_hashing add|statement = Добавление в среднем происходит за <tex>O(1)</tex>. |proof = Один из способов доказательства данного утверждения использует теорию случайных графов. Это делается через неориентированный "кукушкин граф", где каждой ячейке хеш-таблицы соответствует ровно одна вершина, а каждому добавленному элементу — ребро с концами в вершинах, соответствующих ячейкам, в которые указывают хеш-функции элемента. При этом элемент будет добавлен без перехеширования тогда и только тогда, когда после добавления нового ребра граф будет оставаться псевдолесом, то есть каждая его компонента связности будет содержать не более одного цикла.}}Таким образом хеширование кукушки является одним из самых быстрых способов хеширования. ==Плюсы и минусы алгоритма==
[[Категория:Дискретная математика Алгоритмы и алгоритмыструктуры данных]][[Категория: Хеширование]]