http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&user=Kurkin&feedformat=atomВикиконспекты - Вклад участника [ru]2024-03-28T18:48:47ZВклад участникаMediaWiki 1.30.0http://neerc.ifmo.ru/wiki/index.php?title=Quotient_filter&diff=47919Quotient filter2015-06-06T21:08:59Z<p>Kurkin: </p>
<hr />
<div>'''Quotient filter''' {{---}} вероятностная структура данных, позволяющая проверить принадлежность элемента множеству. При этом существует возможность получить ложноположительное срабатывание (элемента в множестве нет, но структура данных сообщает, что он есть), но не ложноотрицательное (элемент в множестве есть, но структура данных сообщает, что его нет).<br />
<br />
Существует связь между размером хранилища и шансом ложноположительного срабатывания. Поддерживаются операции добавления нового элемента в множество. С увеличением размера хранимого множества повышается вероятность ложного срабатывания. <br />
Структуру разработал Michael Bender в 2011 году<ref>Bender, Michael A.; Farach-Colton, Martin; Johnson, Rob; Kuszmaul, Bradley C.; Medjedovic, Dzejla; Montes, Pablo; Shetty, Pradeep; Spillane, Richard P.; Zadok, Erez (June 2011).[http://vldb.org/pvldb/vol5/p1627_michaelabender_vldb2012.pdf "Don't thrash: how to cache your hash on flash" (PDF)]</ref> как замена [[:Фильтр_Блума|фильтра Блума]]. Фильтр используется для ускорения ответов в хранилище ключ-значение. <br />
<br />
==Описание структуры данных==<br />
[[Файл:filter.png|400px|thumb|right|Фильтр используется для ускорения ответов в хранилище ключ-значение. Пары ключ-значение содержатся в хранилище с медленным доступом. Фильтр отфильтровывает ненужные запросы в хранилище (запрос ключа которого точно нет в хранилище), что ускоряет его работу вцелом, но увеличевает потребление памяти]]<br />
<br />
В quotient filter хеш-функция возвращает <tex>p</tex> битовый хеш, последние <tex>r</tex> бит которого называются '''остатком''' (англ. ''remainder''), а <tex>q = p - r</tex> старших бит называются '''частным''' (англ. ''quotient''), отсюда название структуры quotient filter<ref>Knuth, Donald (1973). The Art of Computer Programming:Searching and Sorting, volume 3. Section 6.4, exercise 13: Addison Wesley</ref>. Фильтр представляет собой [[:Хеш-таблица|хеш-таблицу]], в которой харанится остаток и <tex>3</tex> бита дополнительной информации (удобно хранить в целочисленном типе, используя <tex>3</tex> старших бита под дополнительную информацию, а оставшиеся биты под остаток, накладывает ограничение на размер остатка). Биты дополнительной информации используются для разрешения ситуации, когда частное различных ключей указывает на одну ячейку в хеш-таблице. Размер хеш-таблицы составляет <tex>2^q</tex>, так как есть всего <tex>2^q</tex> разных частных.<br />
<br />
Пусть у нас есть ключ <tex>K</tex>, его хеш обозначим <tex>h(K)</tex>, остаток <tex>h_r</tex> и частное <tex>h_q</tex>. Попробуем поместить остаток в хеш-таблицу в ячейку с индексом <tex>h_q</tex>, называемую канонической. Возможно, ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). <br />
При полной коллизии мы получим ложноположительное срабатывание, но при частичной коллизии, с помощью дополнительных битов это избегается. Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа. Этот способ решения колизий схож с [[:Разрешение_коллизий|линейным методом разрешения колизий]]. <br />
<br />
Последовательность ячеек, имеющих одинаковые частные называется '''пробегом''' (англ. ''run''). Возможно, что начало пробега не занимает канонический слот, если он уже занят каким-то другим пробегом.<br />
<br />
Пробег, у которого первый элемент занимает каноническую ячейку, является началом кластера. Кластер {{---}} объединение последовательных пробегов, концом кластера является пустая ячейка или начало другого кластера.<br />
<br />
Три дополнительных бита имеют следующие функции:<br />
* бит занятости {{---}} равен единице, если ячейка является канонической для некого ключа в фильтре, сохраненого необязательно в этой ячейке,<br />
* бит продолжения {{---}} равен единице, если ячейка занята, но не первым элементов пробеге,<br />
* бит сдвига {{---}} равен единице, если пробег сдвинут относительно канонического слота.<br />
<br />
[[Файл:Quotient Filter.png|500px|thumb|right|Пример последовательной вставки элементов <tex> b, f, e, c, d, a</tex>]]<br />
{| class="wikitable" border=1<br />
|+<br />
|-align="center" bgcolor=#EEEEFF <br />
! Бит занятости || Бит Продолжения || Бит сдвига || Описание <br />
|-align="center" bgcolor=#FFFFFF<br />
|0||0||0||style="text-align:left;"|Пустая ячейка.<br />
|-align="center" bgcolor=#FFFFFF<br />
|0||0||1||style="text-align:left;"|Ячейка содержит начало пробега, сдвинутого относительно канонического слота.<br />
|-align="center" bgcolor=#FFFFFF<br />
|0||1||0||style="text-align:left;"|Не используется. <br />
|-align="center" bgcolor=#FFFFFF<br />
|0||1||1||style="text-align:left;"|Ячейка содержит элемент пробега (не первый), сдвинутого относительно канонического слота.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||0||0||style="text-align:left;"|Ячейка содержит первый элемет пробега в его каноническом слоте.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||0||1||style="text-align:left;"|Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||1||0||style="text-align:left;"|Не используется.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||1||1||style="text-align:left;"|Ячейка содержит элемент пробега (не первый), сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.<br />
|}<br />
<br />
=== Поиск ===<br />
<br />
Пусть мы ищем ключ <tex>K</tex>. Смотрим в ячейку с индексом <tex>h_q</tex>, это каноническая ячейка для частного <tex>h_q</tex>. Если в этой ячейке бит занятости не единица, то элемент точно не содержится в множестве.<br />
Если бит занятости единица, то нам нужно найти пробег для <tex>h_q</tex>. Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки с индексом <tex>h_q</tex> и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от ячейки с индексом <tex>h_q</tex> будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на <tex>1</tex>. После того как мы нашли начало кластера, пойдем от него влево, каждая ячейка с битом продолжения равным нулю говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нужный нам пробег для частного <tex>h_q</tex>. Если в этом пробеге содержится <tex>h_r</tex>, то <tex>K</tex>, вероятно, содержится в множестве, иначе <tex>K</tex> точно не содержится в множестве.<br />
<br />
=== Вставка ===<br />
<br />
Аналогично с поиском: найдем позицию для <tex>h_r</tex>, сдвигаем на одну позицию влево все эллементы кластера, начиная с выбранного, обновляем дополнительные биты. <br />
<br />
* Сдвиг не влияет на бит занятости. Выставляем бит занятости в ячейке <tex>h_q</tex> в единицу.<br />
* Если мы вставляем <tex>h_r</tex> в начало пробега, следовательно предыдущий элемент пробега стал вторым, у него нужно выставить бит продолжения.<br />
* Мы выставляем бит сдвига в единицу для каждой ячейки, что мы сдвинули.<br />
<br />
== Преимущества ==<br />
<br />
* Последовательное расположение данных. Можно загружать только <tex>1</tex> кластер, уменьшая количество кеш промахов.<br />
* Простое увеличение или уменьшение хеш-таблицы, достаточно перенести один бит из остатка в частное или наоборот.<br />
* Простое слияние двух фильтров.<br />
<br />
==См. также==<br />
<br />
*[[:Идеальное_хеширование|Идеальное хеширование]]<br />
*[[:Универсальное_семейство_хеш-функций|Универсальное хеширование]]<br />
<br />
==Примечания==<br />
<br />
<references /><br />
<br />
== Источники информации ==<br />
<br />
* [http://en.wikipedia.org/wiki/Quotient_filter Wikipedia — Quotient filter]<br />
* [http://habrahabr.ru/post/242285/ Habrahabr — Quotient filter]<br />
[[Категория: Дискретная математика и алгоритмы ]]<br />
[[Категория: Хеширование]]<br />
[[Категория: Структуры данных]]</div>Kurkinhttp://neerc.ifmo.ru/wiki/index.php?title=Quotient_filter&diff=47918Quotient filter2015-06-06T21:07:23Z<p>Kurkin: </p>
<hr />
<div>'''Quotient filter''' {{---}} вероятностная структура данных, позволяющая проверить принадлежность элемента множеству. При этом существует возможность получить ложноположительное срабатывание (элемента в множестве нет, но структура данных сообщает, что он есть), но не ложноотрицательное (элемент в множестве есть, но структура данных сообщает, что его нет).<br />
<br />
Существует связь между размером хранилища и шансом ложноположительного срабатывания. Поддерживаются операции добавления нового элемента в множество. С увеличением размера хранимого множества повышается вероятность ложного срабатывания. <br />
Структуру разработал Michael Bender в 2011 году<ref>Bender, Michael A.; Farach-Colton, Martin; Johnson, Rob; Kuszmaul, Bradley C.; Medjedovic, Dzejla; Montes, Pablo; Shetty, Pradeep; Spillane, Richard P.; Zadok, Erez (June 2011).[http://vldb.org/pvldb/vol5/p1627_michaelabender_vldb2012.pdf "Don't thrash: how to cache your hash on flash" (PDF)]</ref> как замена [[:Фильтр_Блума|фильтра Блума]]. Фильтр используется для ускорения ответов в хранилище ключ-значение. <br />
<br />
==Описание структуры данных==<br />
[[Файл:filter.png|400px|thumb|right|Фильтр используется для ускорения ответов в хранилище ключ-значение. Пары ключ-значение содержатся в хранилище с медленным доступом. Фильтр отфильтровывает ненужные запросы в хранилище (запрос ключа которого точно нет в хранилище), что ускоряет его работу вцелом, но увеличевает потребление памяти]]<br />
<br />
В quotient filter хеш-функция возвращает <tex>p</tex> битовый хеш, последние <tex>r</tex> бит которого называются '''остатком''' (англ. ''remainder''), а <tex>q = p - r</tex> старших бит называются '''частным''' (англ. ''quotient''), отсюда название структуры quotient filter<ref>Knuth, Donald (1973). The Art of Computer Programming:Searching and Sorting, volume 3. Section 6.4, exercise 13: Addison Wesley</ref>. Фильтр представляет собой [[:Хеш-таблица|хеш-таблицу]], в которой харанится остаток и <tex>3</tex> бита дополнительной информации (удобно хранить в целочисленном типе, используя <tex>3</tex> старших бита под дополнительную информацию, а оставшиеся биты под остаток, накладывает ограничение на размер остатка). Биты дополнительной информации используются для разрешения ситуации, когда частное различных ключей указывает на одну ячейку в хеш-таблице. Размер хеш-таблицы составляет <tex>2^q</tex>, так как есть всего <tex>2^q</tex> разных частных.<br />
<br />
Пусть у нас есть ключ <tex>K</tex>, его хеш обозначим <tex>h(K)</tex>, остаток <tex>h_r</tex> и частное <tex>h_q</tex>. Попробуем поместить остаток в хеш-таблицу в ячейку с индексом <tex>h_q</tex>, называемую канонической. Возможно, ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). <br />
При полной коллизии мы получим ложноположительное срабатывание, но при частичной коллизии с помощью дополнительных битов это избегается. Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа. Этот способ решения колизий схож с [[:Разрешение_коллизий|линейным методом разрешения колизий]]. <br />
<br />
Последовательность ячеек, имеющих одинаковые частные называется '''пробегом''' (англ. ''run''). Возможно, что начало пробега не занимает канонический слот, если он уже занят каким-то другим пробегом.<br />
<br />
Пробег, у которого первый элемент занимает каноническую ячейку, является началом кластера. Кластер {{---}} объединение последовательных пробегов, концом кластера является пустая ячейка или начало другого кластера.<br />
<br />
Три дополнительных бита имеют следующие функции:<br />
* бит занятости {{---}} равен единице, если ячейка является канонической для некого ключа в фильтре, сохраненого необязательно в этой ячейке,<br />
* бит продолжения {{---}} равен единице, если ячейка занята, но не первым элементов пробеге,<br />
* бит сдвига {{---}} равен единице, если пробег сдвинут относительно канонического слота.<br />
<br />
[[Файл:Quotient Filter.png|500px|thumb|right|Пример последовательной вставки элементов <tex> b, f, e, c, d, a</tex>]]<br />
{| class="wikitable" border=1<br />
|+<br />
|-align="center" bgcolor=#EEEEFF <br />
! Бит занятости || Бит Продолжения || Бит сдвига || Описание <br />
|-align="center" bgcolor=#FFFFFF<br />
|0||0||0||style="text-align:left;"|Пустая ячейка.<br />
|-align="center" bgcolor=#FFFFFF<br />
|0||0||1||style="text-align:left;"|Ячейка содержит начало пробега, сдвинутого относительно канонического слота.<br />
|-align="center" bgcolor=#FFFFFF<br />
|0||1||0||style="text-align:left;"|Не используется. <br />
|-align="center" bgcolor=#FFFFFF<br />
|0||1||1||style="text-align:left;"|Ячейка содержит элемент пробега (не первый), сдвинутого относительно канонического слота.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||0||0||style="text-align:left;"|Ячейка содержит первый элемет пробега в его каноническом слоте.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||0||1||style="text-align:left;"|Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||1||0||style="text-align:left;"|Не используется.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||1||1||style="text-align:left;"|Ячейка содержит элемент пробега (не первый), сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.<br />
|}<br />
<br />
=== Поиск ===<br />
<br />
Пусть мы ищем ключ <tex>K</tex>. Смотрим в ячейку с индексом <tex>h_q</tex>, это каноническая ячейка для частного <tex>h_q</tex>. Если в этой ячейке бит занятости не единица, то элемент точно не содержится в множестве.<br />
Если бит занятости единица, то нам нужно найти пробег для <tex>h_q</tex>. Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки с индексом <tex>h_q</tex> и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от ячейки с индексом <tex>h_q</tex> будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на <tex>1</tex>. После того как мы нашли начало кластера, пойдем от него влево, каждая ячейка с битом продолжения равным нулю говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нужный нам пробег для частного <tex>h_q</tex>. Если в этом пробеге содержится <tex>h_r</tex>, то <tex>K</tex>, вероятно, содержится в множестве, иначе <tex>K</tex> точно не содержится в множестве.<br />
<br />
=== Вставка ===<br />
<br />
Аналогично с поиском: найдем позицию для <tex>h_r</tex>, сдвигаем на одну позицию влево все эллементы кластера, начиная с выбранного, обновляем дополнительные биты. <br />
<br />
* Сдвиг не влияет на бит занятости. Выставляем бит занятости в ячейке <tex>h_q</tex> в единицу.<br />
* Если мы вставляем <tex>h_r</tex> в начало пробега, следовательно предыдущий элемент пробега стал вторым, у него нужно выставить бит продолжения.<br />
* Мы выставляем бит сдвига в единицу для каждой ячейки, что мы сдвинули.<br />
<br />
== Преимущества ==<br />
<br />
* Последовательное расположение данных. Можно загружать только <tex>1</tex> кластер, уменьшая количество кеш промахов.<br />
* Простое увеличение или уменьшение хеш-таблицы, достаточно перенести один бит из остатка в частное или наоборот.<br />
* Простое слияние двух фильтров.<br />
<br />
==См. также==<br />
<br />
*[[:Идеальное_хеширование|Идеальное хеширование]]<br />
*[[:Универсальное_семейство_хеш-функций|Универсальное хеширование]]<br />
<br />
==Примечания==<br />
<br />
<references /><br />
<br />
== Источники информации ==<br />
<br />
* [http://en.wikipedia.org/wiki/Quotient_filter Wikipedia — Quotient filter]<br />
* [http://habrahabr.ru/post/242285/ Habrahabr — Quotient filter]<br />
[[Категория: Дискретная математика и алгоритмы ]]<br />
[[Категория: Хеширование]]<br />
[[Категория: Структуры данных]]</div>Kurkinhttp://neerc.ifmo.ru/wiki/index.php?title=Quotient_filter&diff=47915Quotient filter2015-06-06T21:05:14Z<p>Kurkin: </p>
<hr />
<div>'''Quotient filter''' {{---}} вероятностная структура данных, позволяющая проверить принадлежность элемента множеству. При этом существует возможность получить ложноположительное срабатывание (элемента в множестве нет, но структура данных сообщает, что он есть), но не ложноотрицательное (элемент в множестве есть, но структура данных сообщает, что его нет).<br />
<br />
Существует связь между размером хранилища и шансом ложноположительного срабатывания. Поддерживаются операции добавления нового элемента в множество. С увеличением размера хранимого множества повышается вероятность ложного срабатывания. <br />
Структуру разработал Michael Bender в 2011 году<ref>Bender, Michael A.; Farach-Colton, Martin; Johnson, Rob; Kuszmaul, Bradley C.; Medjedovic, Dzejla; Montes, Pablo; Shetty, Pradeep; Spillane, Richard P.; Zadok, Erez (June 2011).[http://vldb.org/pvldb/vol5/p1627_michaelabender_vldb2012.pdf "Don't thrash: how to cache your hash on flash" (PDF)]</ref> как замена [[:Фильтр_Блума|фильтра Блума]]. Фильтр используется для ускорения ответов в хранилище ключ-значение. <br />
<br />
==Описание структуры данных==<br />
[[Файл:filter.png|400px|thumb|right|Фильтр используется для ускорения ответов в хранилище ключ-значение. Пары ключ-значение содержатся в хранилище с медленным доступом. Фильтр отфильтровывает ненужные запросы в хранилище (запрос ключа которого точно нет в хранилище), что ускоряет его работу вцелом, но увеличевает потребление памяти]]<br />
<br />
В quotient filter хеш-функция возвращает <tex>p</tex> битовый хеш, последние <tex>r</tex> бит которого называются '''остатком''' (англ. ''remainder''), а <tex>q = p - r</tex> старших бит называются '''частным''' (англ. ''quotient''), отсюда название структуры quotient filter<ref>Knuth, Donald (1973). The Art of Computer Programming:Searching and Sorting, volume 3. Section 6.4, exercise 13: Addison Wesley</ref>. Фильтр представляет собой [[:Хеш-таблица|хеш-таблицу]], в которой харанится остаток и <tex>3</tex> бита дополнительной информации (удобно хранить в целочисленном типе, используя <tex>3</tex> старших бита под дополнительную информацию, а оставшиеся биты под остаток, накладывает ограничение на размер остатка). Они используются для разрешения ситуации, когда частное различных ключей указывает на одну ячейку в хеш-таблице. Размер хеш-таблицы составляет <tex>2^q</tex>, так как есть всего <tex>2^q</tex> разных частных.<br />
<br />
Пусть у нас есть ключ <tex>K</tex>, его хеш обозначим <tex>h(K)</tex>, остаток <tex>h_r</tex> и частное <tex>h_q</tex>. Попробуем поместить остаток в хеш-таблицу в ячейку с индексом <tex>h_q</tex>, называемую канонической. Возможно, ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). <br />
При полной коллизии мы получим ложноположительное срабатывание, но при частичной коллизии с помощью дополнительных битов это избегается. Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа. Этот способ решения колизий схож с [[:Разрешение_коллизий|линейным методом разрешения колизий]]. <br />
<br />
Последовательность ячеек, имеющих одинаковые частные называется '''пробегом''' (англ. ''run''). Возможно, что начало пробега не занимает канонический слот, если он уже занят каким-то другим пробегом.<br />
<br />
Пробег, у которого первый элемент занимает каноническую ячейку, является началом кластера. Кластер {{---}} объединение последовательных пробегов, концом кластера является пустая ячейка или начало другого кластера.<br />
<br />
Три дополнительных бита имеют следующие функции:<br />
* бит занятости {{---}} равен единице, если ячейка является канонической для некого ключа в фильтре, сохраненого необязательно в этой ячейке,<br />
* бит продолжения {{---}} равен единице, если ячейка занята, но не первым элементов пробеге,<br />
* бит сдвига {{---}} равен единице, если пробег сдвинут относительно канонического слота.<br />
<br />
[[Файл:Quotient Filter.png|500px|thumb|right|Пример последовательной вставки элементов <tex> b, f, e, c, d, a</tex>]]<br />
{| class="wikitable" border=1<br />
|+<br />
|-align="center" bgcolor=#EEEEFF <br />
! Бит занятости || Бит Продолжения || Бит сдвига || Описание <br />
|-align="center" bgcolor=#FFFFFF<br />
|0||0||0||style="text-align:left;"|Пустая ячейка.<br />
|-align="center" bgcolor=#FFFFFF<br />
|0||0||1||style="text-align:left;"|Ячейка содержит начало пробега, сдвинутого относительно канонического слота.<br />
|-align="center" bgcolor=#FFFFFF<br />
|0||1||0||style="text-align:left;"|Не используется. <br />
|-align="center" bgcolor=#FFFFFF<br />
|0||1||1||style="text-align:left;"|Ячейка содержит элемент пробега (не первый), сдвинутого относительно канонического слота.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||0||0||style="text-align:left;"|Ячейка содержит первый элемет пробега в его каноническом слоте.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||0||1||style="text-align:left;"|Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||1||0||style="text-align:left;"|Не используется.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||1||1||style="text-align:left;"|Ячейка содержит элемент пробега (не первый), сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.<br />
|}<br />
<br />
=== Поиск ===<br />
<br />
Пусть мы ищем ключ <tex>K</tex>. Смотрим в ячейку с индексом <tex>h_q</tex>, это каноническая ячейка для частного <tex>h_q</tex>. Если в этой ячейке бит занятости не единица, то элемент точно не содержится в множестве.<br />
Если бит занятости единица, то нам нужно найти пробег для <tex>h_q</tex>. Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки с индексом <tex>h_q</tex> и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от ячейки с индексом <tex>h_q</tex> будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на <tex>1</tex>. После того как мы нашли начало кластера, пойдем от него влево, каждая ячейка с битом продолжения равным нулю говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нужный нам пробег для частного <tex>h_q</tex>. Если в этом пробеге содержится <tex>h_r</tex>, то <tex>K</tex>, вероятно, содержится в множестве, иначе <tex>K</tex> точно не содержится в множестве.<br />
<br />
=== Вставка ===<br />
<br />
Аналогично с поиском: найдем позицию для <tex>h_r</tex>, сдвигаем на одну позицию влево все эллементы кластера, начиная с выбранного, обновляем дополнительные биты. <br />
<br />
* Сдвиг не влияет на бит занятости. Выставляем бит занятости в ячейке <tex>h_q</tex> в единицу.<br />
* Если мы вставляем <tex>h_r</tex> в начало пробега, следовательно предыдущий элемент пробега стал вторым, у него нужно выставить бит продолжения.<br />
* Мы выставляем бит сдвига в единицу для каждой ячейки, что мы сдвинули.<br />
<br />
== Преимущества ==<br />
<br />
* Последовательное расположение данных. Можно загружать только <tex>1</tex> кластер, уменьшая количество кеш промахов.<br />
* Простое увеличение или уменьшение хеш-таблицы, достаточно перенести один бит из остатка в частное или наоборот.<br />
* Простое слияние двух фильтров.<br />
<br />
==См. также==<br />
<br />
*[[:Идеальное_хеширование|Идеальное хеширование]]<br />
*[[:Универсальное_семейство_хеш-функций|Универсальное хеширование]]<br />
<br />
==Примечания==<br />
<br />
<references /><br />
<br />
== Источники информации ==<br />
<br />
* [http://en.wikipedia.org/wiki/Quotient_filter Wikipedia — Quotient filter]<br />
* [http://habrahabr.ru/post/242285/ Habrahabr — Quotient filter]<br />
[[Категория: Дискретная математика и алгоритмы ]]<br />
[[Категория: Хеширование]]<br />
[[Категория: Структуры данных]]</div>Kurkinhttp://neerc.ifmo.ru/wiki/index.php?title=Quotient_filter&diff=47902Quotient filter2015-06-06T20:34:59Z<p>Kurkin: </p>
<hr />
<div>'''Quotient filter''' {{---}} вероятностная структура данных, позволяющая проверить принадлежность элемента множеству. При этом существует возможность получить ложноположительное срабатывание (элемента в множестве нет, но структура данных сообщает, что он есть), но не ложноотрицательное (элемент в множестве есть, но структура данных сообщает, что его нет).<br />
<br />
Существует связь между размером хранилища и шансом ложноположительного срабатывания. Поддерживаются операции добавления нового элемента в множество. С увеличением размера хранимого множества повышается вероятность ложного срабатывания. <br />
Структуру разработал Michael Bender в 2011 году<ref>Bender, Michael A.; Farach-Colton, Martin; Johnson, Rob; Kuszmaul, Bradley C.; Medjedovic, Dzejla; Montes, Pablo; Shetty, Pradeep; Spillane, Richard P.; Zadok, Erez (June 2011).[http://vldb.org/pvldb/vol5/p1627_michaelabender_vldb2012.pdf "Don't thrash: how to cache your hash on flash" (PDF)]</ref> как замена [[:Фильтр_Блума|фильтра Блума]]. Фильтр используется для ускорения ответов в хранилище ключ-значение. <br />
<br />
==Описание структуры данных==<br />
[[Файл:filter.png|400px|thumb|right|Фильтр используется для ускорения ответов в хранилище ключ-значение. Пары ключ-значение содержатся в хранилище с медленным доступом. Фильтр отфильтровывает ненужные запросы в хранилище (запрос ключа которого точно нет в хранилище), что ускоряет его работу вцелом, но увеличевает потребление памяти]]<br />
<br />
Фильтр представляет собой [[:Хеш-таблица|хеш-таблицу]], в которой харанится часть ключа и <tex>3</tex> бита дополнительной информации. Они используются для разрешения ситуации, когда хеш различных ключей указывает на одну ячейку в хеш-таблице. В quotient filter хеш-функция возвращает <tex>p</tex> битовый хеш, последние r бит которого называются '''остатком''' (англ. ''remainder''), а <tex>q = p - r</tex> старших бит называются '''частным''' (англ. ''quotient''), отсюда название структуры Quotient filter<ref>Knuth, Donald (1973). The Art of Computer Programming:Searching and Sorting, volume 3. Section 6.4, exercise 13: Addison Wesley</ref>. Размер хеш-таблицы составляет <tex>2^q</tex>, так как есть всего <tex>2^q</tex> разных частных.<br />
<br />
Пусть у нас есть ключ <tex>K</tex>, его хеш обозначим <tex>h(K)</tex>, остаток <tex>h_r</tex> и частное <tex>h_q</tex>. Попробуем поместить остаток в хеш-таблицу в ячейку с индексом <tex>h_q</tex>, называемую канонической. Возможно, ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа. Этот способ решения колизий схож с [[:Разрешение_коллизий|линейным методом разрешения колизий]].<br />
<br />
Последовательность ячеек, имеющих одинаковые частные называется '''пробегом''' (англ. ''run''). Возможно, что начало пробега не занимает канонический слот, если он уже занят каким-то другим пробегом. <br />
<br />
Пробег, у которого первый элемент занимает каноническую ячейку, является началом кластера. Кластер {{---}} объединение последовательных пробегов, концом кластера является пустая ячейка или начало другого кластера.<br />
<br />
Три дополнительных бита имеют следующие функции:<br />
* бит занятости {{---}} равен единице, если ячейка является канонической для некого ключа в фильтре, сохраненого необязательно в этой ячейке,<br />
* бит продолжения {{---}} равен единице, если ячейка занята, но не первым элементов пробеге,<br />
* бит сдвига {{---}} равен единице, если пробег сдвинут относительно канонического слота.<br />
<br />
[[Файл:Quotient Filter.png|500px|thumb|right|Пример последовательной вставки элементов <tex> b, f, e, c, d, a</tex>]]<br />
{| class="wikitable" border=1<br />
|+<br />
|-align="center" bgcolor=#EEEEFF <br />
! Бит занятости || Бит Продолжения || Бит сдвига || Описание <br />
|-align="center" bgcolor=#FFFFFF<br />
|0||0||0||style="text-align:left;"|Пустая ячейка.<br />
|-align="center" bgcolor=#FFFFFF<br />
|0||0||1||style="text-align:left;"|Ячейка содержит начало пробега, сдвинутого относительно канонического слота.<br />
|-align="center" bgcolor=#FFFFFF<br />
|0||1||0||style="text-align:left;"|Не используется. <br />
|-align="center" bgcolor=#FFFFFF<br />
|0||1||1||style="text-align:left;"|Ячейка содержит элемент пробега (не первый), сдвинутого относительно канонического слота.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||0||0||style="text-align:left;"|Ячейка содержит первый элемет пробега в его каноническом слоте.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||0||1||style="text-align:left;"|Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||1||0||style="text-align:left;"|Не используется.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||1||1||style="text-align:left;"|Ячейка содержит элемент пробега (не первый), сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.<br />
|}<br />
<br />
=== Поиск ===<br />
<br />
Пусть мы ищем ключ <tex>K</tex>. Смотрим в ячейку с индексом <tex>h_q</tex>, это каноническая ячейка для частного <tex>h_q</tex>. Если в этой ячейке бит занятости не единица, то элемент точно не содержится в множестве.<br />
Если бит занятости единица, то нам нужно найти пробег для <tex>h_q</tex>. Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки с индексом <tex>h_q</tex> и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от ячейки с индексом <tex>h_q</tex> будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на <tex>1</tex>. После того как мы нашли начало кластера, пойдем от него влево, каждая ячейка с битом продолжения равным нулю говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нужный нам пробег для частного <tex>h_q</tex>. Если в этом пробеге содержится <tex>h_r</tex>, то <tex>K</tex>, вероятно, содержится в множестве, иначе <tex>K</tex> точно не содержится в множестве.<br />
<br />
=== Вставка ===<br />
<br />
Аналогично с поиском: найдем позицию для <tex>h_r</tex>, сдвигаем на одну позицию влево все эллементы кластера, начиная с выбранного, обновляем дополнительные биты. <br />
<br />
* Сдвиг не влияет на бит занятости. Выставляем бит занятости в ячейке <tex>h_q</tex> в единицу.<br />
* Если мы вставляем <tex>h_r</tex> в начало пробега, следовательно предыдущий элемент пробега стал вторым, у него нужно выставить бит продолжения.<br />
* Мы выставляем бит сдвига в единицу для каждой ячейки, что мы сдвинули.<br />
<br />
== Преимущества ==<br />
<br />
* Последовательное расположение данных. Можно загружать только <tex>1</tex> кластер, уменьшая количество кеш промахов.<br />
* Простое увеличение или уменьшение хеш-таблицы, достаточно перенести один бит из остатка в частное или наоборот.<br />
* Простое слияние двух фильтров.<br />
<br />
==См. также==<br />
<br />
*[[:Идеальное_хеширование|Идеальное хеширование]]<br />
*[[:Универсальное_семейство_хеш-функций|Универсальное хеширование]]<br />
<br />
==Примечания==<br />
<br />
<references /><br />
<br />
== Источники информации ==<br />
<br />
* [http://en.wikipedia.org/wiki/Quotient_filter Wikipedia — Quotient filter]<br />
* [http://habrahabr.ru/post/242285/ Habrahabr — Quotient filter]<br />
[[Категория: Дискретная математика и алгоритмы ]]<br />
[[Категория: Хеширование]]<br />
[[Категория: Структуры данных]]</div>Kurkinhttp://neerc.ifmo.ru/wiki/index.php?title=Quotient_filter&diff=47900Quotient filter2015-06-06T20:34:11Z<p>Kurkin: </p>
<hr />
<div>'''Quotient filter''' {{---}} вероятностная структура данных, позволяющая проверить принадлежность элемента множеству. При этом существует возможность получить ложноположительное срабатывание (элемента в множестве нет, но структура данных сообщает, что он есть), но не ложноотрицательное (элемент в множестве есть, но структура данных сообщает, что его нет).<br />
<br />
Существует связь между размером хранилища и шансом ложноположительного срабатывания. Поддерживаются операции добавления нового элемента в множество. С увеличением размера хранимого множества повышается вероятность ложного срабатывания. <br />
Структуру разработал Michael Bender в 2011 году<ref>Bender, Michael A.; Farach-Colton, Martin; Johnson, Rob; Kuszmaul, Bradley C.; Medjedovic, Dzejla; Montes, Pablo; Shetty, Pradeep; Spillane, Richard P.; Zadok, Erez (June 2011).[http://vldb.org/pvldb/vol5/p1627_michaelabender_vldb2012.pdf "Don't thrash: how to cache your hash on flash" (PDF)]</ref> как замена [[:Фильтр_Блума|фильтра Блума]]. Фильтр используется для ускорения ответов в хранилище ключ-значение. <br />
<br />
==Описание структуры данных==<br />
[[Файл:filter.png|400px|thumb|left|Фильтр используется для ускорения ответов в хранилище ключ-значение. Пары ключ-значение содержатся в хранилище с медленным доступом. Фильтр отфильтровывает ненужные запросы в хранилище (запрос ключа которого точно нет в хранилище), что ускоряет его работу вцелом, но увеличевает потребление памяти]]<br />
<br />
Фильтр представляет собой [[:Хеш-таблица|хеш-таблицу]], в которой харанится часть ключа и <tex>3</tex> бита дополнительной информации. Они используются для разрешения ситуации, когда хеш различных ключей указывает на одну ячейку в хеш-таблице. В quotient filter хеш-функция возвращает <tex>p</tex> битовый хеш, последние r бит которого называются '''остатком''' (англ. ''remainder''), а <tex>q = p - r</tex> старших бит называются '''частным''' (англ. ''quotient''), отсюда название структуры Quotient filter<ref>Knuth, Donald (1973). The Art of Computer Programming:Searching and Sorting, volume 3. Section 6.4, exercise 13: Addison Wesley</ref>. Размер хеш-таблицы составляет <tex>2^q</tex>, так как есть всего <tex>2^q</tex> разных частных.<br />
<br />
Пусть у нас есть ключ <tex>K</tex>, его хеш обозначим <tex>h(K)</tex>, остаток <tex>h_r</tex> и частное <tex>h_q</tex>. Попробуем поместить остаток в хеш-таблицу в ячейку с индексом <tex>h_q</tex>, называемую канонической. Возможно, ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа. Этот способ решения колизий схож с [[:Разрешение_коллизий|линейным методом разрешения колизий]].<br />
<br />
Последовательность ячеек, имеющих одинаковые частные называется '''пробегом''' (англ. ''run''). Возможно, что начало пробега не занимает канонический слот, если он уже занят каким-то другим пробегом. <br />
<br />
Пробег, у которого первый элемент занимает каноническую ячейку, является началом кластера. Кластер {{---}} объединение последовательных пробегов, концом кластера является пустая ячейка или начало другого кластера.<br />
<br />
Три дополнительных бита имеют следующие функции:<br />
* бит занятости {{---}} равен единице, если ячейка является канонической для некого ключа в фильтре, сохраненого необязательно в этой ячейке,<br />
* бит продолжения {{---}} равен единице, если ячейка занята, но не первым элементов пробеге,<br />
* бит сдвига {{---}} равен единице, если пробег сдвинут относительно канонического слота.<br />
<br />
[[Файл:Quotient Filter.png|500px|thumb|right|Пример последовательной вставки элементов <tex> b, f, e, c, d, a</tex>]]<br />
{| class="wikitable" border=1<br />
|+<br />
|-align="center" bgcolor=#EEEEFF <br />
! Бит занятости || Бит Продолжения || Бит сдвига || Описание <br />
|-align="center" bgcolor=#FFFFFF<br />
|0||0||0||style="text-align:left;"|Пустая ячейка.<br />
|-align="center" bgcolor=#FFFFFF<br />
|0||0||1||style="text-align:left;"|Ячейка содержит начало пробега, сдвинутого относительно канонического слота.<br />
|-align="center" bgcolor=#FFFFFF<br />
|0||1||0||style="text-align:left;"|Не используется. <br />
|-align="center" bgcolor=#FFFFFF<br />
|0||1||1||style="text-align:left;"|Ячейка содержит элемент пробега (не первый), сдвинутого относительно канонического слота.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||0||0||style="text-align:left;"|Ячейка содержит первый элемет пробега в его каноническом слоте.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||0||1||style="text-align:left;"|Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||1||0||style="text-align:left;"|Не используется.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||1||1||style="text-align:left;"|Ячейка содержит элемент пробега (не первый), сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.<br />
|}<br />
<br />
=== Поиск ===<br />
<br />
Пусть мы ищем ключ <tex>K</tex>. Смотрим в ячейку с индексом <tex>h_q</tex>, это каноническая ячейка для частного <tex>h_q</tex>. Если в этой ячейке бит занятости не единица, то элемент точно не содержится в множестве.<br />
Если бит занятости единица, то нам нужно найти пробег для <tex>h_q</tex>. Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки с индексом <tex>h_q</tex> и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от ячейки с индексом <tex>h_q</tex> будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на <tex>1</tex>. После того как мы нашли начало кластера, пойдем от него влево, каждая ячейка с битом продолжения равным нулю говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нужный нам пробег для частного <tex>h_q</tex>. Если в этом пробеге содержится <tex>h_r</tex>, то <tex>K</tex>, вероятно, содержится в множестве, иначе <tex>K</tex> точно не содержится в множестве.<br />
<br />
=== Вставка ===<br />
<br />
Аналогично с поиском: найдем позицию для <tex>h_r</tex>, сдвигаем на одну позицию влево все эллементы кластера, начиная с выбранного, обновляем дополнительные биты. <br />
<br />
* Сдвиг не влияет на бит занятости. Выставляем бит занятости в ячейке <tex>h_q</tex> в единицу.<br />
* Если мы вставляем <tex>h_r</tex> в начало пробега, следовательно предыдущий элемент пробега стал вторым, у него нужно выставить бит продолжения.<br />
* Мы выставляем бит сдвига в единицу для каждой ячейки, что мы сдвинули.<br />
<br />
== Преимущества ==<br />
<br />
* Последовательное расположение данных. Можно загружать только <tex>1</tex> кластер, уменьшая количество кеш промахов.<br />
* Простое увеличение или уменьшение хеш-таблицы, достаточно перенести один бит из остатка в частное или наоборот.<br />
* Простое слияние двух фильтров.<br />
<br />
==См. также==<br />
<br />
*[[:Идеальное_хеширование|Идеальное хеширование]]<br />
*[[:Универсальное_семейство_хеш-функций|Универсальное хеширование]]<br />
<br />
==Примечания==<br />
<br />
<references /><br />
<br />
== Источники информации ==<br />
<br />
* [http://en.wikipedia.org/wiki/Quotient_filter Wikipedia — Quotient filter]<br />
* [http://habrahabr.ru/post/242285/ Habrahabr — Quotient filter]<br />
[[Категория: Дискретная математика и алгоритмы ]]<br />
[[Категория: Хеширование]]<br />
[[Категория: Структуры данных]]</div>Kurkinhttp://neerc.ifmo.ru/wiki/index.php?title=Quotient_filter&diff=47898Quotient filter2015-06-06T20:31:07Z<p>Kurkin: </p>
<hr />
<div>[[Файл:filter.png|400px|thumb|right|Фильтр используется для ускорения ответов в хранилище ключ-значение. Пары ключ-значение содержатся в хранилище с медленным доступом. Фильтр отфильтровывает ненужные запросы в хранилище (запрос ключа которого точно нет в хранилище), что ускоряет его работу вцелом, но увеличевает потребление памяти]]<br />
'''Quotient filter''' {{---}} вероятностная структура данных, позволяющая проверить принадлежность элемента множеству. При этом существует возможность получить ложноположительное срабатывание (элемента в множестве нет, но структура данных сообщает, что он есть), но не ложноотрицательное (элемент в множестве есть, но структура данных сообщает, что его нет).<br />
<br />
Существует связь между размером хранилища и шансом ложноположительного срабатывания. Поддерживаются операции добавления нового элемента в множество. С увеличением размера хранимого множества повышается вероятность ложного срабатывания. <br />
Структуру разработал Michael Bender в 2011 году<ref>Bender, Michael A.; Farach-Colton, Martin; Johnson, Rob; Kuszmaul, Bradley C.; Medjedovic, Dzejla; Montes, Pablo; Shetty, Pradeep; Spillane, Richard P.; Zadok, Erez (June 2011).[http://vldb.org/pvldb/vol5/p1627_michaelabender_vldb2012.pdf "Don't thrash: how to cache your hash on flash" (PDF)]</ref> как замена [[:Фильтр_Блума|фильтра Блума]]. Фильтр используется для ускорения ответов в хранилище ключ-значение. <br />
<br />
==Описание структуры данных==<br />
<br />
Фильтр представляет собой [[:Хеш-таблица|хеш-таблицу]], в которой харанится часть ключа и <tex>3</tex> бита дополнительной информации. Они используются для разрешения ситуации, когда хеш различных ключей указывает на одну ячейку в хеш-таблице. В quotient filter хеш-функция возвращает <tex>p</tex> битовый хеш, последние r бит которого называются '''остатком''' (англ. ''remainder''), а <tex>q = p - r</tex> старших бит называются '''частным''' (англ. ''quotient''), отсюда название структуры Quotient filter<ref>Knuth, Donald (1973). The Art of Computer Programming:Searching and Sorting, volume 3. Section 6.4, exercise 13: Addison Wesley</ref>. Размер хеш-таблицы составляет <tex>2^q</tex>, так как есть всего <tex>2^q</tex> разных частных.<br />
<br />
Пусть у нас есть ключ <tex>K</tex>, его хеш обозначим <tex>h(K)</tex>, остаток <tex>h_r</tex> и частное <tex>h_q</tex>. Попробуем поместить остаток в хеш-таблицу в ячейку с индексом <tex>h_q</tex>, называемую канонической. Возможно, ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа. Этот способ решения колизий схож с [[:Разрешение_коллизий|линейным методом разрешения колизий]].<br />
<br />
Последовательность ячеек, имеющих одинаковые частные называется '''пробегом''' (англ. ''run''). Возможно, что начало пробега не занимает канонический слот, если он уже занят каким-то другим пробегом. <br />
<br />
Пробег, у которого первый элемент занимает каноническую ячейку, является началом кластера. Кластер {{---}} объединение последовательных пробегов, концом кластера является пустая ячейка или начало другого кластера.<br />
<br />
Три дополнительных бита имеют следующие функции:<br />
* бит занятости {{---}} равен единице, если ячейка является канонической для некого ключа в фильтре, сохраненого необязательно в этой ячейке,<br />
* бит продолжения {{---}} равен единице, если ячейка занята, но не первым элементов пробеге,<br />
* бит сдвига {{---}} равен единице, если пробег сдвинут относительно канонического слота.<br />
<br />
[[Файл:Quotient Filter.png|500px|thumb|right|Пример последовательной вставки элементов <tex> b, f, e, c, d, a</tex>]]<br />
{| class="wikitable" border=1<br />
|+<br />
|-align="center" bgcolor=#EEEEFF <br />
! Бит занятости || Бит Продолжения || Бит сдвига || Описание <br />
|-align="center" bgcolor=#FFFFFF<br />
|0||0||0||style="text-align:left;"|Пустая ячейка.<br />
|-align="center" bgcolor=#FFFFFF<br />
|0||0||1||style="text-align:left;"|Ячейка содержит начало пробега, сдвинутого относительно канонического слота.<br />
|-align="center" bgcolor=#FFFFFF<br />
|0||1||0||style="text-align:left;"|Не используется. <br />
|-align="center" bgcolor=#FFFFFF<br />
|0||1||1||style="text-align:left;"|Ячейка содержит элемент пробега (не первый), сдвинутого относительно канонического слота.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||0||0||style="text-align:left;"|Ячейка содержит первый элемет пробега в его каноническом слоте.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||0||1||style="text-align:left;"|Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||1||0||style="text-align:left;"|Не используется.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||1||1||style="text-align:left;"|Ячейка содержит элемент пробега (не первый), сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.<br />
|}<br />
<br />
=== Поиск ===<br />
<br />
Пусть мы ищем ключ <tex>K</tex>. Смотрим в ячейку с индексом <tex>h_q</tex>, это каноническая ячейка для частного <tex>h_q</tex>. Если в этой ячейке бит занятости не единица, то элемент точно не содержится в множестве.<br />
Если бит занятости единица, то нам нужно найти пробег для <tex>h_q</tex>. Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки с индексом <tex>h_q</tex> и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от ячейки с индексом <tex>h_q</tex> будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на <tex>1</tex>. После того как мы нашли начало кластера, пойдем от него влево, каждая ячейка с битом продолжения равным нулю говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нужный нам пробег для частного <tex>h_q</tex>. Если в этом пробеге содержится <tex>h_r</tex>, то <tex>K</tex>, вероятно, содержится в множестве, иначе <tex>K</tex> точно не содержится в множестве.<br />
<br />
=== Вставка ===<br />
<br />
Аналогично с поиском: найдем позицию для <tex>h_r</tex>, сдвигаем на одну позицию влево все эллементы кластера, начиная с выбранного, обновляем дополнительные биты. <br />
<br />
* Сдвиг не влияет на бит занятости. Выставляем бит занятости в ячейке <tex>h_q</tex> в единицу.<br />
* Если мы вставляем <tex>h_r</tex> в начало пробега, следовательно предыдущий элемент пробега стал вторым, у него нужно выставить бит продолжения.<br />
* Мы выставляем бит сдвига в единицу для каждой ячейки, что мы сдвинули.<br />
<br />
== Преимущества ==<br />
<br />
* Последовательное расположение данных. Можно загружать только <tex>1</tex> кластер, уменьшая количество кеш промахов.<br />
* Простое увеличение или уменьшение хеш-таблицы, достаточно перенести один бит из остатка в частное или наоборот.<br />
* Простое слияние двух фильтров.<br />
<br />
==См. также==<br />
<br />
*[[:Идеальное_хеширование|Идеальное хеширование]]<br />
*[[:Универсальное_семейство_хеш-функций|Универсальное хеширование]]<br />
<br />
==Примечания==<br />
<br />
<references /><br />
<br />
== Источники информации ==<br />
<br />
* [http://en.wikipedia.org/wiki/Quotient_filter Wikipedia — Quotient filter]<br />
* [http://habrahabr.ru/post/242285/ Habrahabr — Quotient filter]<br />
[[Категория: Дискретная математика и алгоритмы ]]<br />
[[Категория: Хеширование]]<br />
[[Категория: Структуры данных]]</div>Kurkinhttp://neerc.ifmo.ru/wiki/index.php?title=Quotient_filter&diff=47892Quotient filter2015-06-06T20:25:35Z<p>Kurkin: </p>
<hr />
<div>[[Файл:filter.png|500px|thumb|right|Фильтр используется для ускорения ответов в хранилище ключ-значение. Пары ключ-значение содержатся в хранилище с медленным доступом. Фильтр отфильтровывает ненужные запросы в хранилище (запрос ключа которого точно нет в хранилище), что ускоряет его работу вцелом, но увеличевает потребление памяти]]<br />
'''Quotient filter''' {{---}} вероятностная структура данных, позволяющая проверить принадлежность элемента множеству. При этом существует возможность получить ложноположительное срабатывание (элемента в множестве нет, но структура данных сообщает, что он есть), но не ложноотрицательное (элемент в множестве есть, но структура данных сообщает, что его нет).<br />
<br />
Существует связь между размером хранилища и шансом ложноположительного срабатывания. Поддерживаются операции добавления нового элемента в множество. С увеличением размера хранимого множества повышается вероятность ложного срабатывания. <br />
Структуру разработал Michael Bender в 2011 году<ref>Bender, Michael A.; Farach-Colton, Martin; Johnson, Rob; Kuszmaul, Bradley C.; Medjedovic, Dzejla; Montes, Pablo; Shetty, Pradeep; Spillane, Richard P.; Zadok, Erez (June 2011).[http://vldb.org/pvldb/vol5/p1627_michaelabender_vldb2012.pdf "Don't thrash: how to cache your hash on flash" (PDF)]</ref> как замена [[:Фильтр_Блума|фильтра Блума]]. Фильтр используется для ускорения ответов в хранилище ключ-значение. <br />
<br />
==Описание структуры данных==<br />
<br />
Фильтр представляет собой [[:Хеш-таблица|хеш-таблицу]], в которой харанится часть ключа и <tex>3</tex> бита дополнительной информации. Они используются для разрешения ситуации, когда хеш различных ключей указывает на одну ячейку в хеш-таблице. В quotient filter хеш-функция возвращает <tex>p</tex> битовый хеш, последние r бит которого называются '''остатком''' (англ. ''remainder''), а <tex>q = p - r</tex> старших бит называются '''частным''' (англ. ''quotient''), отсюда название структуры Quotient filter<ref>Knuth, Donald (1973). The Art of Computer Programming:Searching and Sorting, volume 3. Section 6.4, exercise 13: Addison Wesley</ref>. Размер хеш-таблицы составляет <tex>2^q</tex>, так как есть всего <tex>2^q</tex> разных частных.<br />
<br />
Пусть у нас есть ключ <tex>K</tex>, его хеш обозначим <tex>h(K)</tex>, остаток <tex>h_r</tex> и частное <tex>h_q</tex>. Попробуем поместить остаток в хеш-таблицу в ячейку с индексом <tex>h_q</tex>, называемую канонической. Возможно, ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа. Этот способ решения колизий схож с [[:Разрешение_коллизий|линейным методом разрешения колизий]].<br />
<br />
Последовательность ячеек, имеющих одинаковые частные называется '''пробегом''' (англ. ''run''). Возможно, что начало пробега не занимает канонический слот, если он уже занят каким-то другим пробегом. <br />
<br />
Пробег, у которого первый элемент занимает каноническую ячейку, является началом кластера. Кластер {{---}} объединение последовательных пробегов, концом кластера является пустая ячейка или начало другого кластера.<br />
<br />
Три дополнительных бита имеют следующие функции:<br />
* бит занятости {{---}} равен единице, если ячейка является канонической для некого ключа в фильтре, сохраненого необязательно в этой ячейке,<br />
* бит продолжения {{---}} равен единице, если ячейка занята, но не первым элементов пробеге,<br />
* бит сдвига {{---}} равен единице, если пробег сдвинут относительно канонического слота.<br />
<br />
[[Файл:Quotient Filter.png|500px|thumb|right|Пример последовательной вставки элементов <tex> b, f, e, c, d, a</tex>]]<br />
{| class="wikitable" border=1<br />
|+<br />
|-align="center" bgcolor=#EEEEFF <br />
! Бит занятости || Бит Продолжения || Бит сдвига || Описание <br />
|-align="center" bgcolor=#FFFFFF<br />
|0||0||0||style="text-align:left;"|Пустая ячейка.<br />
|-align="center" bgcolor=#FFFFFF<br />
|0||0||1||style="text-align:left;"|Ячейка содержит начало пробега, сдвинутого относительно канонического слота.<br />
|-align="center" bgcolor=#FFFFFF<br />
|0||1||0||style="text-align:left;"|Не используется. <br />
|-align="center" bgcolor=#FFFFFF<br />
|0||1||1||style="text-align:left;"|Ячейка содержит элемент пробега (не первый), сдвинутого относительно канонического слота.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||0||0||style="text-align:left;"|Ячейка содержит первый элемет пробега в его каноническом слоте.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||0||1||style="text-align:left;"|Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||1||0||style="text-align:left;"|Не используется.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||1||1||style="text-align:left;"|Ячейка содержит элемент пробега (не первый), сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.<br />
|}<br />
<br />
=== Поиск ===<br />
<br />
Пусть мы ищем ключ <tex>K</tex>. Смотрим в ячейку с индексом <tex>h_q</tex>, это каноническая ячейка для частного <tex>h_q</tex>. Если в этой ячейке бит занятости не единица, то элемент точно не содержится в множестве.<br />
Если бит занятости единица, то нам нужно найти пробег для <tex>h_q</tex>. Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки с индексом <tex>h_q</tex> и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от ячейки с индексом <tex>h_q</tex> будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на <tex>1</tex>. После того как мы нашли начало кластера, пойдем от него влево, каждая ячейка с битом продолжения равным нулю говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нужный нам пробег для частного <tex>h_q</tex>. Если в этом пробеге содержится <tex>h_r</tex>, то <tex>K</tex>, вероятно, содержится в множестве, иначе <tex>K</tex> точно не содержится в множестве.<br />
<br />
=== Вставка ===<br />
<br />
Аналогично с поиском: найдем позицию для <tex>h_r</tex>, сдвигаем на одну позицию влево все эллементы кластера, начиная с выбранного, обновляем дополнительные биты. <br />
<br />
* Сдвиг не влияет на бит занятости. Выставляем бит занятости в ячейке <tex>h_q</tex> в единицу.<br />
* Если мы вставляем <tex>h_r</tex> в начало пробега, следовательно предыдущий элемент пробега стал вторым, у него нужно выставить бит продолжения.<br />
* Мы выставляем бит сдвига в единицу для каждой ячейки, что мы сдвинули.<br />
<br />
== Преимущества ==<br />
<br />
* Последовательное расположение данных. Можно загружать только <tex>1</tex> кластер, уменьшая количество кеш промахов.<br />
* Простое увеличение или уменьшение хеш-таблицы, достаточно перенести один бит из остатка в частное или наоборот.<br />
* Простое слияние двух фильтров.<br />
<br />
==См. также==<br />
<br />
*[[:Идеальное_хеширование|Идеальное хеширование]]<br />
*[[:Универсальное_семейство_хеш-функций|Универсальное хеширование]]<br />
<br />
==Примечания==<br />
<br />
<references /><br />
<br />
== Источники информации ==<br />
<br />
* [http://en.wikipedia.org/wiki/Quotient_filter Wikipedia — Quotient filter]<br />
* [http://habrahabr.ru/post/242285/ Habrahabr — Quotient filter]<br />
[[Категория: Дискретная математика и алгоритмы ]]<br />
[[Категория: Хеширование]]<br />
[[Категория: Структуры данных]]</div>Kurkinhttp://neerc.ifmo.ru/wiki/index.php?title=Quotient_filter&diff=47891Quotient filter2015-06-06T20:24:26Z<p>Kurkin: </p>
<hr />
<div>[[Файл:filter.png|500px|thumb|right|Фильтр используется для ускорения ответов в хранилище ключ-значение. Пары ключ-значение содержатся в хранилище с медленным доступом. Фильтр отфильтровывает ненужные запросы в хранилище (запрос ключа которого точно нет в хранилище), что ускоряет его работу вцелом, но увеличевает потребление памяти]]<br />
'''Quotient filter''' {{---}} вероятностная структура данных, позволяющая проверить принадлежность элемента множеству. При этом существует возможность получить ложноположительное срабатывание (элемента в множестве нет, но структура данных сообщает, что он есть), но не ложноотрицательное (элемент в множестве есть, но структура данных сообщает, что его нет).<br />
<br />
Существует связь между размером хранилища и шансом ложноположительного срабатывания. Поддерживаются операции добавления нового элемента в множество. С увеличением размера хранимого множества повышается вероятность ложного срабатывания. <br />
Структуру разработал Michael Bender в 2011 году<ref>Bender, Michael A.; Farach-Colton, Martin; Johnson, Rob; Kuszmaul, Bradley C.; Medjedovic, Dzejla; Montes, Pablo; Shetty, Pradeep; Spillane, Richard P.; Zadok, Erez (June 2011).[http://vldb.org/pvldb/vol5/p1627_michaelabender_vldb2012.pdf "Don't thrash: how to cache your hash on flash" (PDF)]</ref> как замена [[:Фильтр_Блума|фильтра Блума]]. Фильтр используется для ускорения ответов в хранилище ключ-значение. <br />
<br />
==Описание структуры данных==<br />
<br />
Фильтр представляет собой [[:Хеш-таблица|хеш-таблицу]], в которой харанится часть ключа и <tex>3</tex> бита дополнительной информации. Они используются для разрешения ситуации, когда хеш различных ключей указывает на одну ячейку в хеш-таблице. В quotient filter хеш-функция возвращает <tex>p</tex> битовый хеш, последние r бит которого называются '''остатком''' (англ. ''remainder''), а <tex>q = p - r</tex> старших бит называются '''частным''' (англ. ''quotient''), отсюда название структуры Quotient filter<ref>Knuth, Donald (1973). The Art of Computer Programming:Searching and Sorting, volume 3. Section 6.4, exercise 13: Addison Wesley</ref>. Размер хеш-таблицы составляет <tex>2^q</tex>.<br />
<br />
Пусть у нас есть ключ <tex>K</tex>, его хеш обозначим <tex>h(K)</tex>, остаток <tex>h_r</tex> и частное <tex>h_q</tex>. Попробуем поместить остаток в хеш-таблицу в ячейку с индексом <tex>h_q</tex>, называемую канонической. Возможно, ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа. Этот способ решения колизий схож с [[:Разрешение_коллизий|линейным методом разрешения колизий]].<br />
<br />
Последовательность ячеек, имеющих одинаковые частные называется '''пробегом''' (англ. ''run''). Возможно, что начало пробега не занимает канонический слот, если он уже занят каким-то другим пробегом. <br />
<br />
Пробег, у которого первый элемент занимает каноническую ячейку, является началом кластера. Кластер {{---}} объединение последовательных пробегов, концом кластера является пустая ячейка или начало другого кластера.<br />
<br />
Три дополнительных бита имеют следующие функции:<br />
* бит занятости {{---}} равен единице, если ячейка является канонической для некого ключа в фильтре, сохраненого необязательно в этой ячейке,<br />
* бит продолжения {{---}} равен единице, если ячейка занята, но не первым элементов пробеге,<br />
* бит сдвига {{---}} равен единице, если пробег сдвинут относительно канонического слота.<br />
<br />
[[Файл:Quotient Filter.png|500px|thumb|right|Пример последовательной вставки элементов <tex> b, f, e, c, d, a</tex>]]<br />
{| class="wikitable" border=1<br />
|+<br />
|-align="center" bgcolor=#EEEEFF <br />
! Бит занятости || Бит Продолжения || Бит сдвига || Описание <br />
|-align="center" bgcolor=#FFFFFF<br />
|0||0||0||style="text-align:left;"|Пустая ячейка.<br />
|-align="center" bgcolor=#FFFFFF<br />
|0||0||1||style="text-align:left;"|Ячейка содержит начало пробега, сдвинутого относительно канонического слота.<br />
|-align="center" bgcolor=#FFFFFF<br />
|0||1||0||style="text-align:left;"|Не используется. <br />
|-align="center" bgcolor=#FFFFFF<br />
|0||1||1||style="text-align:left;"|Ячейка содержит элемент пробега (не первый), сдвинутого относительно канонического слота.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||0||0||style="text-align:left;"|Ячейка содержит первый элемет пробега в его каноническом слоте.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||0||1||style="text-align:left;"|Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||1||0||style="text-align:left;"|Не используется.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||1||1||style="text-align:left;"|Ячейка содержит элемент пробега (не первый), сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.<br />
|}<br />
<br />
=== Поиск ===<br />
<br />
Пусть мы ищем ключ <tex>K</tex>. Смотрим в ячейку с индексом <tex>h_q</tex>, это каноническая ячейка для частного <tex>h_q</tex>. Если в этой ячейке бит занятости не единица, то элемент точно не содержится в множестве.<br />
Если бит занятости единица, то нам нужно найти пробег для <tex>h_q</tex>. Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки с индексом <tex>h_q</tex> и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от ячейки с индексом <tex>h_q</tex> будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на <tex>1</tex>. После того как мы нашли начало кластера, пойдем от него влево, каждая ячейка с битом продолжения равным нулю говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нужный нам пробег для частного <tex>h_q</tex>. Если в этом пробеге содержится <tex>h_r</tex>, то <tex>K</tex>, вероятно, содержится в множестве, иначе <tex>K</tex> точно не содержится в множестве.<br />
<br />
=== Вставка ===<br />
<br />
Аналогично с поиском: найдем позицию для <tex>h_r</tex>, сдвигаем на одну позицию влево все эллементы кластера, начиная с выбранного, обновляем дополнительные биты. <br />
<br />
* Сдвиг не влияет на бит занятости. Выставляем бит занятости в ячейке <tex>h_q</tex> в единицу.<br />
* Если мы вставляем <tex>h_r</tex> в начало пробега, следовательно предыдущий элемент пробега стал вторым, у него нужно выставить бит продолжения.<br />
* Мы выставляем бит сдвига в единицу для каждой ячейки, что мы сдвинули.<br />
<br />
== Преимущества ==<br />
<br />
* Последовательное расположение данных. Можно загружать только <tex>1</tex> кластер, уменьшая количество кеш промахов.<br />
* Простое увеличение или уменьшение хеш-таблицы, достаточно перенести один бит из остатка в частное или наоборот.<br />
* Простое слияние двух фильтров.<br />
<br />
==См. также==<br />
<br />
*[[:Идеальное_хеширование|Идеальное хеширование]]<br />
*[[:Универсальное_семейство_хеш-функций|Универсальное хеширование]]<br />
<br />
==Примечания==<br />
<br />
<references /><br />
<br />
== Источники информации ==<br />
<br />
* [http://en.wikipedia.org/wiki/Quotient_filter Wikipedia — Quotient filter]<br />
* [http://habrahabr.ru/post/242285/ Habrahabr — Quotient filter]<br />
[[Категория: Дискретная математика и алгоритмы ]]<br />
[[Категория: Хеширование]]<br />
[[Категория: Структуры данных]]</div>Kurkinhttp://neerc.ifmo.ru/wiki/index.php?title=Quotient_filter&diff=47886Quotient filter2015-06-06T20:18:25Z<p>Kurkin: </p>
<hr />
<div>[[Файл:filter.png|500px|thumb|right|Фильтр используется для ускорения ответов в хранилище ключ-значение. Пары ключ-значение содержатся в хранилище с медленным доступом. Фильтр отфильтровывает ненужные запросы в хранилище (запрос ключа которого точно нет в хранилище), что ускоряет его работу вцелом, но увеличевает потребление памяти]]<br />
'''Quotient filter''' {{---}} вероятностная структура данных, позволяющая проверить принадлежность элемента множеству. При этом существует возможность получить ложноположительное срабатывание (элемента в множестве нет, но структура данных сообщает, что он есть), но не ложноотрицательное (элемент в множестве есть, но структура данных сообщает, что его нет).<br />
<br />
Существует связь между размером хранилища и шансом ложноположительного срабатывания. Поддерживаются операции добавления нового элемента в множество. С увеличением размера хранимого множества повышается вероятность ложного срабатывания. <br />
Структуру разработал Michael Bender в 2011 году<ref>Bender, Michael A.; Farach-Colton, Martin; Johnson, Rob; Kuszmaul, Bradley C.; Medjedovic, Dzejla; Montes, Pablo; Shetty, Pradeep; Spillane, Richard P.; Zadok, Erez (June 2011).[http://vldb.org/pvldb/vol5/p1627_michaelabender_vldb2012.pdf "Don't thrash: how to cache your hash on flash" (PDF)]</ref> как замена [[:Фильтр_Блума|фильтра Блума]]. Фильтр используется для ускорения ответов в хранилище ключ-значение. <br />
<br />
==Описание структуры данных==<br />
<br />
Фильтр представляет собой [[:Хеш-таблица|хеш-таблицу]], в которой харанится часть ключа и <tex>3</tex> бита дополнительной информации. Они используются для разрешения ситуации, когда хеш различных ключей указывает на одну ячейку в хеш-таблице. В quotient filter хеш-функция возвращает <tex>p</tex> битовый хеш, последние r бит которого называются '''остатком''' (англ. ''remainder''), а <tex>q = p - r</tex> старших бит называются '''частным''' (англ. ''quotient''), отсюда название структуры Quotient filter<ref>Knuth, Donald (1973). The Art of Computer Programming:Searching and Sorting, volume 3. Section 6.4, exercise 13: Addison Wesley</ref>. Размер хеш-таблицы составляет <tex>2^q</tex>.<br />
<br />
Пусть у нас есть ключ <tex>K</tex>, его хеш обозначим <tex>h(K)</tex>, остаток <tex>h_r</tex> и частное <tex>h_q</tex>. Попробуем поместить остаток в хеш-таблицу в ячейку <tex>h_q</tex>, называемую канонической. Возможно, ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа. Этот способ решения колизий схож с [[:Разрешение_коллизий|линейным методом разрешения колизий]].<br />
<br />
Последовательность ячеек, имеющих одинаковые частные называется '''пробегом''' (англ. ''run''). Возможно, что начало пробега не занимает канонический слот, если он уже занят каким-то другим пробегом. <br />
<br />
Пробег, у которого первый элемент занимает каноническую ячейку, является началом кластера. '''Кластер''' {{---}} объединение последовательных пробегов, концом кластера является пустая ячейка или начало другого кластера.<br />
<br />
Три дополнительных бита имеют следующие функции:<br />
* бит занятости {{---}} равен единице, если ячейка является канонической для некого ключа в фильтре, сохраненого необязательно в этой ячейке,<br />
* бит продолжения {{---}} равен единице, если ячейка занята, но не первым элементов пробеге,<br />
* бит сдвига {{---}} равен единице, если пробег сдвинут относительно канонического слота.<br />
<br />
[[Файл:Quotient Filter.png|500px|thumb|right|Пример последовательной вставки элементов <tex> b, f, e, c, d, a</tex>]]<br />
{| class="wikitable" border=1<br />
|+<br />
|-align="center" bgcolor=#EEEEFF <br />
! Бит занятости || Бит Продолжения || Бит сдвига || Описание <br />
|-align="center" bgcolor=#FFFFFF<br />
|0||0||0||style="text-align:left;"|Пустая ячейка.<br />
|-align="center" bgcolor=#FFFFFF<br />
|0||0||1||style="text-align:left;"|Ячейка содержит начало пробега, сдвинутого относительно канонического слота.<br />
|-align="center" bgcolor=#FFFFFF<br />
|0||1||0||style="text-align:left;"|Не используется. <br />
|-align="center" bgcolor=#FFFFFF<br />
|0||1||1||style="text-align:left;"|Ячейка содержит элемент пробега (не первый), сдвинутого относительно канонического слота.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||0||0||style="text-align:left;"|Ячейка содержит первый элемет пробега в его каноническом слоте.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||0||1||style="text-align:left;"|Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||1||0||style="text-align:left;"|Не используется.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||1||1||style="text-align:left;"|Ячейка содержит элемент пробега (не первый), сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.<br />
|}<br />
<br />
=== Поиск ===<br />
<br />
Пусть мы ищем ключ <tex>K</tex>. Смотрим в его каноническую ячейку <tex>h_q</tex>. Если бит занятости не единица, то элемент точно не содержится в множестве.<br />
Если бит занятости единица, то нам нужно найти пробег для <tex>h_q</tex>. Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки <tex>h_q</tex> и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от <tex>h_q</tex> будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на <tex>1</tex>. После того как мы нашли начало кластера, пойдем от него влево, каждая ячейка с битом продолжения равным нулю говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нужный нам пробег для <tex>h_q</tex>. Если в этом пробеге содержится <tex>h_r</tex>, то <tex>K</tex>, вероятно, содержится в множестве, иначе <tex>K</tex> точно не содержится в множестве.<br />
<br />
=== Вставка ===<br />
<br />
Аналогично с поиском: найдем позицию для <tex>h_r</tex>, сдвигаем на одну позицию влево все эллементы кластера, начиная с выбранного, обновляем дополнительные биты. <br />
<br />
* Сдвиг не влияет на бит занятости. Выставляем бит занятости в ячейке <tex>h_q</tex> в единицу.<br />
* Если мы вставляем <tex>h_r</tex> в начало пробега, следовательно предыдущий элемент пробега стал вторым, у него нужно выставить бит продолжения.<br />
* Мы выставляем бит сдвига в единицу для каждой ячейки, что мы сдвинули.<br />
<br />
== Преимущества ==<br />
<br />
* Последовательное расположение данных. Можно загружать только <tex>1</tex> кластер, уменьшая количество кеш промахов.<br />
* Простое увеличение или уменьшение хеш-таблицы, достаточно перенести один бит из остатка в частное или наоборот.<br />
* Простое слияние двух фильтров.<br />
<br />
==См. также==<br />
<br />
*[[:Идеальное_хеширование|Идеальное хеширование]]<br />
*[[:Универсальное_семейство_хеш-функций|Универсальное хеширование]]<br />
<br />
==Примечания==<br />
<br />
<references /><br />
<br />
== Источники информации ==<br />
<br />
* [http://en.wikipedia.org/wiki/Quotient_filter Wikipedia — Quotient filter]<br />
* [http://habrahabr.ru/post/242285/ Habrahabr — Quotient filter]<br />
[[Категория: Дискретная математика и алгоритмы ]]<br />
[[Категория: Хеширование]]<br />
[[Категория: Структуры данных]]</div>Kurkinhttp://neerc.ifmo.ru/wiki/index.php?title=Quotient_filter&diff=47880Quotient filter2015-06-06T20:07:19Z<p>Kurkin: </p>
<hr />
<div>[[Файл:filter.png|500px|thumb|right|Фильтр используется для ускорения ответов в хранилище ключ-значение. Пары ключ-значение содержатся в хранилище с медленным доступом. Фильтр отфильтровывает ненужные запросы в хранилище (запрос ключа которого точно нет в хранилище), что ускоряет его работу вцелом, но увеличевает потребление памяти]]<br />
'''Quotient filter''' {{---}} вероятностная структура данных, позволяющая проверить принадлежность элемента множеству. При этом существует возможность получить ложноположительное срабатывание (элемента в множестве нет, но структура данных сообщает, что он есть), но не ложноотрицательное (элемент в множестве есть, но структура данных сообщает, что его нет).<br />
<br />
Существует связь между размером хранилища и шансом ложноположительного срабатывания. Поддерживаются операции добавления нового элемента в множество. С увеличением размера хранимого множества повышается вероятность ложного срабатывания. <br />
Структуру разработал Michael Bender в 2011 году<ref>Bender, Michael A.; Farach-Colton, Martin; Johnson, Rob; Kuszmaul, Bradley C.; Medjedovic, Dzejla; Montes, Pablo; Shetty, Pradeep; Spillane, Richard P.; Zadok, Erez (June 2011).[http://vldb.org/pvldb/vol5/p1627_michaelabender_vldb2012.pdf "Don't thrash: how to cache your hash on flash" (PDF)]</ref> как замена [[:Фильтр_Блума|фильтра Блума]]. Фильтр используется для ускорения ответов в хранилище ключ-значение. <br />
<br />
==Описание структуры данных==<br />
<br />
Фильтр представляет собой [[:Хеш-таблица|хеш-таблицу]], в которой харанится часть ключа и <tex>3</tex> бита дополнительной информации. Они используются для разрешения ситуации, когда хеш различных ключей указывает на одну ячейку в хеш-таблице. В quotient filter хеш-функция возвращает <tex>p</tex> битовый хеш, последние r бит которого называются '''остатком''' (англ. ''remainder''), а <tex>q = p - r</tex> старших бит называются '''частным''' (англ. ''quotient''), отсюда название структуры Quotient filter<ref>Knuth, Donald (1973). The Art of Computer Programming:Searching and Sorting, volume 3. Section 6.4, exercise 13: Addison Wesley</ref>. Размер хеш-таблицы составляет <tex>2^q</tex>.<br />
<br />
Пусть у нас есть ключ <tex>K</tex>, его хеш обозначим <tex>h(K)</tex>, остаток <tex>H_r</tex> и частное <tex>H_q</tex>. Попробуем поместить остаток в хеш-таблицу в ячейку <tex>H_q</tex>, называемую канонической. Возможно, ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа. Этот способ решения колизий схож с [[:Разрешение_коллизий|линейным методом разрешения колизий]].<br />
<br />
Последовательность ячеек, имеющих одинаковые частные называется '''пробегом''' (англ. ''run''). Возможно, что начало пробега не занимает канонический слот, если он уже занят каким-то другим пробегом. <br />
<br />
Пробег, у которого первый элемент занимает каноническую ячейку, является началом кластера. '''Кластер''' {{---}} объединение последовательных пробегов, концом кластера является пустая ячейка или начало другого кластера.<br />
<br />
Три дополнительных бита имеют следующие функции:<br />
* бит занятости {{---}} равен единице, если ячейка является канонической для некого ключа в фильтре, сохраненого необязательно в этой ячейке,<br />
* бит продолжения {{---}} равен единице, если ячейка занята, но не первым элементов пробеге,<br />
* бит сдвига {{---}} равен единице, если пробег сдвинут относительно канонического слота.<br />
<br />
[[Файл:Quotient Filter.png|500px|thumb|right|Пример последовательной вставки элементов <tex> b, f, e, c, d, a</tex>]]<br />
{| class="wikitable" border=1<br />
|+<br />
|-align="center" bgcolor=#EEEEFF <br />
! Бит занятости || Бит Продолжения || Бит сдвига || Описание <br />
|-align="center" bgcolor=#FFFFFF<br />
|0||0||0||style="text-align:left;"|Пустая ячейка.<br />
|-align="center" bgcolor=#FFFFFF<br />
|0||0||1||style="text-align:left;"|Ячейка содержит начало пробега, сдвинутого относительно канонического слота.<br />
|-align="center" bgcolor=#FFFFFF<br />
|0||1||0||style="text-align:left;"|Не используется. <br />
|-align="center" bgcolor=#FFFFFF<br />
|0||1||1||style="text-align:left;"|Ячейка содержит элемент пробега (не первый), сдвинутого относительно канонического слота.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||0||0||style="text-align:left;"|Ячейка содержит первый элемет пробега в его каноническом слоте.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||0||1||style="text-align:left;"|Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||1||0||style="text-align:left;"|Не используется.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||1||1||style="text-align:left;"|Ячейка содержит элемент пробега (не первый), сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.<br />
|}<br />
<br />
=== Поиск ===<br />
<br />
Пусть мы ищем ключ <tex>K</tex>. Смотрим в его каноническую ячейку <tex>H_q</tex>. Если бит занятости не единица, то элемент точно не содержится в множестве.<br />
Если бит занятости единица, то нам нужно найти пробег для <tex>H_q</tex>. Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки <tex>H_q</tex> и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от <tex>H_q</tex> будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на <tex>1</tex>. После того как мы нашли начало кластера, пойдем от него влево, каждая ячейка с битом продолжения равным нулю говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нужный нам пробег для <tex>H_q</tex>. Если в этом пробеге содержится <tex>H_r</tex>, то <tex>K</tex>, вероятно, содержится в множестве, иначе <tex>K</tex> точно не содержится в множестве.<br />
<br />
=== Вставка ===<br />
<br />
Аналогично с поиском: найдем позицию для <tex>H_r</tex>, сдвигаем на одну позицию влево все эллементы кластера, начиная с выбранного, обновляем дополнительные биты. <br />
<br />
* Сдвиг не влияет на бит занятости. Выставляем бит занятости в ячейке <tex>H_q</tex> в единицу.<br />
* Если мы вставляем <tex>H_r</tex> в начало пробега, следовательно предыдущий элемент пробега стал вторым, у него нужно выставить бит продолжения.<br />
* Мы выставляем бит сдвига в единицу для каждой ячейки, что мы сдвинули.<br />
<br />
== Преимущества ==<br />
<br />
* Последовательное расположение данных. Можно загружать только <tex>1</tex> кластер, уменьшая количество кеш промахов.<br />
* Простое увеличение или уменьшение хеш-таблицы, достаточно перенести один бит из остатка в частное или наоборот.<br />
* Простое слияние двух фильтров.<br />
<br />
==См. также==<br />
<br />
*[[:Идеальное_хеширование|Идеальное хеширование]]<br />
*[[:Универсальное_семейство_хеш-функций|Универсальное хеширование]]<br />
<br />
==Примечания==<br />
<br />
<references /><br />
<br />
== Источники информации ==<br />
<br />
* [http://en.wikipedia.org/wiki/Quotient_filter Wikipedia — Quotient filter]<br />
* [http://habrahabr.ru/post/242285/ Habrahabr — Quotient filter]<br />
[[Категория: Дискретная математика и алгоритмы ]]<br />
[[Категория: Хеширование]]<br />
[[Категория: Структуры данных]]</div>Kurkinhttp://neerc.ifmo.ru/wiki/index.php?title=Quotient_filter&diff=47865Quotient filter2015-06-06T19:14:46Z<p>Kurkin: </p>
<hr />
<div>[[Файл:filter.png|350px|thumb|right|Фильтр используется для ускорения ответов в хранилище ключ-значение. Пары ключ-значение содержатся в хранилище с медленным доступом. Фильтр отфильтровывает ненужные запросы в хранилище (запрос ключа которого точно нет в хранилище), что ускоряет его работу вцелом, но увеличевает потребление памяти]]<br />
'''Quotient filter''' {{---}} вероятностная структура данных, позволяющая проверить принадлежность элемента множеству. При этом существует возможность получить ложноположительное срабатывание (элемента в множестве нет, но структура данных сообщает, что он есть), но не ложноотрицательное (элемент в множестве есть, но структура данных сообщает, что его нет).<br />
<br />
Существует связь между размером хранилища и шансом ложноположительного срабатывания. Поддерживаются операции добавления нового элемента в множество. С увеличением размера хранимого множества повышается вероятность ложного срабатывания. <br />
Структуру разработал Michael Bender в 2011 году<ref>Bender, Michael A.; Farach-Colton, Martin; Johnson, Rob; Kuszmaul, Bradley C.; Medjedovic, Dzejla; Montes, Pablo; Shetty, Pradeep; Spillane, Richard P.; Zadok, Erez (June 2011).[http://vldb.org/pvldb/vol5/p1627_michaelabender_vldb2012.pdf "Don't thrash: how to cache your hash on flash" (PDF)]</ref> как замена [[:Фильтр_Блума|фильтра Блума]]. Фильтр используется для ускорения ответов в хранилище ключ-значение. <br />
<br />
==Описание структуры данных==<br />
<br />
Фильтр представляет собой [[:Хеш-таблица|хеш-таблицу]], в которой харанится часть ключа и <tex>3</tex> бита дополнительной информации. Они используются для разрешения ситуации, когда хеш различных ключей указывает на одну ячейку в хеш-таблице. В quotient filter хеш-функция возвращает <tex>p</tex> битовый хеш, последние r бит которого называются '''остатком''' (англ. ''remainder''), а <tex>q = p - r</tex> старших бит называются '''частным''' (англ. ''quotient''), отсюда название структуры Quotient filter<ref>Knuth, Donald (1973). The Art of Computer Programming:Searching and Sorting, volume 3. Section 6.4, exercise 13: Addison Wesley</ref>. Размер хеш-таблицы составляет <tex>2^q</tex>.<br />
<br />
Пусть у нас есть ключ <tex>K</tex>, его хеш обозначим <tex>H(k)</tex>, остаток <tex>H_r</tex> и частное <tex>H_q</tex>. Попробуем поместить остаток в хеш-таблицу в ячейку <tex>H_q</tex>, называемую канонической. Возможно, ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа.<br />
<br />
Последовательность ячеек, имеющих одинаковые частные называется '''пробегом''' (англ. ''run''). Возможно, что начало пробега не занимает канонический слот, если он уже занят каким-то другим пробегом. <br />
<br />
Пробег, у которого первый элемент занимает каноническую ячейку, является началом кластера. '''Кластер''' (англ. ''cluster'') {{---}} объединение последовательных пробегов, концом кластера является пустая ячейка или начало другого кластера.<br />
<br />
Три дополнительных бита имеют следующие функции:<br />
* бит занятости {{---}} равен единице, если ячейка является канонической для некого ключа в фильтре, сохраненого необязательно в этой ячейке,<br />
* бит продолжения {{---}} равен единице, если ячейка занята, но не первым элементов пробеге,<br />
* бит сдвига {{---}} равен единице, если пробег сдвинут относительно канонического слота.<br />
<br />
{| class="wikitable" border=1<br />
|+<br />
|-align="center" bgcolor=#EEEEFF <br />
! Бит занятости || Бит Продолжения || Бит сдвига || Описание <br />
|-align="center" bgcolor=#FFFFFF<br />
|0||0||0||style="text-align:left;"|Пустая ячейка.<br />
|-align="center" bgcolor=#FFFFFF<br />
|0||0||1||style="text-align:left;"|Ячейка содержит начало пробега, сдвинутого относительно канонического слота.<br />
|-align="center" bgcolor=#FFFFFF<br />
|0||1||0||style="text-align:left;"|Не используется. <br />
|-align="center" bgcolor=#FFFFFF<br />
|0||1||1||style="text-align:left;"|Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||0||0||style="text-align:left;"|Ячейка содержит первый элемет пробега в его каноническом слоте.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||0||1||style="text-align:left;"|Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||1||0||style="text-align:left;"|Не используется.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||1||1||style="text-align:left;"|Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.<br />
|}<br />
<br />
=== Поиск ===<br />
[[Файл:Quotient Filter.png|350px|thumb|right|Пример последовательной вставки элементов <tex> b, f, e, c, d, a</tex>]]<br />
<br />
Пусть мы ищем ключ <tex>K</tex>. Смотрим в его каноническую ячейку <tex>H_q</tex>. Если бит занятости не единица, то элемент точно не содержится в множестве.<br />
Если бит занятости единица, то нам нужно найти пробег для <tex>H_q</tex>. Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки <tex>H_q</tex> и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от <tex>H_q</tex> будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на <tex>1</tex>. После того как мы нашли начало кластера, пойдем от него влево, каждая ячейка с битом продолжения равным нулю говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нужный нам пробег для <tex>H_q</tex>. Если в этом пробеге содержится <tex>H_r</tex>, то <tex>K</tex>, вероятно, содержится в множестве, иначе <tex>K</tex> точно не содержится в множестве.<br />
<br />
=== Вставка ===<br />
<br />
Аналогично с поиском: найдем позицию для <tex>H_r</tex>, сдвигаем на одну позицию влево все эллементы кластера, начиная с выбранного, обновляем дополнительные биты. <br />
<br />
* Сдвиг не влияет на бит занятости. Выставляем бит занятости в ячейке <tex>H_q</tex> в единицу.<br />
* Если мы вставляем <tex>H_r</tex> в начало пробега, следовательно предыдущий элемент пробега стал вторым, у него нужно выставить бит продолжения.<br />
* Мы выставляем бит сдвига в единицу для каждой ячейки, что мы сдвинули.<br />
<br />
== Преимущества ==<br />
<br />
* Последовательное расположение данных. Можно загружать только <tex>1</tex> кластер, уменьшая количество кеш промахов.<br />
* Простое увеличение или уменьшение хеш-таблицы, достаточно перенести один бит из остатка в частное или наоборот.<br />
* Простое слияние двух фильтров.<br />
<br />
==См. также==<br />
<br />
*[[:Идеальное_хеширование|Идеальное хеширование]]<br />
*[[:Универсальное_семейство_хеш-функций|Универсальное хеширование]]<br />
<br />
==Примечания==<br />
<br />
<references /><br />
<br />
== Источники ==<br />
<br />
* [http://en.wikipedia.org/wiki/Quotient_filter Wikipedia — Quotient filter]<br />
* [http://habrahabr.ru/post/242285/ Habrahabr — Quotient filter]<br />
[[Категория: Дискретная математика и алгоритмы ]]<br />
[[Категория: Хеширование]]<br />
[[Категория: Структуры данных]]</div>Kurkinhttp://neerc.ifmo.ru/wiki/index.php?title=Quotient_filter&diff=47864Quotient filter2015-06-06T19:13:52Z<p>Kurkin: </p>
<hr />
<div>[[Файл:filter.png|350px|thumb|right|Фильтр используется для ускорения ответов в хранилище ключ-значение. Пары ключ-значение содержатся в хранилище с медленным доступом. Фильтр отфильтровывает ненужные запросы в хранилище (запрос ключа которого точно нет в хранилище), что ускоряет его работу вцелом, но увеличевает потребление памяти]]<br />
'''Quotient filter''' {{---}} вероятностная структура данных, позволяющая проверить принадлежность элемента множеству. При этом существует возможность получить ложноположительное срабатывание (элемента в множестве нет, но структура данных сообщает, что он есть), но не ложноотрицательное (элемент в множестве есть, но структура данных сообщает, что его нет).<br />
<br />
Существует связь между размером хранилища и шансом ложноположительного срабатывания. Поддерживаются операции добавления нового элемента в множество. С увеличением размера хранимого множества повышается вероятность ложного срабатывания. <br />
Структуру разработал Michael Bender в 2011 году<ref>Bender, Michael A.; Farach-Colton, Martin; Johnson, Rob; Kuszmaul, Bradley C.; Medjedovic, Dzejla; Montes, Pablo; Shetty, Pradeep; Spillane, Richard P.; Zadok, Erez (June 2011).[http://vldb.org/pvldb/vol5/p1627_michaelabender_vldb2012.pdf "Don't thrash: how to cache your hash on flash" (PDF)]</ref> как замена [[:Фильтр_Блума|фильтра Блума]]. Фильтр используется для ускорения ответов в хранилище ключ-значение. <br />
<br />
==Описание структуры данных==<br />
<br />
Фильтр представляет собой [[:Хеш-таблица|хеш-таблицу]], в которой харанится часть ключа и <tex>3</tex> бита дополнительной информации. Они используются для разрешения ситуации, когда хеш различных ключей указывает на одну ячейку в хеш-таблице. В quotient filter хеш-функция возвращает <tex>p</tex> битовый хеш, последние r бит которого называются '''остатком''' (англ. ''remainder''), а <tex>q = p - r</tex> старших бит называются '''частным''' (англ. ''quotient''), отсюда название структуры Quotient filter<ref>Knuth, Donald (1973). The Art of Computer Programming:Searching and Sorting, volume 3. Section 6.4, exercise 13: Addison Wesley</ref>. Размер хеш-таблицы составляет <tex>2^q</tex>.<br />
<br />
Пусть у нас есть ключ <tex>K</tex>, его хеш обозначим <tex>H(k)</tex>, остаток <tex>H_r</tex> и частное <tex>H_q</tex>. Попробуем поместить остаток в хеш-таблицу в ячейку <tex>H_q</tex>, называемую канонической. Возможно, ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа.<br />
<br />
Последовательность ячеек, имеющих одинаковые частные называется '''пробегом''' (англ. ''run''). Возможно, что начало пробега не занимает канонический слот, если он уже занят каким-то другим пробегом. <br />
<br />
Пробег, у которого первый элемент занимает каноническую ячейку, является началом кластера. '''Кластер''' (англ. ''cluster'') {{---}} объединение последовательных пробегов, концом кластера является пустая ячейка или начало другого кластера.<br />
<br />
Три дополнительных бита имеют следующие функции:<br />
* бит занятости {{---}} равен единице, если ячейка является канонической для некого ключа в фильтре, сохраненого необязательно в этой ячейке,<br />
* бит продолжения {{---}} равен единице, если ячейка занята, но не первым элементов пробеге,<br />
* бит сдвига {{---}} равен единице, если пробег сдвинут относительно канонического слота.<br />
<br />
{| class="wikitable" border=1<br />
|+<br />
|-align="center" bgcolor=#EEEEFF <br />
! Бит занятости || Бит Продолжения || Бит сдвига || Описание <br />
|-align="center" bgcolor=#FFFFFF<br />
|0||0||0||style="text-align:left;"|Пустая ячейка.<br />
|-align="center" bgcolor=#FFFFFF<br />
|0||0||1||style="text-align:left;"|Ячейка содержит начало пробега, сдвинутого относительно канонического слота.<br />
|-align="center" bgcolor=#FFFFFF<br />
|0||1||0||style="text-align:left;"|Не используется. <br />
|-align="center" bgcolor=#FFFFFF<br />
|0||1||1||style="text-align:left;"|Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||0||0||style="text-align:left;"|Ячейка содержит первый элемет пробега в его каноническом слоте.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||0||1||style="text-align:left;"|Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||1||0||style="text-align:left;"|Не используется.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||1||1||style="text-align:left;"|Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.<br />
|}<br />
<br />
=== Поиск ===<br />
<br />
Пусть мы ищем ключ <tex>K</tex>. Смотрим в его каноническую ячейку <tex>H_q</tex>. Если бит занятости не единица, то элемент точно не содержится в множестве.<br />
Если бит занятости единица, то нам нужно найти пробег для <tex>H_q</tex>. Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки <tex>H_q</tex> и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от <tex>H_q</tex> будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на <tex>1</tex>. После того как мы нашли начало кластера, пойдем от него влево, каждая ячейка с битом продолжения равным нулю говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нужный нам пробег для <tex>H_q</tex>. Если в этом пробеге содержится <tex>H_r</tex>, то <tex>K</tex>, вероятно, содержится в множестве, иначе <tex>K</tex> точно не содержится в множестве.<br />
<br />
=== Вставка ===<br />
[[Файл:Quotient Filter.png|350px|thumb|right|Пример последовательной вставки элементов <tex> b, f, e, c, d, a</tex>]]<br />
<br />
Аналогично с поиском: найдем позицию для <tex>H_r</tex>, сдвигаем на одну позицию влево все эллементы кластера, начиная с выбранного, обновляем дополнительные биты. <br />
<br />
* Сдвиг не влияет на бит занятости. Выставляем бит занятости в ячейке <tex>H_q</tex> в единицу.<br />
* Если мы вставляем <tex>H_r</tex> в начало пробега, следовательно предыдущий элемент пробега стал вторым, у него нужно выставить бит продолжения.<br />
* Мы выставляем бит сдвига в единицу для каждой ячейки, что мы сдвинули.<br />
<br />
== Преимущества ==<br />
<br />
* Последовательное расположение данных. Можно загружать только <tex>1</tex> кластер, уменьшая количество кеш промахов.<br />
* Простое увеличение или уменьшение хеш-таблицы, достаточно перенести один бит из остатка в частное или наоборот.<br />
* Простое слияние двух фильтров.<br />
<br />
==См. также==<br />
<br />
*[[:Идеальное_хеширование|Идеальное хеширование]]<br />
*[[:Универсальное_семейство_хеш-функций|Универсальное хеширование]]<br />
<br />
==Примечания==<br />
<br />
<references /><br />
<br />
== Источники ==<br />
<br />
* [http://en.wikipedia.org/wiki/Quotient_filter Wikipedia — Quotient filter]<br />
* [http://habrahabr.ru/post/242285/ Habrahabr — Quotient filter]<br />
[[Категория: Дискретная математика и алгоритмы ]]<br />
[[Категория: Хеширование]]<br />
[[Категория: Структуры данных]]</div>Kurkinhttp://neerc.ifmo.ru/wiki/index.php?title=Quotient_filter&diff=47860Quotient filter2015-06-06T19:08:57Z<p>Kurkin: </p>
<hr />
<div>'''Quotient filter''' {{---}} вероятностная структура данных, позволяющая проверить принадлежность элемента множеству. При этом существует возможность получить ложноположительное срабатывание (элемента в множестве нет, но структура данных сообщает, что он есть), но не ложноотрицательное (элемент в множестве есть, но структура данных сообщает, что его нет).<br />
<br />
Существует связь между размером хранилища и шансом ложноположительного срабатывания. Поддерживаются операции добавления нового элемента в множество. С увеличением размера хранимого множества повышается вероятность ложного срабатывания. <br />
Структуру разработал Michael Bender в 2011 году<ref>Bender, Michael A.; Farach-Colton, Martin; Johnson, Rob; Kuszmaul, Bradley C.; Medjedovic, Dzejla; Montes, Pablo; Shetty, Pradeep; Spillane, Richard P.; Zadok, Erez (June 2011).[http://vldb.org/pvldb/vol5/p1627_michaelabender_vldb2012.pdf "Don't thrash: how to cache your hash on flash" (PDF)]</ref> как замена [[:Фильтр_Блума|фильтра Блума]]. Фильтр используется для ускорения ответов в хранилище ключ-значение. <br />
<br />
[[Файл:filter.png|400px|thumb|right|Фильтр используется для ускорения ответов в хранилище ключ-значение. Пары ключ-значение содержатся в хранилище с медленным доступом. Фильтр отфильтровывает ненужные запросы в хранилище (запрос ключа которого точно нет в хранилище), что ускоряет его работу вцелом, но увеличевает потребление памяти]]<br />
<br />
==Описание структуры данных==<br />
<br />
Фильтр представляет собой [[:Хеш-таблица|хеш-таблицу]], в которой харанится часть ключа и <tex>3</tex> бита дополнительной информации. Они используются для разрешения ситуации, когда хеш различных ключей указывает на одну ячейку в хеш-таблице. В quotient filter хеш-функция возвращает <tex>p</tex> битовый хеш, последние r бит которого называются '''остатком''' (англ. ''remainder''), а <tex>q = p - r</tex> старших бит называются '''частным''' (англ. ''quotient''), отсюда название структуры Quotient filter<ref>Knuth, Donald (1973). The Art of Computer Programming:Searching and Sorting, volume 3. Section 6.4, exercise 13: Addison Wesley</ref>. Размер хеш-таблицы составляет <tex>2^q</tex>.<br />
<br />
Пусть у нас есть ключ <tex>K</tex>, его хеш обозначим <tex>H(k)</tex>, остаток <tex>H_r</tex> и частное <tex>H_q</tex>. Попробуем поместить остаток в хеш-таблицу в ячейку <tex>H_q</tex>, называемую канонической. Возможно, ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа.<br />
<br />
Последовательность ячеек, имеющих одинаковые частные называется '''пробегом''' (англ. ''run''). Возможно, что начало пробега не занимает канонический слот, если он уже занят каким-то другим пробегом. <br />
<br />
Пробег, у которого первый элемент занимает каноническую ячейку, является началом кластера. '''Кластер''' (англ. ''cluster'') {{---}} объединение последовательных пробегов, концом кластера является пустая ячейка или начало другого кластера.<br />
<br />
Три дополнительных бита имеют следующие функции:<br />
* бит занятости {{---}} равен единице, если ячейка является канонической для некого ключа в фильтре, сохраненого необязательно в этой ячейке,<br />
* бит продолжения {{---}} равен единице, если ячейка занята, но не первым элементов пробеге,<br />
* бит сдвига {{---}} равен единице, если пробег сдвинут относительно канонического слота.<br />
<br />
{| class="wikitable" border=1<br />
|+<br />
|-align="center" bgcolor=#EEEEFF <br />
! Бит занятости || Бит Продолжения || Бит сдвига || Описание <br />
|-align="center" bgcolor=#FFFFFF<br />
|0||0||0||style="text-align:left;"|Пустая ячейка.<br />
|-align="center" bgcolor=#FFFFFF<br />
|0||0||1||style="text-align:left;"|Ячейка содержит начало пробега, сдвинутого относительно канонического слота.<br />
|-align="center" bgcolor=#FFFFFF<br />
|0||1||0||style="text-align:left;"|Не используется. <br />
|-align="center" bgcolor=#FFFFFF<br />
|0||1||1||style="text-align:left;"|Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||0||0||style="text-align:left;"|Ячейка содержит первый элемет пробега в его каноническом слоте.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||0||1||style="text-align:left;"|Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||1||0||style="text-align:left;"|Не используется.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||1||1||style="text-align:left;"|Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.<br />
|}<br />
<br />
=== Поиск ===<br />
<br />
Пусть мы ищем ключ <tex>K</tex>. Смотрим в его каноническую ячейку <tex>H_q</tex>. Если бит занятости не единица, то элемент точно не содержится в множестве.<br />
Если бит занятости единица, то нам нужно найти пробег для <tex>H_q</tex>. Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки <tex>H_q</tex> и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от <tex>H_q</tex> будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на <tex>1</tex>. После того как мы нашли начало кластера, пойдем от него влево, каждая ячейка с битом продолжения равным нулю говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нужный нам пробег для <tex>H_q</tex>. Если в этом пробеге содержится <tex>H_r</tex>, то <tex>K</tex>, вероятно, содержится в множестве, иначе <tex>K</tex> точно не содержится в множестве.<br />
<br />
=== Вставка ===<br />
<br />
Аналогично с поиском: найдем позицию для <tex>H_r</tex>, сдвигаем на одну позицию влево все эллементы кластера, начиная с выбранного, обновляем дополнительные биты. <br />
<br />
* Сдвиг не влияет на бит занятости. Выставляем бит занятости в ячейке <tex>H_q</tex> в единицу.<br />
* Если мы вставляем <tex>H_r</tex> в начало пробега, следовательно предыдущий элемент пробега стал вторым, у него нужно выставить бит продолжения.<br />
* Мы выставляем бит сдвига в единицу для каждой ячейки, что мы сдвинули.<br />
<br />
== Преимущества ==<br />
<br />
* Последовательное расположение данных. Можно загружать только <tex>1</tex> кластер, уменьшая количество кеш промахов.<br />
* Простое увеличение или уменьшение хеш-таблицы, достаточно перенести один бит из остатка в частное или наоборот.<br />
* Простое слияние двух фильтров.<br />
<br />
==См. также==<br />
<br />
*[[:Идеальное_хеширование|Идеальное хеширование]]<br />
*[[:Универсальное_семейство_хеш-функций|Универсальное хеширование]]<br />
<br />
==Примечания==<br />
<br />
<references /><br />
<br />
== Источники ==<br />
<br />
* [http://en.wikipedia.org/wiki/Quotient_filter Wikipedia — Quotient filter]<br />
* [http://habrahabr.ru/post/242285/ Habrahabr — Quotient filter]<br />
[[Категория: Дискретная математика и алгоритмы ]]<br />
[[Категория: Хеширование]]<br />
[[Категория: Структуры данных]]</div>Kurkinhttp://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Quotient_Filter.png&diff=47859Файл:Quotient Filter.png2015-06-06T19:00:33Z<p>Kurkin: Quotient_filter</p>
<hr />
<div>Quotient_filter</div>Kurkinhttp://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Filter.png&diff=47855Файл:Filter.png2015-06-06T18:56:37Z<p>Kurkin: Принцип работы фильтра</p>
<hr />
<div>Принцип работы фильтра</div>Kurkinhttp://neerc.ifmo.ru/wiki/index.php?title=Quotient_filter&diff=47854Quotient filter2015-06-06T18:51:30Z<p>Kurkin: </p>
<hr />
<div>'''Quotient filter''' {{---}} вероятностная структура данных, позволяющая проверить принадлежность элемента множеству. При этом существует возможность получить ложноположительное срабатывание (элемента в множестве нет, но структура данных сообщает, что он есть), но не ложноотрицательное (элемент в множестве есть, но структура данных сообщает, что его нет).<br />
<br />
Существует связь между размером хранилища и шансом ложноположительного срабатывания. Поддерживаются операции добавления нового элемента в множество. С увеличением размера хранимого множества повышается вероятность ложного срабатывания. <br />
Структуру разработал Michael Bender в 2011 году<ref>Bender, Michael A.; Farach-Colton, Martin; Johnson, Rob; Kuszmaul, Bradley C.; Medjedovic, Dzejla; Montes, Pablo; Shetty, Pradeep; Spillane, Richard P.; Zadok, Erez (June 2011).[http://vldb.org/pvldb/vol5/p1627_michaelabender_vldb2012.pdf "Don't thrash: how to cache your hash on flash" (PDF)]</ref> как замена [[:Фильтр_Блума|фильтра Блума]]. Фильтр используется для ускорения ответов в хранилище ключ-значение. <br />
<br />
==Описание структуры данных==<br />
<br />
Фильтр представляет собой [[:Хеш-таблица|хеш-таблицу]], в которой харанится часть ключа и <tex>3</tex> бита дополнительной информации. Они используются для разрешения ситуации, когда хеш различных ключей указывает на одну ячейку в хеш-таблице. В quotient filter хеш-функция возвращает <tex>p</tex> битовый хеш, последние r бит которого называются '''остатком''' (англ. ''remainder''), а <tex>q = p - r</tex> старших бит называются '''частным''' (англ. ''quotient''), отсюда название структуры Quotient filter<ref>Knuth, Donald (1973). The Art of Computer Programming:Searching and Sorting, volume 3. Section 6.4, exercise 13: Addison Wesley</ref>. Размер хеш-таблицы составляет <tex>2^q</tex>.<br />
<br />
Пусть у нас есть ключ <tex>K</tex>, его хеш обозначим <tex>H(k)</tex>, остаток <tex>H_r</tex> и частное <tex>H_q</tex>. Попробуем поместить остаток в хеш-таблицу в ячейку <tex>H_q</tex>, называемую канонической. Возможно, ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа.<br />
<br />
Последовательность ячеек, имеющих одинаковые частные называется '''пробегом''' (англ. ''run''). Возможно, что начало пробега не занимает канонический слот, если он уже занят каким-то другим пробегом. <br />
<br />
Пробег, у которого первый элемент занимает каноническую ячейку, является началом кластера. '''Кластер''' (англ. ''cluster'') {{---}} объединение последовательных пробегов, концом кластера является пустая ячейка или начало другого кластера.<br />
<br />
Три дополнительных бита имеют следующие функции:<br />
* бит занятости {{---}} равен единице, если ячейка является канонической для некого ключа в фильтре, сохраненого необязательно в этой ячейке,<br />
* бит продолжения {{---}} равен единице, если ячейка занята, но не первым элементов пробеге,<br />
* бит сдвига {{---}} равен единице, если пробег сдвинут относительно канонического слота.<br />
<br />
{| class="wikitable" border=1<br />
|+<br />
|-align="center" bgcolor=#EEEEFF <br />
! Бит занятости || Бит Продолжения || Бит сдвига || Описание <br />
|-align="center" bgcolor=#FFFFFF<br />
|0||0||0||style="text-align:left;"|Пустая ячейка.<br />
|-align="center" bgcolor=#FFFFFF<br />
|0||0||1||style="text-align:left;"|Ячейка содержит начало пробега, сдвинутого относительно канонического слота.<br />
|-align="center" bgcolor=#FFFFFF<br />
|0||1||0||style="text-align:left;"|Не используется. <br />
|-align="center" bgcolor=#FFFFFF<br />
|0||1||1||style="text-align:left;"|Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||0||0||style="text-align:left;"|Ячейка содержит первый элемет пробега в его каноническом слоте.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||0||1||style="text-align:left;"|Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||1||0||style="text-align:left;"|Не используется.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||1||1||style="text-align:left;"|Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.<br />
|}<br />
<br />
=== Поиск ===<br />
<br />
Пусть мы ищем ключ <tex>K</tex>. Смотрим в его каноническую ячейку <tex>H_q</tex>. Если бит занятости не единица, то элемент точно не содержится в множестве.<br />
Если бит занятости единица, то нам нужно найти пробег для <tex>H_q</tex>. Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки <tex>H_q</tex> и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от <tex>H_q</tex> будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на <tex>1</tex>. После того как мы нашли начало кластера, пойдем от него влево, каждая ячейка с битом продолжения равным нулю говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нужный нам пробег для <tex>H_q</tex>. Если в этом пробеге содержится <tex>H_r</tex>, то <tex>K</tex> ,вероятно, содержится в множестве, иначе <tex>K</tex> точно не содержится в множестве.<br />
<br />
=== Вставка ===<br />
<br />
Аналогично с поиском: найдем позицию для <tex>H_r</tex>, сдвигаем на одну позицию влево все эллементы кластера, начиная с выбранного, обновляем дополнительные биты. <br />
<br />
* Сдвиг не влияет на бит занятости. Выставляем бит занятости в ячейке <tex>H_q</tex> в единицу.<br />
* Если мы вставляем <tex>H_r</tex> в начало пробега, следовательно предыдущий элемент пробега стал вторым, у него нужно выставить бит продолжения.<br />
* Мы выставляем бит сдвига в единицу для каждой ячейки, что мы сдвинули.<br />
<br />
== Преимущества ==<br />
<br />
* Последовательное расположение данных. Можно загружать только <tex>1</tex> кластер, уменьшая количество кеш промахов.<br />
* Простое увеличение или уменьшение хеш-таблицы, достаточно перенести один бит из остатка в частное или наоборот.<br />
* Простое слияние двух фильтров.<br />
<br />
==См. также==<br />
<br />
*[[:Идеальное_хеширование|Идеальное хеширование]]<br />
*[[:Универсальное_семейство_хеш-функций|Универсальное хеширование]]<br />
<br />
==Примечания==<br />
<br />
<references /><br />
<br />
== Источники ==<br />
<br />
* [http://en.wikipedia.org/wiki/Quotient_filter Wikipedia — Quotient filter]<br />
* [http://habrahabr.ru/post/242285/ Habrahabr — Quotient filter]<br />
[[Категория: Дискретная математика и алгоритмы ]]<br />
[[Категория: Хеширование]]<br />
[[Категория: Структуры данных]]</div>Kurkinhttp://neerc.ifmo.ru/wiki/index.php?title=Quotient_filter&diff=47846Quotient filter2015-06-06T18:35:55Z<p>Kurkin: </p>
<hr />
<div>'''Quotient filter''' {{---}} вероятностная структура данных, позволяющая проверить принадлежность элемента множеству. При этом существует возможность получить ложноположительное срабатывание (элемента в множестве нет, но структура данных сообщает, что он есть), но не ложноотрицательное (элемент в множестве есть, но структура данных сообщает, что его нет).<br />
<br />
Существует связь между размером хранилища и шансом ложноположительного срабатывания. Поддерживаются операции добавления нового элемента в множество. С увеличением размера хранимого множества повышается вероятность ложного срабатывания. <br />
Структуру разработал Michael Bender в 2011 году<ref>Bender, Michael A.; Farach-Colton, Martin; Johnson, Rob; Kuszmaul, Bradley C.; Medjedovic, Dzejla; Montes, Pablo; Shetty, Pradeep; Spillane, Richard P.; Zadok, Erez (June 2011).[http://vldb.org/pvldb/vol5/p1627_michaelabender_vldb2012.pdf "Don't thrash: how to cache your hash on flash" (PDF)]</ref> как замена [[:Фильтр_Блума|фильтра Блума]].<br />
<br />
==Описание структуры данных==<br />
<br />
Фильтр представляет собой [[:Хеш-таблица|хеш-таблицу]], в которой харанится часть ключа и <tex>3</tex> бита дополнительной информации. Они используются для разрешения ситуации, когда хеш различных ключей указывает на одну ячейку в хеш-таблице. В quotient filter хеш-функция возвращает <tex>p</tex> битовый хеш, последние r бит которого называются '''остатком''' (англ. ''remainder''), а <tex>q = p - r</tex> старших бит называются '''частным''' (англ. ''quotient''), отсюда название структуры Quotient filter<ref>Knuth, Donald (1973). The Art of Computer Programming:Searching and Sorting, volume 3. Section 6.4, exercise 13: Addison Wesley</ref>. Размер хеш-таблицы составляет <tex>2^q</tex>.<br />
<br />
Пусть у нас есть ключ <tex>K</tex>, его хеш обозначим <tex>H(k)</tex>, остаток <tex>H_r</tex> и частное <tex>H_q</tex>. Попробуем поместить остаток в хеш-таблицу в ячейку <tex>H_q</tex>, называемую канонической. Возможно, ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа.<br />
<br />
Последовательность ячеек, имеющих одинаковые частные называется '''пробегом''' (англ. ''run''). Возможно, что начало пробега не занимает канонический слот, если он уже занят каким-то другим пробегом. <br />
<br />
Пробег, у которого первый элемент занимает каноническую ячейку, является началом кластера. '''Кластер''' (англ. ''cluster'') {{---}} объединение последовательных пробегов, концом кластера является пустая ячейка или начало другого кластера.<br />
<br />
Три дополнительных бита имеют следующие функции:<br />
* бит занятости {{---}} равен единице, если ячейка является канонической для некого ключа в фильтре, сохраненого необязательно в этой ячейке,<br />
* бит продолжения {{---}} равен единице, если ячейка занята, но не первым элементов пробеге,<br />
* бит сдвига {{---}} равен единице, если пробег сдвинут относительно канонического слота.<br />
<br />
{| class="wikitable" border=1<br />
|+<br />
|-align="center" bgcolor=#EEEEFF <br />
! Бит занятости || Бит Продолжения || Бит сдвига || Описание <br />
|-align="center" bgcolor=#FFFFFF<br />
|0||0||0||style="text-align:left;"|Пустая ячейка.<br />
|-align="center" bgcolor=#FFFFFF<br />
|0||0||1||style="text-align:left;"|Ячейка содержит начало пробега, сдвинутого относительно канонического слота.<br />
|-align="center" bgcolor=#FFFFFF<br />
|0||1||0||style="text-align:left;"|Не используется. <br />
|-align="center" bgcolor=#FFFFFF<br />
|0||1||1||style="text-align:left;"|Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||0||0||style="text-align:left;"|Ячейка содержит первый элемет пробега в его каноническом слоте.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||0||1||style="text-align:left;"|Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||1||0||style="text-align:left;"|Не используется.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||1||1||style="text-align:left;"|Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.<br />
|}<br />
<br />
=== Поиск ===<br />
<br />
Пусть мы ищем ключ <tex>K</tex>. Смотрим в его каноническую ячейку <tex>H_q</tex>. Если бит занятости не единица, то элемент точно не содержится в множестве.<br />
Если бит занятости единица, то нам нужно найти пробег для <tex>H_q</tex>. Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки <tex>H_q</tex> и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от <tex>H_q</tex> будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на <tex>1</tex>. После того как мы нашли начало кластера, пойдем от него влево, каждая ячейка с битом продолжения равным нулю говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нужный нам пробег для <tex>H_q</tex>. Если в этом пробеге содержится <tex>H_r</tex>, то <tex>K</tex> ,вероятно, содержится в множестве, иначе <tex>K</tex> точно не содержится в множестве.<br />
<br />
=== Вставка ===<br />
<br />
Аналогично с поиском: найдем позицию для <tex>H_r</tex>, сдвигаем на одну позицию влево все эллементы кластера, начиная с выбранного, обновляем дополнительные биты. <br />
<br />
* Сдвиг не влияет на бит занятости. Выставляем бит занятости в ячейке <tex>H_q</tex> в единицу.<br />
* Если мы вставляем <tex>H_r</tex> в начало пробега, следовательно предыдущий элемент пробега стал вторым, у него нужно выставить бит продолжения.<br />
* Мы выставляем бит сдвига в единицу для каждой ячейки, что мы сдвинули.<br />
<br />
== Преимущества ==<br />
<br />
* Последовательное расположение данных. Можно загружать только <tex>1</tex> кластер, уменьшая количество кеш промахов.<br />
* Простое увеличение или уменьшение хеш-таблицы, достаточно перенести один бит из остатка в частное или наоборот.<br />
* Простое слияние двух фильтров.<br />
<br />
==См. также==<br />
<br />
*[[:Идеальное_хеширование|Идеальное хеширование]]<br />
*[[:Универсальное_семейство_хеш-функций|Универсальное хеширование]]<br />
<br />
==Примечания==<br />
<br />
<references /><br />
<br />
== Источники ==<br />
<br />
* [http://en.wikipedia.org/wiki/Quotient_filter Wikipedia — Quotient filter]<br />
* [http://habrahabr.ru/post/242285/ Habrahabr — Quotient filter]<br />
[[Категория: Дискретная математика и алгоритмы ]]<br />
[[Категория: Хеширование]]<br />
[[Категория: Структуры данных]]</div>Kurkinhttp://neerc.ifmo.ru/wiki/index.php?title=Quotient_filter&diff=47843Quotient filter2015-06-06T18:29:30Z<p>Kurkin: </p>
<hr />
<div>'''Quotient filter''' {{---}} вероятностная структура данных, позволяющая проверить принадлежность элемента множеству. При этом существует возможность получить ложноположительное срабатывание (элемента в множестве нет, но структура данных сообщает, что он есть), но не ложноотрицательное (элемент в множестве есть, но структура данных сообщает, что его нет).<br />
<br />
Существует связь между размером хранилища и шансом ложноположительного срабатывания. Поддерживаются операции добавления нового элемента в множество. С увеличением размера хранимого множества повышается вероятность ложного срабатывания. <br />
Структуру разработал Michael Bender в 2011 году<ref>Bender, Michael A.; Farach-Colton, Martin; Johnson, Rob; Kuszmaul, Bradley C.; Medjedovic, Dzejla; Montes, Pablo; Shetty, Pradeep; Spillane, Richard P.; Zadok, Erez (June 2011).[http://vldb.org/pvldb/vol5/p1627_michaelabender_vldb2012.pdf "Don't thrash: how to cache your hash on flash" (PDF)]</ref> как замена [[:Фильтр_Блума|фильтра Блума]].<br />
<br />
==Описание структуры данных==<br />
<br />
Фильтр представляет собой [[:Хеш-таблица|хеш-таблицу]], в которой харанится часть ключа и <tex>3</tex> бита дополнительной информации. Они используются для разрешения ситуации, когда хеш различных ключей указывает на одну ячейку в хеш таблице. В Quotient filter хеш функция возвращает <tex>p</tex> битовый хеш, последние r бит которого называются остатком, а <tex>q = p - r</tex> старших бит называются частным (англ. ''quotient''), отсюда название структуры Quotient filter<ref>Knuth, Donald (1973). The Art of Computer Programming:Searching and Sorting, volume 3. Section 6.4, exercise 13: Addison Wesley</ref>. Размер хеш таблицы составляет <tex>2^q</tex>.<br />
<br />
Пусть у нас есть ключ <tex>K</tex>, его хеш обозначим <tex>H(k)</tex>, остаток <tex>H_r</tex> и частное <tex>H_q</tex>. Попробуем поместить остаток в хеш таблицу в ячейку <tex>H_q</tex>, называемую канонической. Возможно, ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа.<br />
<br />
Последовательность ячеек, имеющих одинаковые частные называется пробегом (англ. ''run''). Возможно, что начало пробега не занимает канонический слот, если он уже занят каким-то другим пробегом. <br />
<br />
Пробег, у которого первый элемент занимает каноническую ячейку, является началом кластера. Кластер (англ. ''cluster'') {{---}} объединение последовательных пробегов, концом кластера является пустая ячейка или начало другого кластера.<br />
<br />
Три дополнительных бита имеют следующие функции:<br />
# бит занятости {{---}} равен единице, если ячейка является канонической для некого ключа в фильтре, сохраненого необязательно в этой ячейке. <br />
# бит продолжения {{---}} равен единице, если ячейка занята, но не первым элементов пробеге.<br />
# бит сдвига {{---}} равен единице, если пробег сдвинут относительно канонического слота.<br />
<br />
{| class="wikitable" border=1<br />
|+<br />
|-align="center" bgcolor=#EEEEFF <br />
! Бит занятости || Бит Продолжения || Бит сдвига || Описание <br />
|-align="center" bgcolor=#FFFFFF<br />
|0||0||0||style="text-align:left;"|Пустая ячейка.<br />
|-align="center" bgcolor=#FFFFFF<br />
|0||0||1||style="text-align:left;"|Ячейка содержит начало пробега, сдвинутого относительно канонического слота.<br />
|-align="center" bgcolor=#FFFFFF<br />
|0||1||0||style="text-align:left;"|Не используется. <br />
|-align="center" bgcolor=#FFFFFF<br />
|0||1||1||style="text-align:left;"|Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||0||0||style="text-align:left;"|Ячейка содержит первый элемет пробега в его каноническом слоте.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||0||1||style="text-align:left;"|Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||1||0||style="text-align:left;"|Не используется.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||1||1||style="text-align:left;"|Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.<br />
|}<br />
<br />
=== Поиск ===<br />
<br />
Пусть мы ищем ключ <tex>K</tex>. Смотрим в его каноническую ячейку <tex>H_q</tex>. Если бит занятости не единица, то элемент точно не содержится в множестве.<br />
Если бит занятости единица, то нам нужно найти пробег для <tex>H_q</tex>. Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки <tex>H_q</tex> и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от <tex>H_q</tex> будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на <tex>1</tex>. После того как мы нашли начало кластера, пойдем от него влево, каждая ячейка с битом продолжения равным нулю говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нужный нам пробег для <tex>H_q</tex>. Если в этом пробеге содержится <tex>H_r</tex>, то <tex>K</tex> ,вероятно, содержится в множестве, иначе <tex>K</tex> точно не содержится в множестве.<br />
<br />
=== Вставка ===<br />
<br />
Аналогично с поиском: найдем позицию для <tex>H_r</tex>, сдвигаем на одну позицию влево все эллементы кластера, начиная с выбранного, обновляем дополнительные биты. <br />
<br />
* Сдвиг не влияет на бит занятости. Выставляем бит занятости в ячейке <tex>H_q</tex> в единицу.<br />
* Если мы вставляем <tex>H_r</tex> в начало пробега, следовательно предыдущий элемент пробега стал вторым, у него нужно выставить бит продолжения.<br />
* Мы выставляем бит сдвига в единицу для каждой ячейки, что мы сдвинули.<br />
<br />
== Преимущества ==<br />
<br />
* Последовательное расположение данных. Можно загружать только <tex>1</tex> кластер, уменьшая количество кеш промахов.<br />
* Простое увеличение или уменьшение хеш таблицы, достаточно перенести один бит из остатка в частное или наоборот.<br />
* Простое слияние двух фильтров.<br />
<br />
==См. также==<br />
<br />
*[[:Идеальное_хеширование|Идеальное хеширование]]<br />
*[[:Универсальное_семейство_хеш-функций|Универсальное хеширование]]<br />
<br />
==Примечания==<br />
<br />
<references /><br />
<br />
== Источники ==<br />
<br />
* [http://en.wikipedia.org/wiki/Quotient_filter Wikipedia — Quotient filter]<br />
* [http://habrahabr.ru/post/242285/ Habrahabr — Quotient filter]<br />
[[Категория: Дискретная математика и алгоритмы ]]<br />
[[Категория: Хеширование]]<br />
[[Категория: Структуры данных]]</div>Kurkinhttp://neerc.ifmo.ru/wiki/index.php?title=Quotient_filter&diff=47840Quotient filter2015-06-06T18:22:43Z<p>Kurkin: </p>
<hr />
<div>'''Quotient filter''' {{---}} вероятностная структура данных, позволяющая проверить принадлежность элемента множеству. При этом существует возможность получить ложноположительное срабатывание (элемента в множестве нет, но структура данных сообщает, что он есть), но не ложноотрицательное(элемент в множестве есть, но структура данных сообщает, что его нет).<br />
<br />
Существует связь между размером хранилища и шансом ложноположительного срабатывания. Поддерживаются операции добавления нового элемента в множество. С увеличением размера хранимого множества повышается вероятность ложного срабатывания. <br />
Структуру разработал Michael Bender в 2011 году<ref>Bender, Michael A.; Farach-Colton, Martin; Johnson, Rob; Kuszmaul, Bradley C.; Medjedovic, Dzejla; Montes, Pablo; Shetty, Pradeep; Spillane, Richard P.; Zadok, Erez (June 2011).[http://vldb.org/pvldb/vol5/p1627_michaelabender_vldb2012.pdf "Don't thrash: how to cache your hash on flash" (PDF)]</ref> как замена [[:Фильтр_Блума|фильтра Блума]].<br />
<br />
==Описание структуры данных==<br />
<br />
Фильтр представляет собой [[:Хеш-таблица|хеш-таблицу]], в которой харанится часть ключа и 3 бита дополнительной информации. Они используются для разрешения ситуации, когда хеш различных ключей указывает на одну ячейку в хеш таблице. В Quotient filter хеш функция возвращает <tex>p</tex> битовый хеш, последние r бит которого называются остатком, а <tex>q = p - r</tex> старших бит называются частным (англ. ''quotient''), отсюда название структуры Quotient filter<ref>Knuth, Donald (1973). The Art of Computer Programming:Searching and Sorting, volume 3. Section 6.4, exercise 13: Addison Wesley</ref>. Размер хеш таблицы составляет <tex>2^q</tex>.<br />
<br />
Пусть у нас есть ключ <tex>D</tex>, его хеш обозначим <tex>Dh</tex>, остаток <tex>Dr</tex> и частное <tex>Dq</tex>. Попробуем поместить остаток в хеш таблицу в ячейку <tex>Dq</tex>, называемую канонической. Возможно, ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа.<br />
<br />
Последовательность ячеек, имеющих одинаковые частные называется пробегом (англ. ''run''). Возможно, что начало пробега не занимает канонический слот, если он уже занят каким-то другим пробегом. <br />
<br />
Пробег, у которого первый элемент занимает каноническую ячейку, является началом кластера. Кластер (англ. ''cluster'') {{---}} объединение последовательных пробегов, концом кластера является пустая ячейка или начало другого кластера.<br />
<br />
Три дополнительных бита имеют следующие функции:<br />
# бит занятости {{---}} равен единице, если ячейка является канонической для некого ключа в фильтре, сохраненого необязательно в этой ячейке. <br />
# бит продолжения {{---}} равен единице, если ячейка занята, но не первым элементов пробеге.<br />
# бит сдвига {{---}} равен единице, если пробег сдвинут относительно канонического слота.<br />
<br />
{| class="wikitable" border=1<br />
|+<br />
|-align="center" bgcolor=#EEEEFF <br />
! Бит занятости || Бит Продолжения || Бит сдвига || Описание <br />
|-align="center" bgcolor=#FFFFFF<br />
|0||0||0||style="text-align:left;"|Пустая ячейка.<br />
|-align="center" bgcolor=#FFFFFF<br />
|0||0||1||style="text-align:left;"|Ячейка содержит начало пробега, сдвинутого относительно канонического слота.<br />
|-align="center" bgcolor=#FFFFFF<br />
|0||1||0||style="text-align:left;"|Не используется. <br />
|-align="center" bgcolor=#FFFFFF<br />
|0||1||1||style="text-align:left;"|Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||0||0||style="text-align:left;"|Ячейка содержит первый элемет пробега в его каноническом слоте.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||0||1||style="text-align:left;"|Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||1||0||style="text-align:left;"|Не используется.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||1||1||style="text-align:left;"|Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.<br />
|}<br />
<br />
=== Поиск ===<br />
<br />
Пусть мы ищем ключ <tex>D</tex>. Смотрим в его каноническую ячейку <tex>Dq</tex>. Если бит занятости не единица, то элемент точно не содержится в множестве.<br />
Если бит занятости единица, то нам нужно найти пробег для <tex>Dq</tex>. Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки <tex>Dq</tex> и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от <tex>Dq</tex> будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на <tex>1</tex>. После того как мы нашли начало кластера, пойдем от него влево, каждая ячейка с битом продолжения равным нулю говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нужный нам пробег для <tex>Dq</tex>. Если в этом пробеге содержится <tex>Dr</tex>, то <tex>D</tex> ,вероятно, содержится в множестве, иначе <tex>D</tex> точно не содержится в множестве.<br />
<br />
=== Вставка ===<br />
<br />
Аналогично с поиском: найдем позицию для <tex>Dr</tex>, сдвигаем на одну позицию влево все эллементы кластера, начиная с выбранного, обновляем дополнительные биты. <br />
<br />
* Сдвиг не влияет на бит занятости. Выставляем бит занятости в ячейке <tex>Dq</tex> в единицу.<br />
* Если мы вставляем <tex>Dr</tex> в начало пробега, следовательно предыдущий элемент пробега стал вторым, у него нужно выставить бит продолжения.<br />
* Мы выставляем бит сдвига в единицу для каждой ячейки, что мы сдвинули.<br />
<br />
== Преимущества ==<br />
<br />
* Последовательное расположение данных. Можно загружать только 1 кластер, уменьшая количество кеш промахов.<br />
* Простое увеличение или уменьшение хеш таблицы, достаточно перенести один бит из остатка в частное или наоборот.<br />
* Простое слияние двух фильтров.<br />
<br />
==См. Также==<br />
<br />
*[[:Идеальное_хеширование|Идеальное хеширование]]<br />
*[[:Универсальное_семейство_хеш-функций|Универсальное хеширование]]<br />
<br />
==Примечания==<br />
<br />
<references /><br />
<br />
== Источники ==<br />
<br />
* [http://en.wikipedia.org/wiki/Quotient_filter Wikipedia — Quotient filter]<br />
* [http://habrahabr.ru/post/242285/ Habrahabr — Quotient filter]<br />
[[Категория: Дискретная математика и алгоритмы ]]<br />
[[Категория: Хеширование]]<br />
[[Категория: Структуры данных]]</div>Kurkinhttp://neerc.ifmo.ru/wiki/index.php?title=Quotient_filter&diff=47834Quotient filter2015-06-06T18:14:40Z<p>Kurkin: /* Описание структуры данных */</p>
<hr />
<div>'''Quotient filter''' {{---}} вероятностная структура данных, позволяющая проверить принадлежность элемента множеству. При этом существует возможность получить ложноположительное срабатывание (элемента в множестве нет, но структура данных сообщает, что он есть), но не ложноотрицательное(элемент в множестве есть, но структура данных сообщает, что его нет).<br />
<br />
Существует связь между размером хранилища и шансом ложноположительного срабатывания. Поддерживаются операции добавления нового элемента в множество. С увеличением размера хранимого множества повышается вероятность ложного срабатывания. <br />
Структуру разработал Michael Bender в 2011 году как замена [[:Фильтр_Блума|фильтра Блума]].<br />
<br />
==Описание структуры данных==<br />
<br />
Фильтр представляет собой [[:Хеш-таблица|хеш-таблицу]], в которой харанится часть ключа и 3 бита дополнительной информации. Они используются для разрешения ситуации, когда хеш различных ключей указывает на одну ячейку в хеш таблице. В Quotient filter хеш функция возвращает <tex>p</tex> битовый хеш, последние r бит которого называются остатком, а <tex>q = p - r</tex> старших бит называются частным (англ. ''quotient''), отсюда название структуры Quotient filter<ref>Knuth, Donald (1973). The Art of Computer Programming:Searching and Sorting, volume 3. Section 6.4, exercise 13: Addison Wesley</ref>. Размер хеш таблицы составляет <tex>2^q</tex>.<br />
<br />
Пусть у нас есть ключ <tex>D</tex>, его хеш обозначим <tex>Dh</tex>, остаток <tex>Dr</tex> и частное <tex>Dq</tex>. Попробуем поместить остаток в хеш таблицу в ячейку <tex>Dq</tex>, называемую канонической. Возможно, ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа.<br />
<br />
Последовательность ячеек, имеющих одинаковые частные называется пробегом (англ. ''run''). Возможно, что начало пробега не занимает канонический слот, если он уже занят каким-то другим пробегом. <br />
<br />
Пробег, у которого первый элемент занимает каноническую ячейку, является началом кластера. Кластер (англ. ''cluster'') {{---}} объединение последовательных пробегов, концом кластера является пустая ячейка или начало другого кластера.<br />
<br />
Три дополнительных бита имеют следующие функции:<br />
# бит занятости {{---}} равен единице, если ячейка является канонической для некого ключа в фильтре, сохраненого необязательно в этой ячейке. <br />
# бит продолжения {{---}} равен единице, если ячейка занята, но не первым элементов пробеге.<br />
# бит сдвига {{---}} равен единице, если пробег сдвинут относительно канонического слота.<br />
<br />
{| class="wikitable" border=1<br />
|+<br />
|-align="center" bgcolor=#EEEEFF <br />
! Бит занятости || Бит Продолжения || Бит сдвига || Описание <br />
|-align="center" bgcolor=#FFFFFF<br />
|0||0||0||style="text-align:left;"|Пустая ячейка.<br />
|-align="center" bgcolor=#FFFFFF<br />
|0||0||1||style="text-align:left;"|Ячейка содержит начало пробега, сдвинутого относительно канонического слота.<br />
|-align="center" bgcolor=#FFFFFF<br />
|0||1||0||style="text-align:left;"|Не используется. <br />
|-align="center" bgcolor=#FFFFFF<br />
|0||1||1||style="text-align:left;"|Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||0||0||style="text-align:left;"|Ячейка содержит первый элемет пробега в его каноническом слоте.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||0||1||style="text-align:left;"|Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||1||0||style="text-align:left;"|Не используется.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||1||1||style="text-align:left;"|Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.<br />
|}<br />
<br />
=== Поиск ===<br />
<br />
Пусть мы ищем ключ <tex>D</tex>. Смотрим в его каноническую ячейку <tex>Dq</tex>. Если бит занятости не единица, то элемент точно не содержится в множестве.<br />
Если бит занятости единица, то нам нужно найти пробег для <tex>Dq</tex>. Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки <tex>Dq</tex> и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от <tex>Dq</tex> будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на <tex>1</tex>. После того как мы нашли начало кластера, пойдем от него влево, каждая ячейка с битом продолжения равным нулю говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нужный нам пробег для <tex>Dq</tex>. Если в этом пробеге содержится <tex>Dr</tex>, то <tex>D</tex> ,вероятно, содержится в множестве, иначе <tex>D</tex> точно не содержится в множестве.<br />
<br />
=== Вставка ===<br />
<br />
Аналогично с поиском: найдем позицию для <tex>Dr</tex>, сдвигаем на одну позицию влево все эллементы кластера, начиная с выбранного, обновляем дополнительные биты. <br />
<br />
* Сдвиг не влияет на бит занятости. Выставляем бит занятости в ячейке <tex>Dq</tex> в единицу.<br />
* Если мы вставляем <tex>Dr</tex> в начало пробега, следовательно предыдущий элемент пробега стал вторым, у него нужно выставить бит продолжения.<br />
* Мы выставляем бит сдвига в единицу для каждой ячейки, что мы сдвинули.<br />
<br />
== Преимущества ==<br />
<br />
* Последовательное расположение данных. Можно загружать только 1 кластер, уменьшая количество кеш промахов.<br />
* Простое увеличение или уменьшение хеш таблицы, достаточно перенести один бит из остатка в частное или наоборот.<br />
* Простое слияние двух фильтров.<br />
<br />
==См. Также==<br />
<br />
*[[:Идеальное_хеширование|Идеальное хеширование]]<br />
*[[:Универсальное_семейство_хеш-функций|Универсальное хеширование]]<br />
<br />
==Примечания==<br />
<br />
<references /><br />
<br />
== Источники ==<br />
<br />
* [http://en.wikipedia.org/wiki/Quotient_filter Wikipedia — Quotient filter]<br />
* [http://habrahabr.ru/post/242285/ Habrahabr — Quotient filter]<br />
[[Категория: Дискретная математика и алгоритмы ]]<br />
[[Категория: Хеширование]]<br />
[[Категория: Структуры данных]]</div>Kurkinhttp://neerc.ifmo.ru/wiki/index.php?title=Quotient_filter&diff=47830Quotient filter2015-06-06T18:07:07Z<p>Kurkin: /* Описание структуры данных */</p>
<hr />
<div>'''Quotient filter''' {{---}} вероятностная структура данных, позволяющая проверить принадлежность элемента множеству. При этом существует возможность получить ложноположительное срабатывание (элемента в множестве нет, но структура данных сообщает, что он есть), но не ложноотрицательное(элемент в множестве есть, но структура данных сообщает, что его нет).<br />
<br />
Существует связь между размером хранилища и шансом ложноположительного срабатывания. Поддерживаются операции добавления нового элемента в множество. С увеличением размера хранимого множества повышается вероятность ложного срабатывания. <br />
Структуру разработал Michael Bender в 2011 году как замена [[:Фильтр_Блума|фильтра Блума]].<br />
<br />
==Описание структуры данных==<br />
<br />
Фильтр представляет собой [[:Хеш-таблица|хеш-таблицу]], в которой харанится часть ключа и 3 бита дополнительной информации. Они используются для разрешения ситуации, когда хеш различных ключей указывает на одну ячейку в хеш таблице. В Quotient filter хеш функция возвращает <tex>p</tex> битовый хеш, последние r бит которого называются остатком, а <tex>q = p - r</tex> старших бит называются частным (англ. ''quotient''), отсюда название структуры Quotient filter<ref>Knuth, Donald (1973). The Art of Computer Programming:Searching and Sorting, volume 3. Section 6.4, exercise 13: Addison Wesley</ref>. Размер хеш таблицы составляет <tex>2^q</tex>.<br />
<br />
Пусть у нас есть ключ <tex>D</tex>, его хеш обозначим <tex>Dh</tex>, остаток <tex>Dr</tex> и частное <tex>Dq</tex>. Попробуем поместить остаток в хеш таблицу в ячейку <tex>Dq</tex>, называемую канонической. Возможно, ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа.<br />
<br />
Последовательность ячеек, имеющих одинаковые частные называется пробегом (англ. ''run''). Возможно, что начало пробега не занимает канонический слот, если он уже занят каким-то другим пробегом. <br />
<br />
Пробег, у которого первый элемент занимает каноническую ячейку, является началом кластера. Кластер (англ. ''cluster'') {{---}} объединение последовательных пробегов, концом кластера является пустая ячейка или начало другого кластера.<br />
<br />
Три дополнительных бита имеют следующие функции:<br />
# бит занятости {{---}} равен единице, если ячейка является канонической для некого ключа в фильтре, сохраненого необязательно в этой ячейке. <br />
# бит продолжения {{---}} равен единице, если ячейка занята, но не первым элементов пробеге.<br />
# бит сдвига {{---}} равен единице, если пробег сдвинут относительно канонического слота.<br />
<br />
{| class="wikitable" style="width:10cm" border=1<br />
|+<br />
|-align="center" bgcolor=#EEEEFF<br />
! Бит занятости || Бит Продолжения || Бит сдвига || Описание <br />
|-align="center" bgcolor=#FFFFFF<br />
|0||0||0||Пустая ячейка.<br />
|-align="center" bgcolor=#FFFFFF<br />
|0||0||1||Ячейка содержит начало пробега, сдвинутого относительно канонического слота.<br />
|-align="center" bgcolor=#FFFFFF<br />
|0||1||0||Не используется. <br />
|-align="center" bgcolor=#FFFFFF<br />
|0||1||1||Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||0||0||Ячейка содержит первый элемет пробега в его каноническом слоте.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||0||1||Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||1||0||Не используется.<br />
|-align="center" bgcolor=#FFFFFF<br />
|1||1||1||Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.<br />
|}<br />
<br />
=== Поиск ===<br />
<br />
Пусть мы ищем ключ <tex>D</tex>. Смотрим в его каноническую ячейку <tex>Dq</tex>. Если бит занятости не единица, то элемент точно не содержится в множестве.<br />
Если бит занятости единица, то нам нужно найти пробег для <tex>Dq</tex>. Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки <tex>Dq</tex> и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от <tex>Dq</tex> будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на <tex>1</tex>. После того как мы нашли начало кластера, пойдем от него влево, каждая ячейка с битом продолжения равным нулю говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нужный нам пробег для <tex>Dq</tex>. Если в этом пробеге содержится <tex>Dr</tex>, то <tex>D</tex> ,вероятно, содержится в множестве, иначе <tex>D</tex> точно не содержится в множестве.<br />
<br />
=== Вставка ===<br />
<br />
Аналогично с поиском: найдем позицию для <tex>Dr</tex>, сдвигаем на одну позицию влево все эллементы кластера, начиная с выбранного, обновляем дополнительные биты. <br />
<br />
* Сдвиг не влияет на бит занятости. Выставляем бит занятости в ячейке <tex>Dq</tex> в единицу.<br />
* Если мы вставляем <tex>Dr</tex> в начало пробега, следовательно предыдущий элемент пробега стал вторым, у него нужно выставить бит продолжения.<br />
* Мы выставляем бит сдвига в единицу для каждой ячейки, что мы сдвинули.<br />
<br />
== Преимущества ==<br />
<br />
* Последовательное расположение данных. Можно загружать только 1 кластер, уменьшая количество кеш промахов.<br />
* Простое увеличение или уменьшение хеш таблицы, достаточно перенести один бит из остатка в частное или наоборот.<br />
* Простое слияние двух фильтров.<br />
<br />
==См. Также==<br />
<br />
*[[:Идеальное_хеширование|Идеальное хеширование]]<br />
*[[:Универсальное_семейство_хеш-функций|Универсальное хеширование]]<br />
<br />
==Примечания==<br />
<br />
<references /><br />
<br />
== Источники ==<br />
<br />
* [http://en.wikipedia.org/wiki/Quotient_filter Wikipedia — Quotient filter]<br />
* [http://habrahabr.ru/post/242285/ Habrahabr — Quotient filter]<br />
[[Категория: Дискретная математика и алгоритмы ]]<br />
[[Категория: Хеширование]]<br />
[[Категория: Структуры данных]]</div>Kurkinhttp://neerc.ifmo.ru/wiki/index.php?title=Quotient_filter&diff=47829Quotient filter2015-06-06T18:00:31Z<p>Kurkin: /* Описание структуры данных */</p>
<hr />
<div>'''Quotient filter''' {{---}} вероятностная структура данных, позволяющая проверить принадлежность элемента множеству. При этом существует возможность получить ложноположительное срабатывание (элемента в множестве нет, но структура данных сообщает, что он есть), но не ложноотрицательное(элемент в множестве есть, но структура данных сообщает, что его нет).<br />
<br />
Существует связь между размером хранилища и шансом ложноположительного срабатывания. Поддерживаются операции добавления нового элемента в множество. С увеличением размера хранимого множества повышается вероятность ложного срабатывания. <br />
Структуру разработал Michael Bender в 2011 году как замена [[:Фильтр_Блума|фильтра Блума]].<br />
<br />
==Описание структуры данных==<br />
<br />
Фильтр представляет собой [[:Хеш-таблица|хеш-таблицу]], в которой харанится часть ключа и 3 бита дополнительной информации. Они используются для разрешения ситуации, когда хеш различных ключей указывает на одну ячейку в хеш таблице. В Quotient filter хеш функция возвращает <tex>p</tex> битовый хеш, последние r бит которого называются остатком, а <tex>q = p - r</tex> старших бит называются частным (англ. ''quotient''), отсюда название структуры Quotient filter<ref>Knuth, Donald (1973). The Art of Computer Programming:Searching and Sorting, volume 3. Section 6.4, exercise 13: Addison Wesley</ref>. Размер хеш таблицы составляет <tex>2^q</tex>.<br />
<br />
Пусть у нас есть ключ <tex>D</tex>, его хеш обозначим <tex>Dh</tex>, остаток <tex>Dr</tex> и частное <tex>Dq</tex>. Попробуем поместить остаток в хеш таблицу в ячейку <tex>Dq</tex>, называемую канонической. Возможно, ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа.<br />
<br />
Последовательность ячеек, имеющих одинаковые частные называется пробегом (англ. ''run''). Возможно, что начало пробега не занимает канонический слот, если он уже занят каким-то другим пробегом. <br />
<br />
Пробег, у которого первый элемент занимает каноническую ячейку, является началом кластера. Кластер (англ. ''cluster'') {{---}} объединение последовательных пробегов, концом кластера является пустая ячейка или начало другого кластера.<br />
<br />
Три дополнительных бита имеют следующие функции:<br />
# бит занятости {{---}} равен единице, если ячейка является канонической для некого ключа в фильтре, сохраненого необязательно в этой ячейке. <br />
# бит продолжения {{---}} равен единице, если ячейка занята, но не первым элементов пробеге.<br />
# бит сдвига {{---}} равен единице, если пробег сдвинут относительно канонического слота.<br />
<br />
<br />
Возможные состояния:<br />
0 0 0 : Пустая ячейка. <br />
0 0 1 : Ячейка содержит начало пробега, сдвинутого относительно канонического слота. <br />
0 1 0 : не используется. <br />
0 1 1 : Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота. <br />
1 0 0 : Ячейка содержит первый элемет пробега в его каноническом слоте. <br />
1 0 1 : Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо. <br />
1 1 0 : не используется. <br />
1 1 1 : Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо. <br />
<br />
=== Поиск ===<br />
<br />
Пусть мы ищем ключ <tex>D</tex>. Смотрим в его каноническую ячейку <tex>Dq</tex>. Если бит занятости не единица, то элемент точно не содержится в множестве.<br />
Если бит занятости единица, то нам нужно найти пробег для <tex>Dq</tex>. Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки <tex>Dq</tex> и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от <tex>Dq</tex> будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на <tex>1</tex>. После того как мы нашли начало кластера, пойдем от него влево, каждая ячейка с битом продолжения равным нулю говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нужный нам пробег для <tex>Dq</tex>. Если в этом пробеге содержится <tex>Dr</tex>, то <tex>D</tex> ,вероятно, содержится в множестве, иначе <tex>D</tex> точно не содержится в множестве.<br />
<br />
=== Вставка ===<br />
<br />
Аналогично с поиском: найдем позицию для <tex>Dr</tex>, сдвигаем на одну позицию влево все эллементы кластера, начиная с выбранного, обновляем дополнительные биты. <br />
<br />
* Сдвиг не влияет на бит занятости. Выставляем бит занятости в ячейке <tex>Dq</tex> в единицу.<br />
* Если мы вставляем <tex>Dr</tex> в начало пробега, следовательно предыдущий элемент пробега стал вторым, у него нужно выставить бит продолжения.<br />
* Мы выставляем бит сдвига в единицу для каждой ячейки, что мы сдвинули.<br />
<br />
== Преимущества ==<br />
<br />
* Последовательное расположение данных. Можно загружать только 1 кластер, уменьшая количество кеш промахов.<br />
* Простое увеличение или уменьшение хеш таблицы, достаточно перенести один бит из остатка в частное или наоборот.<br />
* Простое слияние двух фильтров.<br />
<br />
==См. Также==<br />
<br />
*[[:Идеальное_хеширование|Идеальное хеширование]]<br />
*[[:Универсальное_семейство_хеш-функций|Универсальное хеширование]]<br />
<br />
==Примечания==<br />
<br />
<references /><br />
<br />
== Источники ==<br />
<br />
* [http://en.wikipedia.org/wiki/Quotient_filter Wikipedia — Quotient filter]<br />
* [http://habrahabr.ru/post/242285/ Habrahabr — Quotient filter]<br />
[[Категория: Дискретная математика и алгоритмы ]]<br />
[[Категория: Хеширование]]<br />
[[Категория: Структуры данных]]</div>Kurkinhttp://neerc.ifmo.ru/wiki/index.php?title=Quotient_filter&diff=47828Quotient filter2015-06-06T17:59:10Z<p>Kurkin: </p>
<hr />
<div>'''Quotient filter''' {{---}} вероятностная структура данных, позволяющая проверить принадлежность элемента множеству. При этом существует возможность получить ложноположительное срабатывание (элемента в множестве нет, но структура данных сообщает, что он есть), но не ложноотрицательное(элемент в множестве есть, но структура данных сообщает, что его нет).<br />
<br />
Существует связь между размером хранилища и шансом ложноположительного срабатывания. Поддерживаются операции добавления нового элемента в множество. С увеличением размера хранимого множества повышается вероятность ложного срабатывания. <br />
Структуру разработал Michael Bender в 2011 году как замена [[:Фильтр_Блума|фильтра Блума]].<br />
<br />
==Описание структуры данных==<br />
<br />
Фильтр представляет собой [[:Хеш-таблица|хеш-таблицу]], в которой харанится часть ключа и 3 бита дополнительной информации. Они используются для разрешения ситуации, когда хеш различных ключей указывает на одну ячейку в хеш таблице. В <tex>Quotient filter</tex> хеш функция возвращает <tex>p</tex> битовый хеш, последние r бит которого называются остатком, а <tex>q = p - r</tex> старших бит называются частным (англ. ''quotient''), отсюда название структуры Quotient filter<ref>Knuth, Donald (1973). The Art of Computer Programming:Searching and Sorting, volume 3. Section 6.4, exercise 13: Addison Wesley</ref>. Размер хеш таблицы составляет <tex>2^q</tex>.<br />
<br />
Пусть у нас есть ключ <tex>D</tex>, его хеш обозначим <tex>Dh</tex>, остаток <tex>Dr</tex> и частное <tex>Dq</tex>. Попробуем поместить остаток в хеш таблицу в ячейку <tex>Dq</tex>, называемую канонической. Возможно, ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа.<br />
<br />
Последовательность ячеек, имеющих одинаковые частные называется пробегом (англ. ''run''). Возможно, что начало пробега не занимает канонический слот, если он уже занят каким-то другим пробегом. <br />
<br />
Пробег, у которого первый элемент занимает каноническую ячейку, является началом кластера. Кластер (англ. ''cluster'') {{---}} объединение последовательных пробегов, концом кластера является пустая ячейка или начало другого кластера.<br />
<br />
Три дополнительных бита имеют следующие функции:<br />
# бит занятости {{---}} равен единице, если ячейка является канонической для некого ключа в фильтре, сохраненого необязательно в этой ячейке. <br />
# бит продолжения {{---}} равен единице, если ячейка занята, но не первым элементов пробеге.<br />
# бит сдвига {{---}} равен единице, если пробег сдвинут относительно канонического слота.<br />
<br />
<br />
Возможные состояния:<br />
0 0 0 : Пустая ячейка. <br />
0 0 1 : Ячейка содержит начало пробега, сдвинутого относительно канонического слота. <br />
0 1 0 : не используется. <br />
0 1 1 : Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота. <br />
1 0 0 : Ячейка содержит первый элемет пробега в его каноническом слоте. <br />
1 0 1 : Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо. <br />
1 1 0 : не используется. <br />
1 1 1 : Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо. <br />
<br />
=== Поиск ===<br />
<br />
Пусть мы ищем ключ <tex>D</tex>. Смотрим в его каноническую ячейку <tex>Dq</tex>. Если бит занятости не единица, то элемент точно не содержится в множестве.<br />
Если бит занятости единица, то нам нужно найти пробег для <tex>Dq</tex>. Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки <tex>Dq</tex> и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от <tex>Dq</tex> будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на <tex>1</tex>. После того как мы нашли начало кластера, пойдем от него влево, каждая ячейка с битом продолжения равным нулю говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нужный нам пробег для <tex>Dq</tex>. Если в этом пробеге содержится <tex>Dr</tex>, то <tex>D</tex> ,вероятно, содержится в множестве, иначе <tex>D</tex> точно не содержится в множестве.<br />
<br />
=== Вставка ===<br />
<br />
Аналогично с поиском: найдем позицию для <tex>Dr</tex>, сдвигаем на одну позицию влево все эллементы кластера, начиная с выбранного, обновляем дополнительные биты. <br />
<br />
* Сдвиг не влияет на бит занятости. Выставляем бит занятости в ячейке <tex>Dq</tex> в единицу.<br />
* Если мы вставляем <tex>Dr</tex> в начало пробега, следовательно предыдущий элемент пробега стал вторым, у него нужно выставить бит продолжения.<br />
* Мы выставляем бит сдвига в единицу для каждой ячейки, что мы сдвинули.<br />
<br />
<br />
== Преимущества ==<br />
<br />
* Последовательное расположение данных. Можно загружать только 1 кластер, уменьшая количество кеш промахов.<br />
* Простое увеличение или уменьшение хеш таблицы, достаточно перенести один бит из остатка в частное или наоборот.<br />
* Простое слияние двух фильтров.<br />
<br />
==См. Также==<br />
<br />
*[[:Идеальное_хеширование|Идеальное хеширование]]<br />
*[[:Универсальное_семейство_хеш-функций|Универсальное хеширование]]<br />
<br />
==Примечания==<br />
<br />
<references /><br />
<br />
== Источники ==<br />
<br />
* [http://en.wikipedia.org/wiki/Quotient_filter Wikipedia — Quotient filter]<br />
* [http://habrahabr.ru/post/242285/ Habrahabr — Quotient filter]<br />
[[Категория: Дискретная математика и алгоритмы ]]<br />
[[Категория: Хеширование]]<br />
[[Категория: Структуры данных]]</div>Kurkinhttp://neerc.ifmo.ru/wiki/index.php?title=Quotient_filter&diff=47827Quotient filter2015-06-06T17:58:17Z<p>Kurkin: </p>
<hr />
<div>'''Quotient filter''' {{---}} вероятностная структура данных, позволяющая проверить принадлежность элемента множеству. При этом существует возможность получить ложноположительное срабатывание (элемента в множестве нет, но структура данных сообщает, что он есть), но не ложноотрицательное(элемент в множестве есть, но структура данных сообщает, что его нет).<br />
<br />
Существует связь между размером хранилища и шансом ложноположительного срабатывания. Поддерживаются операции добавления нового элемента в множество. С увеличением размера хранимого множества повышается вероятность ложного срабатывания. <br />
Структуру разработал Michael Bender в 2011 году как замена [[:Фильтр_Блума|фильтра Блума]].<br />
<br />
==Описание структуры данных==<br />
<br />
Фильтр представляет собой [[:Хеш-таблица|хеш-таблицу]], в которой харанится часть ключа и 3 бита дополнительной информации. Они используются для разрешения ситуации, когда хеш различных ключей указывает на одну ячейку в хеш таблице. В <tex>Quotient filter</tex> хеш функция возвращает <tex>p</tex> битовый хеш, последние r бит которого называются остатком, а <tex>q = p - r</tex> старших бит называются частным (англ. ''quotient''), отсюда название структуры Quotient filter (названа Дональдом Кнутом<ref>Knuth, Donald (1973). The Art of Computer Programming:Searching and Sorting, volume 3. Section 6.4, exercise 13: Addison Wesley</ref>). Размер хеш таблицы составляет <tex>2^q</tex>.<br />
<br />
Пусть у нас есть ключ <tex>D</tex>, его хеш обозначим <tex>Dh</tex>, остаток <tex>Dr</tex> и частное <tex>Dq</tex>. Попробуем поместить остаток в хеш таблицу в ячейку <tex>Dq</tex>, называемую канонической. Возможно, ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа.<br />
<br />
Последовательность ячеек, имеющих одинаковые частные называется пробегом (англ. ''run''). Возможно, что начало пробега не занимает канонический слот, если он уже занят каким-то другим пробегом. <br />
<br />
Пробег, у которого первый элемент занимает каноническую ячейку, является началом кластера. Кластер (англ. ''cluster'') {{---}} объединение последовательных пробегов, концом кластера является пустая ячейка или начало другого кластера.<br />
<br />
Три дополнительных бита имеют следующие функции:<br />
# бит занятости {{---}} равен единице, если ячейка является канонической для некого ключа в фильтре, сохраненого необязательно в этой ячейке. <br />
# бит продолжения {{---}} равен единице, если ячейка занята, но не первым элементов пробеге.<br />
# бит сдвига {{---}} равен единице, если пробег сдвинут относительно канонического слота.<br />
<br />
<br />
Возможные состояния:<br />
0 0 0 : Пустая ячейка. <br />
0 0 1 : Ячейка содержит начало пробега, сдвинутого относительно канонического слота. <br />
0 1 0 : не используется. <br />
0 1 1 : Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота. <br />
1 0 0 : Ячейка содержит первый элемет пробега в его каноническом слоте. <br />
1 0 1 : Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо. <br />
1 1 0 : не используется. <br />
1 1 1 : Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо. <br />
<br />
=== Поиск ===<br />
<br />
Пусть мы ищем ключ <tex>D</tex>. Смотрим в его каноническую ячейку <tex>Dq</tex>. Если бит занятости не единица, то элемент точно не содержится в множестве.<br />
Если бит занятости единица, то нам нужно найти пробег для <tex>Dq</tex>. Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки <tex>Dq</tex> и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от <tex>Dq</tex> будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на <tex>1</tex>. После того как мы нашли начало кластера, пойдем от него влево, каждая ячейка с битом продолжения равным нулю говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нужный нам пробег для <tex>Dq</tex>. Если в этом пробеге содержится <tex>Dr</tex>, то <tex>D</tex> ,вероятно, содержится в множестве, иначе <tex>D</tex> точно не содержится в множестве.<br />
<br />
=== Вставка ===<br />
<br />
Аналогично с поиском: найдем позицию для <tex>Dr</tex>, сдвигаем на одну позицию влево все эллементы кластера, начиная с выбранного, обновляем дополнительные биты. <br />
<br />
* Сдвиг не влияет на бит занятости. Выставляем бит занятости в ячейке <tex>Dq</tex> в единицу.<br />
* Если мы вставляем <tex>Dr</tex> в начало пробега, следовательно предыдущий элемент пробега стал вторым, у него нужно выставить бит продолжения.<br />
* Мы выставляем бит сдвига в единицу для каждой ячейки, что мы сдвинули.<br />
<br />
<br />
== Преимущества ==<br />
<br />
* Последовательное расположение данных. Можно загружать только 1 кластер, уменьшая количество кеш промахов.<br />
* Простое увеличение или уменьшение хеш таблицы, достаточно перенести один бит из остатка в частное или наоборот.<br />
* Простое слияние двух фильтров.<br />
<br />
==См. Также==<br />
<br />
*[[:Идеальное_хеширование|Идеальное хеширование]]<br />
*[[:Универсальное_семейство_хеш-функций|Универсальное хеширование]]<br />
<br />
==Примечания==<br />
<br />
<references /><br />
<br />
== Источники ==<br />
<br />
* [http://en.wikipedia.org/wiki/Quotient_filter Wikipedia — Quotient filter]<br />
* [http://habrahabr.ru/post/242285/ Habrahabr — Quotient filter]<br />
[[Категория: Дискретная математика и алгоритмы ]]<br />
[[Категория: Хеширование]]<br />
[[Категория: Структуры данных]]</div>Kurkinhttp://neerc.ifmo.ru/wiki/index.php?title=Quotient_filter&diff=47826Quotient filter2015-06-06T17:51:19Z<p>Kurkin: </p>
<hr />
<div>'''Quotient filter''' {{---}} вероятностная структура данных, позволяющая проверить принадлежность элемента множеству. При этом существует возможность получить ложноположительное срабатывание (элемента в множестве нет, но структура данных сообщает, что он есть), но не ложноотрицательное(элемент в множестве есть, но структура данных сообщает, что его нет).<br />
<br />
Существует связь между размером хранилища и шансом ложноположительного срабатывания. Поддерживаются операции добавления нового элемента в множество. С увеличением размера хранимого множества повышается вероятность ложного срабатывания. <br />
Структура разработана в 2011 году Бендером как замена [[:Фильтр_Блума|фильтра Блума]].<br />
<br />
==Описание структуры данных==<br />
<br />
Фильтр представляет собой хеш таблицу, в которой харанится часть ключа и 3 бита дополнительной информации. Они используются для разрешения ситуации, когда хеш различных ключей указывает на одну ячейку в хеш таблице. В <tex>Quotient filter</tex> хеш функция возвращает <tex>p</tex> битовый хеш, последние r бит которого называются остатком, а <tex>q = p - r</tex> старших бит называются частным (англ. ''quotient''), отсюда название структуры Quotient filter(придумано Кнутом в The Art of Computer Programming:Searching and Sorting, volume 3. Section 6.4, exercise 13). Размер хеш таблицы составляет <tex>2^q</tex>.<br />
<br />
Пусть у нас есть ключ <tex>D</tex>, его хеш обозначим <tex>Dh</tex>, остаток <tex>Dr</tex> и частное <tex>Dq</tex>. Попробуем поместить остаток в хеш таблицу в ячейку <tex>Dq</tex>, называемую канонической. Возможно, ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа.<br />
<br />
Последовательность ячеек, имеющих одинаковые частные называется пробегом (англ. ''run''). Возможно, что начало пробега не занимает канонический слот, если он уже занят каким-то другим пробегом. <br />
<br />
Пробег, у которого первый элемент занимает каноническую ячейку, является началом кластера. Кластер (англ. ''cluster'') {{---}} объединение последовательных пробегов, концом кластера является пустая ячейка или начало другого кластера.<br />
<br />
Три дополнительных бита имеют следующие функции:<br />
# бит занятости {{---}} равен единице, если ячейка является канонической для некого ключа в фильтре, сохраненого необязательно в этой ячейке. <br />
# бит продолжения {{---}} равен единице, если ячейка занята, но не первым элементов пробеге.<br />
# бит сдвига {{---}} равен единице, если пробег сдвинут относительно канонического слота.<br />
<br />
<br />
Возможные состояния:<br />
0 0 0 : Пустая ячейка. <br />
0 0 1 : Ячейка содержит начало пробега, сдвинутого относительно канонического слота. <br />
0 1 0 : не используется. <br />
0 1 1 : Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота. <br />
1 0 0 : Ячейка содержит первый элемет пробега в его каноническом слоте. <br />
1 0 1 : Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо. <br />
1 1 0 : не используется. <br />
1 1 1 : Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо. <br />
<br />
=== Поиск ===<br />
<br />
Пусть мы ищем ключ <tex>D</tex>. Смотрим в его каноническую ячейку <tex>Dq</tex>. Если бит занятости не единица, то элемент точно не содержится в множестве.<br />
Если бит занятости единица, то нам нужно найти пробег для <tex>Dq</tex>. Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки <tex>Dq</tex> и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от <tex>Dq</tex> будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на <tex>1</tex>. После того как мы нашли начало кластера, пойдем от него влево, каждая ячейка с битом продолжения равным нулю говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нужный нам пробег для <tex>Dq</tex>. Если в этом пробеге содержится <tex>Dr</tex>, то <tex>D</tex> ,вероятно, содержится в множестве, иначе <tex>D</tex> точно не содержится в множестве.<br />
<br />
=== Вставка ===<br />
<br />
Аналогично с поиском: найдем позицию для <tex>Dr</tex>, сдвигаем на одну позицию влево все эллементы кластера, начиная с выбранного, обновляем дополнительные биты. <br />
<br />
* Сдвиг не влияет на бит занятости. Выставляем бит занятости в ячейке <tex>Dq</tex> в единицу.<br />
* Если мы вставляем <tex>Dr</tex> в начало пробега, следовательно предыдущий элемент пробега стал вторым, у него нужно выставить бит продолжения.<br />
* Мы выставляем бит сдвига в единицу для каждой ячейки, что мы сдвинули.<br />
<br />
<br />
== Преимущества ==<br />
<br />
* Последовательное расположение данных. Можно загружать только 1 кластер, уменьшая количество кеш промахов.<br />
* Простое увеличение или уменьшение хеш таблицы, достаточно перенести один бит из остатка в частное или наоборот.<br />
* Простое слияние двух фильтров.<br />
<br />
==См. Также==<br />
<br />
*[[:Идеальное_хеширование|Идеальное хеширование]]<br />
*[[:Универсальное_семейство_хеш-функций|Универсальное хеширование]]<br />
<br />
==Примечания==<br />
<br />
<references /><br />
<br />
== Источники ==<br />
<br />
* [http://en.wikipedia.org/wiki/Quotient_filter Wikipedia — Quotient filter]<br />
* [http://habrahabr.ru/post/242285/ Habrahabr — Quotient filter]<br />
[[Категория: Дискретная математика и алгоритмы ]]<br />
[[Категория: Хеширование]]<br />
[[Категория: Структуры данных]]</div>Kurkinhttp://neerc.ifmo.ru/wiki/index.php?title=Quotient_filter&diff=47825Quotient filter2015-06-06T17:47:15Z<p>Kurkin: Новая страница: «'''Quotient filter''' {{---}} вероятностная структура данных, позволяющая проверить принадлежность ...»</p>
<hr />
<div>'''Quotient filter''' {{---}} вероятностная структура данных, позволяющая проверить принадлежность элемента множеству. При этом существует возможность получить ложноположительное срабатывание (элемента в множестве нет, но структура данных сообщает, что он есть), но не ложноотрицательное(элемент в множестве есть, но структура данных сообщает, что его нет).<br />
<br />
Существует связь между размером хранилища и шансом ложноположительного срабатывания. Поддерживаются операции добавления нового элемента в множество. С увеличением размера хранимого множества повышается вероятность ложного срабатывания. <br />
Структура разработана в 2011 году Бендером как замена [[:Фильтр_Блума|фильтра Блума]].<br />
<br />
==Описание структуры данных==<br />
<br />
Фильтр представляет собой хеш таблицу, в которой харанится часть ключа и 3 бита дополнительной информации. Они используются для разрешения ситуации, когда хеш различных ключей указывает на одну ячейку в хеш таблице. В <tex>Quotient filter</tex> хеш функция возвращает <tex>p</tex> битовый хеш, последние r бит которого называются остатком, а <tex>q = p - r</tex> старших бит называются частным (англ. ''quotient''), отсюда название структуры Quotient filter(придумано Кнутом в The Art of Computer Programming:Searching and Sorting, volume 3. Section 6.4, exercise 13). Размер хеш таблицы составляет <tex>2^q</tex>.<br />
<br />
Пусть у нас есть ключ <tex>D</tex>, его хеш обозначим <tex>Dh</tex>, остаток <tex>Dr</tex> и частное <tex>Dq</tex>. Попробуем поместить остаток в хеш таблицу в ячейку <tex>Dq</tex>, называемую канонической. Возможно, ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа.<br />
<br />
Последовательность ячеек, имеющих одинаковые частные называется пробегом (англ. ''run''). Возможно, что начало пробега не занимает канонический слот, если он уже занят каким-то другим пробегом. <br />
<br />
Пробег, у которого первый элемент занимает каноническую ячейку, является началом кластера. Кластер (англ. ''cluster'') {{---}} объединение последовательных пробегов, концом кластера является пустая ячейка или начало другого кластера.<br />
<br />
Три дополнительных бита имеют следующие функции:<br />
# бит занятости {{---}} равен единице, если ячейка является канонической для некого ключа в фильтре, сохраненого необязательно в этой ячейке. <br />
# бит продолжения {{---}} равен единице, если ячейка занята, но не первым элементов пробеге.<br />
# бит сдвига {{---}} равен единице, если пробег сдвинут относительно канонического слота.<br />
<br />
<br />
Возможные состояния:<br />
0 0 0 : Пустая ячейка. <br />
0 0 1 : Ячейка содержит начало пробега, сдвинутого относительно канонического слота. <br />
0 1 0 : не используется. <br />
0 1 1 : Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота. <br />
1 0 0 : Ячейка содержит первый элемет пробега в его каноническом слоте. <br />
1 0 1 : Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо. <br />
1 1 0 : не используется. <br />
1 1 1 : Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо. <br />
<br />
=== Поиск ===<br />
<br />
Пусть мы ищем ключ <tex>D</tex>. Смотрим в его каноническую ячейку <tex>Dq</tex>. Если бит занятости не единица, то элемент точно не содержится в множестве.<br />
Если бит занятости единица, то нам нужно найти пробег для <tex>Dq</tex>. Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки <tex>Dq</tex> и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от <tex>Dq</tex> будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на <tex>1</tex>. После того как мы нашли начало кластера, пойдем от него влево, каждая ячейка с битом продолжения равным нулю говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нужный нам пробег для <tex>Dq</tex>. Если в этом пробеге содержится <tex>Dr</tex>, то <tex>D</tex> ,вероятно, содержится в множестве, иначе <tex>D</tex> точно не содержится в множестве.<br />
<br />
=== Вставка ===<br />
<br />
Аналогично с поиском: найдем позицию для <tex>Dr</tex>, сдвигаем на одну позицию влево все эллементы кластера, начиная с выбранного, обновляем дополнительные биты. <br />
<br />
* Сдвиг не влияет на бит занятости. Выставляем бит занятости в ячейке <tex>Dq</tex> в единицу.<br />
* Если мы вставляем <tex>Dr</tex> в начало пробега, следовательно предыдущий элемент пробега стал вторым, у него нужно выставить бит продолжения.<br />
* Мы выставляем бит сдвига в единицу для каждой ячейки, что мы сдвинули.<br />
<br />
<br />
== Преимущества ==<br />
<br />
* Последовательное расположение данных. Можно загружать только 1 кластер, уменьшая количество кеш промахов.<br />
* Простое увеличение или уменьшение хеш таблицы, достаточно перенести один бит из остатка в частное или наоборот.<br />
* Простое слияние двух фильтров.<br />
<br />
==См. Также==<br />
<br />
*[[:Идеальное_хеширование|Идеальное хеширование]]<br />
*[[:Универсальное_хеширование|Универсальное хеширование]]<br />
<br />
<br />
== Источники ==<br />
<br />
* [http://en.wikipedia.org/wiki/Quotient_filter Quotient filter — Wikipedia]<br />
* [http://habrahabr.ru/post/242285/ Quotient filter — Habrahabr]<br />
[[Категория: Дискретная математика и алгоритмы ]]<br />
[[Категория: Хеширование]]</div>Kurkinhttp://neerc.ifmo.ru/wiki/index.php?title=%D0%94%D0%B8%D1%81%D0%BA%D1%80%D0%B5%D1%82%D0%BD%D0%B0%D1%8F_%D0%BC%D0%B0%D1%82%D0%B5%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B0,_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D0%B8_%D1%81%D1%82%D1%80%D1%83%D0%BA%D1%82%D1%83%D1%80%D1%8B_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&diff=47824Дискретная математика, алгоритмы и структуры данных2015-06-06T17:46:56Z<p>Kurkin: /* Хеширование */</p>
<hr />
<div>[[Категория:Дискретная математика и алгоритмы]]<br />
[[Категория: Алгоритмы и структуры данных]]<br />
Убедительная просьба читать [[Обсуждение:Дискретная_математика_и_алгоритмы | правила оформления вики-конспектов]].<br />
<br />
Символом <tex> \star </tex> помечены дополнительные темы (возможно, сложные), которые не были подробно рассмотрены (или вообще рассмотрены) в рамках курса.<br />
<br />
= Первый семестр =<br />
<br />
== Отношения ==<br />
*[[Определение отношения]]<br />
*[[Композиция отношений|Композиция отношений, степень отношения, обратное отношение]]<br />
*[[Рефлексивное отношение|Рефлексивное отношение. Антирефлексивное отношение.]]<br />
*[[Симметричное отношение]]<br />
*[[Антисимметричное отношение]]<br />
*[[Транзитивное отношение]]<br />
*[[Отношение порядка]]<br />
*[[Отношение эквивалентности]]<br />
*[[Транзитивное замыкание|Транзитивное замыкание отношения]]<br />
*[[Алгоритм Флойда — Уоршелла|Алгоритм Флойда-Уоршалла построения транзитивного замыкания отношения]]<br />
*[[Транзитивный остов]]<br />
<br />
== Булевы функции ==<br />
*[[Определение булевой функции]]<br />
*[[Суперпозиции]]<br />
*[[ДНФ]]<br />
*[[Сокращенная и минимальная ДНФ | Сокращенная и минимальная ДНФ, минимизация ДНФ методами гиперкубов, карт Карно, Квайна]]<br />
*[[КНФ]]<br />
*[[Специальные формы КНФ|Специальные формы КНФ: КНФ в форме Хорна и КНФ в форме Крома]]<br />
*[[Полином Жегалкина | Полином Жегалкина, преобразование Мёбиуса]]<br />
*[[Полные системы функций. Теорема Поста о полной системе функций]]<br />
*[[Представление функции класса DM с помощью медианы]]<br />
*[[Пороговая функция]]<br />
*[[Троичная логика]]<tex>^\star</tex><br />
<br />
== Схемы из функциональных элементов ==<br />
*[[Реализация булевой функции схемой из функциональных элементов]]<br />
*[[Простейшие методы синтеза схем из функциональных элементов]]<br />
*[[Метод Лупанова синтеза схем]]<br />
*[[Cумматор]]<br />
*[[Каскадный сумматор]]<br />
*[[Двоичный каскадный сумматор]]<br />
*[[Троичный сумматор]]<tex>^\star</tex><br />
*[[Реализация вычитания сумматором]]<br />
*[[Матричный умножитель]]<br />
*[[Дерево Уоллеса]]<br />
*[[Контактная схема]]<br />
*[[Квантовые гейты]]<tex>^\star</tex><br />
<br />
== Представление информации ==<br />
*[[Кодирование информации]]<br />
*[[Представление целых чисел: прямой код, код со сдвигом, дополнительный код]]<br />
*[[Представление вещественных чисел]]<br />
*[[Представление символов, таблицы кодировок]]<tex>^\star</tex><br />
<br />
== Алгоритмы сжатия ==<br />
* [[Алгоритм Хаффмана]]<br />
* [[Оптимальное хранение словаря в алгоритме Хаффмана]]<br />
* [[Алгоритм Хаффмана за O(n)]]<br />
* [[Алгоритм Ху-Таккера]]<tex>^\star</tex><br />
* [[Неравенство Крафта]]<br />
* [[Неравенство Макмиллана]]<br />
* [[Код Шеннона]]<br />
* [[Оптимальный префиксный код с длиной кодового слова не более L бит]]<tex>^\star</tex><br />
* [[Алгоритмы LZ77 и LZ78]]<br />
* [[Алгоритм LZW]]<br />
* [[Алгоритм LZSS]]<tex>^\star</tex><br />
* [[Преобразование Барроуза-Уиллера | Преобразование Барроуза-Уиллера и обратное ему]]<br />
* [[Преобразование MTF]]<br />
* [[Расстояние Хэмминга]]<br />
* [[Избыточное кодирование, код Хэмминга]]<br />
* [[Гамма-, дельта- и омега-код Элиаса]]<tex>^\star</tex><br />
<br />
== Комбинаторика ==<br />
=== Комбинаторные объекты ===<br />
* [[Комбинаторные объекты]]<br />
* [[Лексикографический порядок]]<br />
* [[Коды Грея]]<br />
* [[Коды Грея для перестановок]]<br />
* [[Коды антигрея]]<br />
* [[Цепные коды]]<br />
* [[Правильные скобочные последовательности]]<br />
<br />
=== Генерация комбинаторных объектов ===<br />
* [[Генерация комбинаторных объектов в лексикографическом порядке]]<br />
* [[Получение номера по объекту]]<br />
* [[Получение объекта по номеру]]<br />
* [[Получение следующего объекта]]<br />
* [[Получение предыдущего объекта]]<tex>^\star</tex> <br />
* [[Метод генерации случайной перестановки, алгоритм Фишера-Йетса]]<br />
* [[Методы генерации случайного сочетания]]<tex>^\star</tex><br />
<br />
=== Подсчёт числа объектов ===<br />
* [[Формула включения-исключения | Формула включения-исключения, подсчет числа беспорядков]]<br />
* [[Нахождение количества разбиений числа на слагаемые | Нахождение количества разбиений числа на слагаемые. Пентагональная теорема Эйлера]]<br />
* [[Производящая функция]]<br />
* [[Лемма Бёрнсайда и Теорема Пойа]]<br />
* [[Задача об ожерельях]]<br />
* [[Числа Стирлинга первого рода]]<br />
* [[Числа Стирлинга второго рода]]<br />
* [[Числа Эйлера I и II рода | Числа Эйлера первого и второго рода. Подъемы в перестановках]]<tex>^\star</tex><br />
* [[Числа Каталана]]<br />
<br />
=== Свойства комбинаторных объектов ===<br />
* [[Умножение перестановок, обратная перестановка, группа перестановок]]<br />
* [[Действие перестановки на набор из элементов, представление в виде циклов]]<br />
* [[Таблица инверсий]]<br />
* [[Теорема Кэли]]<br />
* [[Матричное представление перестановок]]<br />
* [[Задача о минимуме/максимуме скалярного произведения]]<br />
* [[Задача о монотонных подпоследовательностях, теорема о связи длины НВП и НУП]]<br />
<br />
== [[Динамическое программирование]] ==<br />
=== Классические задачи динамического программирования ===<br />
*[[Кратчайший путь в ациклическом графе]]<br />
*[[Задача о числе путей в ациклическом графе]]<br />
*[[Задача о расстановке знаков в выражении]]<br />
*[[Задача о порядке перемножения матриц]]<br />
*[[Задача о наибольшей общей подпоследовательности]]<br />
*[[Задача о наибольшей возрастающей подпоследовательности]]<br />
*[[Задача коммивояжера, ДП по подмножествам]]<br />
*[[Задача о редакционном расстоянии, алгоритм Вагнера-Фишера]]<br />
*[[Задача о рюкзаке]]<br />
<br />
=== Способы оптимизации методов динамического программирования ===<br />
*[[Метод четырех русских для умножения матриц]]<tex>^\star</tex><br />
*[[Применение метода четырех русских в задачах ДП на примере задачи о НОП]]<tex>^\star</tex><br />
*[[Задача об оптимальном префиксном коде с сохранением порядка. Монотонность точки разреза]]<br />
*[[Meet-in-the-middle]]<tex>^\star</tex><br />
<br />
=== Другие задачи ===<br />
*[[Задача о расстоянии Дамерау-Левенштейна]]<tex>^\star</tex><br />
*[[Задача о выводе в контекстно-свободной грамматике, алгоритм Кока-Янгера-Касами]]<br />
*[[Задача о наибольшей подпоследовательности-палиндроме]]<br />
*[[Наибольшая общая возрастающая подпоследовательность]]<tex>^\star</tex><br />
*[[Задача о наибольшей общей палиндромной подпоследовательности]]<tex>^\star</tex><br />
*[[Динамическое программирование по профилю]]<tex>^\star</tex><br />
*[[Динамика по поддеревьям]]<br />
<br />
== Теория вероятностей ==<br />
*[[Вероятностное пространство, элементарный исход, событие]]<br />
*[[Независимые события]]<br />
*[[Условная вероятность]]<br />
*[[Формула полной вероятности]]<br />
*[[Формула Байеса]]<br />
*[[Дискретная случайная величина]]<br />
*[[Независимые случайные величины]]<br />
*[[Математическое ожидание случайной величины]]<br />
*[[Дисперсия случайной величины]]<br />
*[[Ковариация случайных величин]]<br />
*[[Корреляция случайных величин]]<br />
*[[Неравенство Маркова]]<br />
*[[Энтропия случайного источника]]<br />
*[[Симуляция одним распределением другого]]<br />
*[[Арифметическое кодирование]]<br />
*[[Парадоксы теории вероятностей]]<tex>^\star</tex><br />
*[[Схема Бернулли]]<tex>^\star</tex><br />
<br />
== Марковские цепи ==<br />
<br />
* [[Марковская цепь]]<br />
* [[Теорема о поглощении]]<br />
* [[Фундаментальная матрица]]<br />
* [[Математическое ожидание времени поглощения]]<br />
* [[Расчет вероятности поглощения в состоянии]]<br />
* [[Эргодическая марковская цепь]]<br />
* [[Регулярная марковская цепь]]<br />
* [[Примеры использования Марковских цепей]]<br />
* [[Скрытые Марковские модели]]<tex>^\star</tex><br />
* [[Алгоритм Витерби]]<tex>^\star</tex><br />
* [[Алгоритм "Вперед-Назад"]]<tex>^\star</tex><br />
* [[Алгоритм Баума-Велша]]<tex>^\star</tex><br />
<br />
= Второй семестр =<br />
<br />
== Амортизационный анализ ==<br />
* [[Амортизационный анализ]]<br />
* [[Динамический массив]]<br />
* [[Hashed Array Tree]]<tex>^\star</tex><br />
* [[Список]]<br />
* [[Стек]]<br />
* [[Очередь]]<br />
* [[Мажорирующий элемент]]<br />
* [[Счетчик Кнута]]<br />
* [[Мастер-теорема]]<tex>^\star</tex><br />
<br />
== Персистентные структуры данных ==<br />
* [[Персистентные структуры данных]]<br />
* [[Персистентный стек]]<br />
* [[Персистентная очередь]]<br />
* [[Персистентный дек]]<br />
* [[Персистентная приоритетная очередь]]<br />
<br />
== Приоритетные очереди ==<br />
<br />
* [[Двоичная куча]]<br />
* [[Биномиальная куча]]<br />
* [[Фибоначчиева куча]]<br />
* [[Левосторонняя куча]]<br />
* [[Тонкая куча]]<br />
* [[Толстая куча на избыточном счетчике]]<br />
* [[Куча Бродала-Окасаки]]<tex>^\star</tex><br />
<br />
== Система непересекающихся множеств ==<br />
* [[СНМ (наивные реализации) | Наивные реализации]]<br />
* [[СНМ (списки с весовой эвристикой) | Списки с весовой эвристикой]]<br />
* [[СНМ(реализация с помощью леса корневых деревьев) | Реализация с помощью леса корневых деревьев]]<br />
* [[СНМ с операцией удаления за О(1)]]<tex>^\star</tex><br />
<br />
== [[Поисковые структуры данных]] ==<br />
* [[Упорядоченное множество]]<br />
* [[Дерево поиска, наивная реализация]]<br />
* [[АВЛ-дерево]]<br />
* [[2-3 дерево]]<br />
* [[B-дерево]]<br />
* [[Красно-черное дерево]]<br />
* [[Декартово дерево]]<br />
* [[Декартово дерево по неявному ключу]]<br />
* [[Splay-дерево]]<br />
* [[Tango-дерево]]<tex>^\star</tex><br />
* [[Рандомизированное бинарное дерево поиска]]<br />
* [[Дерево ван Эмде Боаса]]<br />
* [[Список с пропусками]]<br />
* [[Fusion tree]]<tex>^\star</tex><br />
* [[Сверхбыстрый цифровой бор]]<br />
* [[Rope]]<tex>^\star</tex><br />
<br />
== Дерево отрезков ==<br />
<br />
* [[Статистики на отрезках. Корневая эвристика]]<br />
* [[Дерево отрезков. Построение]]<br />
* [[Реализация запроса в дереве отрезков сверху]]<br />
* [[Реализация запроса в дереве отрезков снизу]]<br />
* [[Несогласованные поддеревья. Реализация массового обновления]]<br />
* [[Многомерное дерево отрезков]]<br />
* [[Сжатое многомерное дерево отрезков]]<br />
<br />
== Дерево Фенвика ==<br />
* [[Дерево Фенвика]]<br />
* [[Встречное дерево Фенвика]]<br />
* [[Дерево Фенвика для некоммутативных операций]]<br />
* [[Многомерное дерево Фенвика]]<br />
<br />
== Хеширование ==<br />
* [[Хеш-таблица]]<br />
* [[Разрешение коллизий]]<br />
* [[Хеширование кукушки]]<br />
* [[Идеальное хеширование]]<br />
* [[Перехеширование]]<br />
* [[Фильтр Блума]]<br />
* [[Quotient filter]]<br />
* [[Универсальное семейство хеш-функций]]<br />
* [[Расширяемое хеширование]]<tex>^\star</tex><br />
<br />
== [[Сортировки]] ==<br />
=== Квадратичные сортировки ===<br />
* [[Сортировка выбором]]<br />
* [[Сортировка пузырьком]]<br />
* [[Сортировка вставками]]<br />
=== Сортировки на сравнениях ===<br />
* [[Сортировка Шелла]]<tex>^\star</tex><br />
* [[Сортировка кучей]]<br />
* [[Быстрая сортировка]]<br />
* [[Сортировка слиянием]]<br />
* [[Cортировка слиянием с использованием O(1) дополнительной памяти]]<br />
* [[Терпеливая сортировка]]<tex>^\star</tex><br />
* [[Timsort]]<tex>^\star</tex><br />
* [[Smoothsort]]<tex>^\star</tex><br />
* [[Теорема о нижней оценке для сортировки сравнениями]]<br />
<br />
=== Многопоточные сортировки ===<br />
* [[Многопоточная сортировка слиянием]]<tex>^\star</tex><br />
* [[PSRS-сортировка]]<tex>^\star</tex><br />
=== Другие сортировки ===<br />
* [[Поиск k-ой порядковой статистики]]<br />
* [[Поиск k-ой порядковой статистики за линейное время]]<br />
* [[Поиск k-ой порядковой статистики в двух массивах]]<tex>^\star</tex><br />
* [[Сортировка подсчетом]]<br />
* [[Цифровая сортировка]]<br />
* [[Карманная сортировка]]<br />
* [[Сортировка Хана]]<tex>^\star</tex><br />
<br />
== Сортирующие сети ==<br />
* [[Сортирующие сети]]<br />
* [[0-1 принцип | Проверка сети компараторов на то, что она сортирующая. 0-1 принцип]]<br />
* [[Сортирующие сети для квадратичных сортировок]]<br />
* [[Сортировочные сети с особыми свойствами]]<tex>^\star</tex><br />
* [[Сеть Бетчера]]<br />
<br />
== Алгоритмы поиска ==<br />
* [[Целочисленный двоичный поиск]]<br />
* [[Вещественный двоичный поиск]]<br />
* [[Троичный поиск]]<br />
* [[Поиск с помощью золотого сечения]]<br />
* [[Интерполяционный поиск]]<br />
<br />
== Связь между структурами данных ==<br />
* [[Связь между структурами данных]]<br />
<br />
= Третий семестр =<br />
<br />
== Основные определения теории графов ==<br />
* [[Основные определения теории графов|Основные определения: граф, ребро, вершина, степень, петля, путь, цикл]]<br />
* [[Лемма о рукопожатиях]]<br />
* [[Теорема о существовании простого пути в случае существования пути]]<br />
* [[Теорема о существовании простого цикла в случае существования цикла]]<br />
* [[Матрица смежности графа]]<br />
* [[Связь степени матрицы смежности и количества путей]]<br />
* [[Матрица инцидентности графа]]<br />
* [[Циклическое пространство графа]]<tex>^\star</tex><br />
* [[Фундаментальные циклы графа]]<tex>^\star</tex><br />
* [[Дерево, эквивалентные определения]]<br />
* [[Алгоритмы на деревьях]]<tex>^\star</tex><br />
* [[Дополнительный, самодополнительный граф]]<br />
* [[Теоретико-множественные операции над графами]]<tex>^\star</tex><br />
<br />
== Связность в графах ==<br />
* [[Отношение связности, компоненты связности]]<br />
* [[Отношение реберной двусвязности]]<br />
* [[Отношение вершинной двусвязности]]<br />
* [[Граф компонент реберной двусвязности]]<br />
* [[Граф блоков-точек сочленения]]<br />
* [[Точка сочленения, эквивалентные определения]]<br />
* [[Мост, эквивалентные определения]]<br />
* [[k-связность]]<br />
* [[Теорема Менгера]]<br />
* [[Теорема Менгера, альтернативное доказательство]]<br />
* [[Вершинная, реберная связность, связь между ними и минимальной степенью вершины]]<br />
<br />
== Остовные деревья ==<br />
=== Построение остовных деревьев ===<br />
* [[Остовные деревья: определения, лемма о безопасном ребре]]<br />
* [[Алгоритм Прима]]<br />
* [[Алгоритм Краскала]]<br />
* [[Алгоритм Борувки]]<br />
* [[Критерий Тарьяна минимальности остовного дерева|Теорема Тарьяна (критерий минимальности остовного дерева)]]<br />
* [[Алгоритм двух китайцев]]<br />
<br />
=== Свойства остовных деревьев ===<br />
* [[Матрица Кирхгофа]]<br />
* [[Связь матрицы Кирхгофа и матрицы инцидентности]]<br />
* [[Подсчет числа остовных деревьев с помощью матрицы Кирхгофа]]<br />
* [[Количество помеченных деревьев]]<br />
* [[Коды Прюфера]]<br />
<br />
== Обходы графов ==<br />
=== Эйлеровы графы ===<br />
* [[Эйлеров цикл, Эйлеров путь, Эйлеровы графы, Эйлеровость орграфов]]<br />
* [[Покрытие ребер графа путями]]<br />
* [[Алгоритм построения Эйлерова цикла]]<br />
* [[Произвольно вычерчиваемые из заданной вершины графы]]<br />
=== Гамильтоновы графы ===<br />
* [[Гамильтоновы графы]]<br />
* [[Теорема Хватала]]<br />
* [[Теорема Поша]]<tex>^\star</tex><br />
* [[Теорема Дирака]]<br />
* [[Теорема Оре]]<br />
* [[Алгоритм нахождения Гамильтонова цикла в условиях теорем Дирака и Оре]]<br />
* [[Теорема Гринберга]]<tex>^\star</tex><br />
* [[Турниры]]<br />
* [[Теорема Редеи-Камиона]]<br />
<br />
== Укладки графов ==<br />
* [[Укладка графа на плоскости]]<br />
* [[Формула Эйлера]]<br />
* [[Непланарность K5 и K3,3|Непланарность <tex>K_5</tex> и <tex>K_{3,3}</tex>]]<br />
* [[Укладка дерева]]<br />
* [[Укладка графа с планарными компонентами реберной двусвязности]]<br />
* [[Укладка графа с планарными компонентами вершинной двусвязности]]<br />
* [[Теорема Понтрягина-Куратовского]]<br />
* [[Двойственный граф планарного графа]]<br />
* [[Теорема Фари]]<tex>^\star</tex><br />
<br />
== Раскраски графов ==<br />
* [[Раскраска графа]]<br />
* [[Двудольные графы и раскраска в 2 цвета]]<br />
* [[Хроматический многочлен]]<br />
* [[Формула Зыкова]]<br />
* [[Формула Уитни]]<br />
* [[Теорема Брукса]]<br />
* [[Верхние и нижние оценки хроматического числа]]<tex>^\star</tex><br />
* [[Хроматическое число планарного графа]]<br />
* [[Многочлен Татта]]<tex>^\star</tex><br />
* [[Теория Рамсея]]<tex>^\star</tex><br />
<br />
== Обход в глубину ==<br />
* [[Обход в глубину, цвета вершин]]<br />
* [[Лемма о белых путях]]<br />
* [[Использование обхода в глубину для проверки связности]]<br />
* [[Использование обхода в глубину для поиска цикла]]<br />
* [[Использование обхода в глубину для топологической сортировки]]<br />
* [[Использование обхода в глубину для поиска компонент сильной связности]]<br />
* [[Использование обхода в глубину для поиска точек сочленения]]<br />
* [[Построение компонент вершинной двусвязности]]<br />
* [[Использование обхода в глубину для поиска мостов]]<br />
* [[Построение компонент реберной двусвязности]]<br />
<br />
== Кратчайшие пути в графах ==<br />
* [[Обход в ширину]]<br />
* [[Алгоритм Форда-Беллмана]]<br />
* [[Алгоритм Дейкстры]]<br />
* [[Алгоритм Левита]]<tex>^\star</tex><br />
* [[Алгоритм Флойда]]<br />
* [[Алгоритм A*]] <tex>^\star</tex><br />
* [[Алгоритм Джонсона]]<br />
* [[Эвристики для поиска кратчайших путей]]<tex>^\star</tex><br />
* [[Алгоритм D*]] <tex>^\star</tex><br />
<br />
== Задача о паросочетании ==<br />
* [[Паросочетания: основные определения, теорема о максимальном паросочетании и дополняющих цепях]]<br />
* [[Алгоритм Форда-Фалкерсона для поиска максимального паросочетания]]<br />
* [[Алгоритм Куна для поиска максимального паросочетания]]<br />
* [[Теорема Холла]]<br />
* [[Связь максимального паросочетания и минимального вершинного покрытия в двудольных графах]]<br />
* [[Связь вершинного покрытия и независимого множества]]<br />
* [[Матрица Татта и связь с размером максимального паросочетания в двудольном графе]]<br />
* [[Теорема Татта о существовании полного паросочетания]]<br />
* [[Алгоритм вырезания соцветий|Паросочетания в недвудольных графах. Алгоритм вырезания соцветий]]<br />
* [[Декомпозиция Эдмондса-Галлаи]]<br />
* [[Задача об устойчивом паросочетании]]<tex>^\star</tex><br />
<br />
== Задача о максимальном потоке ==<br />
* [[Определение сети, потока]]<br />
* [[Разрез, лемма о потоке через разрез]]<br />
* [[Дополняющая сеть, дополняющий путь]]<br />
* [[Лемма о сложении потоков]]<br />
* [[Теорема Форда-Фалкерсона]]<br />
* [[Алгоритм Форда-Фалкерсона, реализация с помощью поиска в глубину]]<br />
* [[Алоритм Эдмондса-Карпа]]<br />
* [[Алгоритм масштабирования потока]]<br />
* [[Блокирующий поток]]<br />
* [[Схема алгоритма Диница]]<br />
* [[Теоремы Карзанова о числе итераций алгоритма Диница в сети с целочисленными пропускными способностями]]<br />
* [[Алгоритм поиска блокирующего потока в ациклической сети]]<br />
* [[Метод проталкивания предпотока]]<br />
* [[Алгоритм "поднять-в-начало"]]<br />
* [[Теорема о декомпозиции]]<br />
* [[Теорема о декомпозиционном барьере]]<br />
* [[Циркуляция потока]]<br />
* [[Алгоритм Каргера для нахождения минимального разреза]]<tex>^\star</tex><br />
<br />
== Задача о потоке минимальной стоимости ==<br />
* [[Поток минимальной стоимости]]<br />
* [[Теорема Форда-Фалкерсона о потоке минимальной стоимости]]<br />
* [[Лемма об эквивалентности свойства потока быть минимальной стоимости и отсутствии отрицательных циклов в остаточной сети]]<br />
* [[Поиск потока минимальной стоимости методом дополнения вдоль путей минимальной стоимости]]<br />
* [[Использование потенциалов Джонсона при поиске потока минимальной стоимости]]<br />
* [[Сведение задачи о назначениях к задаче о потоке минимальной стоимости]]<br />
* [[Венгерский алгоритм решения задачи о назначениях]]<br />
<br />
= Четвертый семестр =<br />
<br />
== Основные определения. Простые комбинаторные свойства слов ==<br />
* [[Основные определения, связанные со строками]]<br />
* [[Период и бордер, их связь]]<br />
* [[Слово Фибоначчи]]<br />
* [[Слово Туэ-Морса]]<br />
* [[Декомпозиция Линдона]]<tex>^\star</tex><br />
* [[Алгоритм Ландау-Шмидта]]<tex>^\star</tex><br />
* [[Алгоритм Крочемора]]<tex>^\star</tex><br />
* [[Алгоритм Мейна-Лоренца]]<tex>^\star</tex><br />
<br />
== [[Поиск подстроки в строке]] ==<br />
=== Точный поиск ===<br />
* [[Наивный алгоритм поиска подстроки в строке]]<br />
* [[Поиск подстроки в строке с использованием хеширования. Алгоритм Рабина-Карпа]]<br />
* [[Поиск наибольшей общей подстроки двух строк с использованием хеширования]]<br />
* [[Префикс-функция]]<br />
* [[Алгоритм Кнута-Морриса-Пратта]]<br />
* [[Алгоритм Бойера-Мура]]<br />
* [[Алгоритм Колусси]]<tex>^\star</tex><br />
* [[Алгоритм Shift-And]]<tex>^\star</tex><br />
* [[Z-функция]]<br />
* [[Автомат для поиска образца в тексте]]<br />
* [[Бор]]<br />
* [[Алгоритм Ахо-Корасик]]<br />
=== Нечёткий поиск ===<br />
* [[Алгоритм Ландау-Вишкина (k несовпадений)]]<tex>^\star</tex><br />
* [[Алгоритм Ландау-Вишкина (k различий)]]<tex>^\star</tex><br />
<br />
== Суффиксное дерево ==<br />
* [[Суффиксный бор]]<br />
* [[Сжатое суффиксное дерево]]<br />
* [[Алгоритм Укконена]]<br />
* [[Алгоритм МакКрейта]]<tex>^\star</tex><br />
* [[Алгоритм Фарача]]<tex>^\star</tex><br />
<br />
== Суффиксный массив ==<br />
* [[Суффиксный массив]]<br />
* [[Построение суффиксного массива с помощью стандартных методов сортировки]]<br />
* [[Алгоритм цифровой сортировки суффиксов циклической строки]]<br />
* [[Алгоритм Касаи и др.]]<br />
* [[Алгоритм Карккайнена-Сандерса]]<br />
* [[Алгоритм поиска подстроки в строке с помощью суффиксного массива]]<br />
<br />
== Задача о наименьшем общем предке ==<br />
* [[Сведение задачи LCA к задаче RMQ]]<br />
* [[Сведение задачи RMQ к задаче LCA]]<br />
* [[Метод двоичного подъема]]<br />
* [[Решение RMQ с помощью разреженной таблицы]]<br />
* [[Алгоритм Фарака-Колтона и Бендера]] (решение +/-1 RMQ с помощью метода четырех русских)<br />
* [[Алгоритм Шибера-Вишкина]]<tex>^\star</tex><br />
* [[Алгоритм Тарьяна поиска LCA за O(1) в оффлайн]]<tex>^\star</tex><br />
* [[Link-Cut Tree]]<tex>^\star</tex><br />
<br />
== Матроиды ==<br />
=== Основные факты теории матроидов ===<br />
* [[Определение матроида]]<br />
* [[Примеры матроидов]]<br />
* [[Прямая сумма матроидов]]<br />
* [[Теорема Радо-Эдмондса (жадный алгоритм)]]<br />
* [[Теорема о базах]]<br />
* [[Аксиоматизация матроида базами]]<br />
* [[Теорема о циклах]]<br />
* [[Аксиоматизация матроида циклами]]<br />
* [[Ранговая функция, полумодулярность]]<br />
* [[Аксиоматизация матроида рангами]]<br />
* [[Двойственный матроид]]<br />
* [[Оператор замыкания для матроидов]]<br />
* [[Покрытия, закрытые множества]]<br />
* [[Матроид Вамоса]]<tex>^\star</tex><br />
<br />
=== Пересечение матроидов ===<br />
* [[Пересечение матроидов, определение, примеры]]<br />
* [[Лемма о паросочетании в графе замен]]<br />
* [[Лемма о единственном паросочетании в графе замен]]<br />
* [[Граф замен для двух матроидов]]<br />
* [[Лемма о единственном паросочетании в подграфе замен, индуцированном кратчайшим путем]]<br />
* [[Алгоритм построения базы в пересечении матроидов]]<br />
* [[Теорема Эдмондса-Лоулера]]<br />
=== Объединение матроидов ===<br />
* [[Объединение матроидов, проверка множества на независимость]]<br />
* [[Объединение матроидов, доказательство того, что объединение является матроидом]]<br />
* [[Алгоритм построения базы в объединении матроидов]]<br />
<br />
== Теория расписаний ==<br />
* [[Классификация задач]]<br />
* [[Методы решения задач теории расписаний]]<br />
* [[Правило Лаулера]]<br />
* [[Flow shop]]<br />
* [[P1sumu|<tex>1 \mid \mid \sum U_{i}</tex>]]<br />
* [[1ripi1sumwc|<tex>1 \mid r_{i}, p_i=1\mid \sum w_{i}C_{i}</tex>]]<br />
* [[1ridipi1|<tex>1 \mid r_{i}, d_{i}, p_{i} = 1 \mid -</tex>]]<br />
* [[1outtreesumwc | <tex>1 \mid outtree \mid \sum w_i C_i</tex>]]<br />
* [[1pi1sumwu|<tex>1 \mid p_{i} = 1 \mid \sum w_{i}U_{i}</tex>]]<br />
* [[1precpmtnrifmax|<tex>1 \mid prec, pmtn, r_i \mid f_{\max}</tex>]]<br />
* [[1precripi1Lmax|<tex>1 \mid prec; r_i; p_i = 1 \mid L_{max}</tex>]]<br />
* [[P2precpi1Lmax|<tex>P2 \mid prec, p_i = 1 \mid L_{\max}</tex>]]<br />
* [[PpmtnriLmax|<tex>P \mid pmtn, r_i \mid L_{max}</tex>]]<br />
* [[QpmtnCmax|<tex>Q \mid pmtn \mid C_{max}</tex>]]<br />
* [[QpmtnriLmax|<tex>Q \mid pmtn, r_{i} \mid L_{max}</tex>]]<br />
* [[QSumCi|<tex>Q\mid\mid\sum{C_i}</tex>]]<br />
* [[R2Cmax|<tex>R2 \mid \mid C_{max}</tex>]]<br />
* [[F2Cmax|<tex>F2 \mid \mid C_{max}</tex>]]<br />
* [[Fpij1sumwu|<tex>F \mid p_{ij} = 1 \mid \sum w_i U_i</tex>]]<br />
* [[O2Cmax|<tex>O2 \mid \mid C_{max}</tex>]]<br />
* [[Opi1sumu|<tex>O \mid p_{ij} = 1 \mid \sum U_i</tex>]]<br />
* [[J2ni2Cmax|<tex>J2 \mid n_{i} \le 2 \mid C_{max}</tex>]]<br />
* [[J2pij1Lmax| <tex>J2\mid p_{ij} = 1\mid L_{max}</tex>]]</div>Kurkinhttp://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Kurkin&diff=47823Обсуждение участника:Kurkin2015-06-06T17:46:10Z<p>Kurkin: </p>
<hr />
<div>'''Quotient filter''' {{---}} вероятностная структура данных, позволяющая проверить принадлежность элемента множеству. При этом существует возможность получить ложноположительное срабатывание (элемента в множестве нет, но структура данных сообщает, что он есть), но не ложноотрицательное(элемент в множестве есть, но структура данных сообщает, что его нет).<br />
<br />
Существует связь между размером хранилища и шансом ложноположительного срабатывания. Поддерживаются операции добавления нового элемента в множество. С увеличением размера хранимого множества повышается вероятность ложного срабатывания. <br />
Структура разработана в 2011 году Бендером как замена [[:Фильтр_Блума|фильтра Блума]].<br />
<br />
==Описание структуры данных==<br />
<br />
Фильтр представляет собой хеш таблицу, в которой харанится часть ключа и 3 бита дополнительной информации. Они используются для разрешения ситуации, когда хеш различных ключей указывает на одну ячейку в хеш таблице. В <tex>Quotient filter</tex> хеш функция возвращает <tex>p</tex> битовый хеш, последние r бит которого называются остатком, а <tex>q = p - r</tex> старших бит называются частным (англ. ''quotient''), отсюда название структуры Quotient filter(придумано Кнутом в The Art of Computer Programming:Searching and Sorting, volume 3. Section 6.4, exercise 13). Размер хеш таблицы составляет <tex>2^q</tex>.<br />
<br />
Пусть у нас есть ключ <tex>D</tex>, его хеш обозначим <tex>Dh</tex>, остаток <tex>Dr</tex> и частное <tex>Dq</tex>. Попробуем поместить остаток в хеш таблицу в ячейку <tex>Dq</tex>, называемую канонической. Возможно, ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа.<br />
<br />
Последовательность ячеек, имеющих одинаковые частные называется пробегом (англ. ''run''). Возможно, что начало пробега не занимает канонический слот, если он уже занят каким-то другим пробегом. <br />
<br />
Пробег, у которого первый элемент занимает каноническую ячейку, является началом кластера. Кластер (англ. ''cluster'') {{---}} объединение последовательных пробегов, концом кластера является пустая ячейка или начало другого кластера.<br />
<br />
Три дополнительных бита имеют следующие функции:<br />
# бит занятости {{---}} равен единице, если ячейка является канонической для некого ключа в фильтре, сохраненого необязательно в этой ячейке. <br />
# бит продолжения {{---}} равен единице, если ячейка занята, но не первым элементов пробеге.<br />
# бит сдвига {{---}} равен единице, если пробег сдвинут относительно канонического слота.<br />
<br />
<br />
Возможные состояния:<br />
0 0 0 : Пустая ячейка. <br />
0 0 1 : Ячейка содержит начало пробега, сдвинутого относительно канонического слота. <br />
0 1 0 : не используется. <br />
0 1 1 : Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота. <br />
1 0 0 : Ячейка содержит первый элемет пробега в его каноническом слоте. <br />
1 0 1 : Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо. <br />
1 1 0 : не используется. <br />
1 1 1 : Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо. <br />
<br />
=== Поиск ===<br />
<br />
Пусть мы ищем ключ <tex>D</tex>. Смотрим в его каноническую ячейку <tex>Dq</tex>. Если бит занятости не единица, то элемент точно не содержится в множестве.<br />
Если бит занятости единица, то нам нужно найти пробег для <tex>Dq</tex>. Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки <tex>Dq</tex> и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от <tex>Dq</tex> будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на <tex>1</tex>. После того как мы нашли начало кластера, пойдем от него влево, каждая ячейка с битом продолжения равным нулю говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нужный нам пробег для <tex>Dq</tex>. Если в этом пробеге содержится <tex>Dr</tex>, то <tex>D</tex> ,вероятно, содержится в множестве, иначе <tex>D</tex> точно не содержится в множестве.<br />
<br />
=== Вставка ===<br />
<br />
Аналогично с поиском: найдем позицию для <tex>Dr</tex>, сдвигаем на одну позицию влево все эллементы кластера, начиная с выбранного, обновляем дополнительные биты. <br />
<br />
* Сдвиг не влияет на бит занятости. Выставляем бит занятости в ячейке <tex>Dq</tex> в единицу.<br />
* Если мы вставляем <tex>Dr</tex> в начало пробега, следовательно предыдущий элемент пробега стал вторым, у него нужно выставить бит продолжения.<br />
* Мы выставляем бит сдвига в единицу для каждой ячейки, что мы сдвинули.<br />
<br />
<br />
== Преимущества ==<br />
<br />
* Последовательное расположение данных. Можно загружать только 1 кластер, уменьшая количество кеш промахов.<br />
* Простое увеличение или уменьшение хеш таблицы, достаточно перенести один бит из остатка в частное или наоборот.<br />
* Простое слияние двух фильтров.<br />
<br />
==См. Также==<br />
<br />
*[[:Идеальное_хеширование|Идеальное хеширование]]<br />
*[[:Универсальное_хеширование|Универсальное хеширование]]<br />
<br />
<br />
== Источники ==<br />
<br />
* [http://en.wikipedia.org/wiki/Quotient_filter Quotient filter — Wikipedia]<br />
* [http://habrahabr.ru/post/242285/ Quotient filter — Habrahabr]<br />
[[Категория: Дискретная математика и алгоритмы ]]<br />
[[Категория: Хеширование]]</div>Kurkinhttp://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Kurkin&diff=47822Обсуждение участника:Kurkin2015-06-06T17:42:45Z<p>Kurkin: </p>
<hr />
<div>'''Quotient filter''' {{---}} вероятностная структура данных, позволяющая проверить принадлежность элемента множеству. При этом существует возможность получить ложноположительное срабатывание (элемента в множестве нет, но структура данных сообщает, что он есть), но не ложноотрицательное(элемент в множестве есть, но структура данных сообщает, что его нет).<br />
<br />
Существует связь между размером хранилища и шансом ложноположительного срабатывания. Поддерживаются операции добавления нового элемента в множество. С увеличением размера хранимого множества повышается вероятность ложного срабатывания. <br />
Структура разработана в 2011 году Бендером как замена [[:Фильтр_Блума|фильтра Блума]].<br />
<br />
==Описание структуры данных==<br />
<br />
Фильтр представляет собой хеш таблицу, в которой харанится часть ключа и 3 бита дополнительной информации. Они используются для разрешения ситуации, когда хеш различных ключей указывает на одну ячейку в хеш таблице. В <tex>Quotient filter</tex> хеш функция возвращает <tex>p</tex> битовый хеш, последние r бит которого называются остатком, а <tex>q = p - r</tex> старших бит называются частным (англ. ''quotient''), отсюда название структуры Quotient filter(придумано Кнутом в The Art of Computer Programming:Searching and Sorting, volume 3. Section 6.4, exercise 13). Размер хеш таблицы составляет <tex>2^q</tex>.<br />
<br />
Пусть у нас есть ключ <tex>D</tex>, его хеш обозначим <tex>Dh</tex>, остаток <tex>Dr</tex> и частное <tex>Dq</tex>. Попробуем поместить остаток в хеш таблицу в ячейку <tex>Dq</tex>, называемую канонической. Возможно, ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа.<br />
<br />
Последовательность ячеек, имеющих одинаковые частные называется пробегом (англ. ''run''). Возможно, что начало пробега не занимает канонический слот, если он уже занят каким-то другим пробегом. <br />
<br />
Пробег, у которого первый элемент занимает каноническую ячейку, является началом кластера. Кластер (англ. ''cluster'') {{---}} объединение последовательных пробегов, концом кластера является пустая ячейка или начало другого кластера.<br />
<br />
Три дополнительных бита имеют следующие функции:<br />
# бит занятости {{---}} равен единице, если ячейка является канонической для некого ключа в фильтре, сохраненого необязательно в этой ячейке. <br />
# бит продолжения {{---}} равен единице, если ячейка занята, но не первым элементов пробеге.<br />
# бит сдвига {{---}} равен единице, если пробег сдвинут относительно канонического слота.<br />
<br />
<br />
Возможные состояния:<br />
0 0 0 : Пустая ячейка. <br />
0 0 1 : Ячейка содержит начало пробега, сдвинутого относительно канонического слота. <br />
0 1 0 : не используется. <br />
0 1 1 : Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота. <br />
1 0 0 : Ячейка содержит первый элемет пробега в его каноническом слоте. <br />
1 0 1 : Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо. <br />
1 1 0 : не используется. <br />
1 1 1 : Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо. <br />
<br />
=== Поиск ===<br />
<br />
Пусть мы ищем ключ <tex>D</tex>. Смотрим в его каноническую ячейку <tex>Dq</tex>. Если бит занятости не единица, то элемент точно не содержится в множестве.<br />
Если бит занятости единица, то нам нужно найти пробег для <tex>Dq</tex>. Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки <tex>Dq</tex> и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от <tex>Dq</tex> будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на <tex>1</tex>. После того как мы нашли начало кластера, пойдем от него влево, каждая ячейка с битом продолжения равным нулю говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нужный нам пробег для <tex>Dq</tex>. Если в этом пробеге содержится <tex>Dr</tex>, то <tex>D</tex> ,вероятно, содержится в множестве, иначе <tex>D</tex> точно не содержится в множестве.<br />
<br />
=== Вставка ===<br />
<br />
Аналогично с поиском: найдем позицию для <tex>Dr</tex>, сдвигаем на одну позицию влево все эллементы кластера, начиная с выбранного, обновляем дополнительные биты. <br />
<br />
* Сдвиг не влияет на бит занятости. Выставляем бит занятости в ячейке <tex>Dq</tex> в единицу.<br />
* Если мы вставляем <tex>Dr</tex> в начало пробега, следовательно предыдущий элемент пробега стал вторым, у него нужно выставить бит продолжения.<br />
* Мы выставляем бит сдвига в единицу для каждой ячейки, что мы сдвинули.<br />
<br />
<br />
== Преимущества ==<br />
<br />
* Последовательное расположение данных. Можно загружать только 1 кластер, уменьшая количество кеш промахов.<br />
* Простое увеличение или уменьшение хеш таблицы, достаточно перенести один бит из остатка в частное или наоборот.<br />
* Простое слияние двух фильтров.<br />
<br />
== Источники ==<br />
<br />
* [http://en.wikipedia.org/wiki/Quotient_filter Quotient filter — Wikipedia]<br />
* [http://habrahabr.ru/post/242285/ Quotient filter — Habrahabr]<br />
[[Категория: Дискретная математика и алгоритмы ]]<br />
[[Категория: Хеширование]]</div>Kurkinhttp://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Kurkin&diff=47821Обсуждение участника:Kurkin2015-06-06T17:35:40Z<p>Kurkin: </p>
<hr />
<div>=Quotient filter=<br />
{{Определение<br />
|definition =<br />
'''Quotient filter''' {{---}} вероятностная структура данных, позволяющая проверить принадлежность элемента множеству. При этом существует возможность получить ложноположительное срабатывание (элемента в множестве нет, но структура данных сообщает, что он есть), но не ложноотрицательное.<br />
}}<br />
<br />
Существует связь между размером хранилища и шансом ложноположительного срабатывания. Поддерживаются операции добавления нового элемента в множество. С увеличением размера хранимого множества повышается вероятность ложного срабатывания. <br />
Структура разработана в 2011 году Бендером как замена [[:Фильтр_Блума|фильтра Блума]].<br />
<br />
==Описание структуры данных==<br />
<br />
Фильтр представляет собой хеш таблицу, в которой харанится часть ключа и 3 бита дополнительной информации. Они используются для разрешения ситуации, когда хеш различных ключей указывает на одну ячейку в хеш таблице. В <tex>Quotient filter</tex> хеш функция возвращает <tex>p</tex> битовый хеш, последние r бит которого называются остатком, а <tex>q = p - r</tex> старших бит называются частным (англ. ''quotient''), отсюда название структуры Quotient filter(придумано Кнутом в The Art of Computer Programming:Searching and Sorting, volume 3. Section 6.4, exercise 13). Размер хеш таблицы составляет <tex>2^q</tex>.<br />
<br />
Пусть у нас есть ключ <tex>D</tex>, его хеш обозначим <tex>Dh</tex>, остаток <tex>Dr</tex> и частное <tex>Dq</tex>. Попробуем поместить остаток в хеш таблицу в ячейку <tex>Dq</tex>, называемую канонической. Возможно, ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа.<br />
<br />
Последовательность ячеек, имеющих одинаковые частные называется пробегом (англ. ''run''). Возможно, что начало пробега не занимает канонический слот, если он уже занят каким-то другим пробегом. <br />
<br />
Пробег, у которого первый элемент занимает каноническую ячейку, является началом кластера. Кластер (англ. ''cluster'') {{---}} объединение последовательных пробегов, концом кластера является пустая ячейка или начало другого кластера.<br />
<br />
Три дополнительных бита имеют следующие функции:<br />
# бит занятости {{---}} равен единице, если ячейка является канонической для некого ключа в фильтре, сохраненого необязательно в этой ячейке. <br />
# бит продолжения {{---}} равен единице, если ячейка занята, но не первым элементов пробеге.<br />
# бит сдвига {{---}} равен единице, если пробег сдвинут относительно канонического слота.<br />
<br />
<br />
Возможные состояния:<br />
0 0 0 : Пустая ячейка. <br />
0 0 1 : Ячейка содержит начало пробега, сдвинутого относительно канонического слота. <br />
0 1 0 : не используется. <br />
0 1 1 : Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота. <br />
1 0 0 : Ячейка содержит первый элемет пробега в его каноническом слоте. <br />
1 0 1 : Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо. <br />
1 1 0 : не используется. <br />
1 1 1 : Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо. <br />
<br />
=== Поиск ===<br />
<br />
Пусть мы ищем ключ <tex>D</tex>. Смотрим в его каноническую ячейку <tex>Dq</tex>. Если бит занятости не единица, то элемент точно не содержится в множестве.<br />
Если бит занятости единица, то нам нужно найти пробег для <tex>Dq</tex>. Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки <tex>Dq</tex> и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от <tex>Dq</tex> будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на <tex>1</tex>. После того как мы нашли начало кластера, пойдем от него влево, каждая ячейка с битом продолжения равным нулю говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нужный нам пробег для <tex>Dq</tex>. Если в этом пробеге содержится <tex>Dr</tex>, то <tex>D</tex> ,вероятно, содержится в множестве, иначе <tex>D</tex> точно не содержится в множестве.<br />
<br />
=== Вставка ===<br />
<br />
Аналогично с поиском: найдем позицию для <tex>Dr</tex>, сдвигаем на одну позицию влево все эллементы кластера, начиная с выбранного, обновляем дополнительные биты. <br />
<br />
* Сдвиг не влияет на бит занятости. Выставляем бит занятости в ячейке <tex>Dq</tex> в единицу.<br />
* Если мы вставляем <tex>Dr</tex> в начало пробега, следовательно предыдущий элемент пробега стал вторым, у него нужно выставить бит продолжения.<br />
* Мы выставляем бит сдвига в единицу для каждой ячейки, что мы сдвинули.<br />
<br />
<br />
== Преимущества ==<br />
<br />
* Последовательное расположение данных. Можно загружать только 1 кластер, уменьшая количество кеш промахов.<br />
* Простое увеличение или уменьшение хеш таблицы, достаточно перенести один бит из остатка в частное или наоборот.<br />
* Простое слияние двух фильтров.<br />
<br />
== Источники ==<br />
<br />
* [http://en.wikipedia.org/wiki/Quotient_filter Quotient filter — Wikipedia]<br />
* [http://habrahabr.ru/post/242285/ Quotient filter — Habrahabr]<br />
[[Категория: Дискретная математика и алгоритмы ]]<br />
[[Категория: Хеширование]]</div>Kurkinhttp://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Kurkin&diff=47820Обсуждение участника:Kurkin2015-06-06T17:34:19Z<p>Kurkin: </p>
<hr />
<div>=Quotient filter=<br />
{{Определение<br />
|definition =<br />
'''Quotient filter''' {{---}} вероятностная структура данных, позволяющая проверить принадлежность элемента множеству. При этом существует возможность получить ложноположительное срабатывание (элемента в множестве нет, но структура данных сообщает, что он есть), но не ложноотрицательное.<br />
}}<br />
<br />
Существует связь между размером хранилища и шансом ложноположительного срабатывания. Поддерживаются операции добавления нового элемента в множество. С увеличением размера хранимого множества повышается вероятность ложного срабатывания. <br />
Структура разработана в 2011 году Бендером как замена [[:Фильтр_Блума|фильтра Блума]].<br />
<br />
==Описание структуры данных==<br />
<br />
Фильтр представляет собой хеш таблицу, в которой харанится часть ключа и 3 бита дополнительной информации. Они используются для разрешения ситуации, когда хеш различных ключей указывает на одну ячейку в хеш таблице. В <tex>Quotient filter</tex> хеш функция возвращает <tex>p</tex> битовый хеш, последние r бит которого называются остатком, а <tex>q = p - r</tex> старших бит называются частным (англ. ''quotient''), отсюда название структуры Quotient filter(придумано Кнутом в The Art of Computer Programming:Searching and Sorting, volume 3. Section 6.4, exercise 13). Размер хеш таблицы составляет <tex>2^q</tex>.<br />
<br />
Пусть у нас есть ключ <tex>D</tex>, его хеш обозначим <tex>Dh</tex>, остаток <tex>Dr</tex> и частное <tex>Dq</tex>. Попробуем поместить остаток в хеш таблицу в ячейку <tex>Dq</tex>, называемую канонической. Возможно, ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа.<br />
<br />
Последовательность ячеек, имеющих одинаковые частные называется пробегом (англ. ''run''). Возможно, что начало пробега не занимает канонический слот, если он уже занят каким-то другим пробегом. <br />
<br />
Пробег, у которого первый элемент занимает каноническую ячейку, является началом кластера. Кластер (англ. ''cluster'') {{---}} объединение последовательных пробегов, концом кластера является пустая ячейка или начало другого кластера.<br />
<br />
Три дополнительных бита имеют следующие функции:<br />
# бит занятости {{---}} равен единице, если ячейка является канонической для некого ключа в фильтре, сохраненого необязательно в этой ячейке. <br />
# бит продолжения {{---}} равен единице, если ячейка занята, но не первым элементов пробеге.<br />
# бит сдвига {{---}} равен единице, если пробег сдвинут относительно канонического слота.<br />
<br />
<br />
Возможные состояния:<br />
0 0 0 : Пустая ячейка. <br />
0 0 1 : Ячейка содержит начало пробега, сдвинутого относительно канонического слота. <br />
0 1 0 : не используется. <br />
0 1 1 : Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота. <br />
1 0 0 : Ячейка содержит первый элемет пробега в его каноническом слоте. <br />
1 0 1 : Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо. <br />
1 1 0 : не используется. <br />
1 1 1 : Ячейка содержит элем ент пробега(не первый), сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо. <br />
<br />
=== Поиск ===<br />
<br />
Пусть мы ищем ключ <tex>D</tex>. Смотрим в его каноническую ячейку <tex>Dq</tex>. Если бит занятости не единица, то элемент точно не содержится в множестве.<br />
Если бит занятости единица, то нам нужно найти пробег для <tex>Dq</tex>. Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки <tex>Dq</tex> и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от <tex>Dq</tex> будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на <tex>1</tex>. После того как мы нашли начало кластера, пойдем от него влево, каждая ячейка с битом продолжения равным нулю говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нужный нам пробег для <tex>Dq</tex>. Если в этом пробеге содержится <tex>Dr</tex>, то <tex>D</tex> ,вероятно, содержится в множестве, иначе <tex>D</tex> точно не содержится в множестве.<br />
<br />
=== Вставка ===<br />
<br />
Аналогично с поиском: найдем позицию для <tex>Dr</tex>, сдвигаем на одну позицию влево все эллементы кластера, начиная с выбранного, обновляем дополнительные биты. <br />
<br />
* Сдвиг не влияет на бит занятости. Выставляем бит занятости в ячейке <tex>Dq</tex> в единицу.<br />
* Если мы вставляем <tex>Dr</tex> в начало пробега, следовательно предыдущий элемент пробега стал вторым, у него нужно выставить бит продолжения.<br />
* Мы выставляем бит сдвига в единицу для каждой ячейки, что мы сдвинули.<br />
<br />
<br />
== Преимущества ==<br />
<br />
* Последовательное расположение данных. Можно загружать только 1 кластер, уменьшая количество кеш промахов.<br />
* Простое увеличение или уменьшение хеш таблицы, достаточно перенести один бит из остатка в частное или наоборот.<br />
* Простое слияние двух фильтров.<br />
<br />
== Источники ==<br />
<br />
* [http://en.wikipedia.org/wiki/Quotient_filter Quotient filter — Wikipedia]<br />
* [http://habrahabr.ru/post/242285/ Quotient filter — Habrahabr]<br />
[[Категория: Дискретная математика и алгоритмы ]]<br />
[[Категория: Хеширование]]</div>Kurkinhttp://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Kurkin&diff=47819Обсуждение участника:Kurkin2015-06-06T17:31:13Z<p>Kurkin: </p>
<hr />
<div>=Quotient filter=<br />
{{Определение<br />
|definition =<br />
'''Quotient filter''' {{---}} вероятностная структура данных, позволяющая проверить принадлежность элемента множеству. При этом существует возможность получить ложноположительное срабатывание (элемента в множестве нет, но структура данных сообщает, что он есть), но не ложноотрицательное.<br />
}}<br />
<br />
Существует связь между размером хранилища и шансом ложноположительного срабатывания. Поддерживаются операции добавления нового элемента в множество. С увеличением размера хранимого множества повышается вероятность ложного срабатывания. <br />
Структура разработана в 2011 году Бендером как замена [[:Фильтр_Блума|фильтра Блума]].<br />
<br />
==Описание структуры данных==<br />
<br />
Фильтр представляет собой хеш таблицу, в которой харанится часть ключа и 3 бита дополнительной информации. Они используются для разрешения ситуации, когда хеш различных ключей указывает на одну ячейку в хеш таблице. В <tex>Quotient filter</tex> хеш функция возвращает <tex>p</tex> битовый хеш, последние r бит которого называются остатком, а <tex>q = p - r</tex> старших бит называются частным (англ. ''quotient''), отсюда название структуры Quotient filter(придумано Кнутом в The Art of Computer Programming:Searching and Sorting, volume 3. Section 6.4, exercise 13). Размер хеш таблицы составляет <tex>2^q</tex>.<br />
<br />
Пусть у нас есть ключ <tex>D</tex>, его хеш обозначим <tex>Dh</tex>, остаток <tex>Dr</tex> и частное <tex>Dq</tex>. Попробуем поместить остаток в хеш таблицу в ячейку <tex>Dq</tex>, называемую канонической. Возможно, ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа.<br />
<br />
Последовательность ячеек, имеющих одинаковые частные называется пробегом (англ. ''run''). Возможно, что начало пробега не занимает канонический слот, если он уже занят каким-то другим пробегом. <br />
<br />
Пробег, у которого первый элемент занимает каноническую ячейку, является началом кластера. Кластер (англ. ''cluster'') {{---}} объединение последовательных пробегов, концом кластера является пустая ячейка или начало другого кластера.<br />
<br />
Три дополнительных бита имеют следующие функции:<br />
# бит занятости {{---}} равен единице, если ячейка является канонической для некого ключа в фильтре, сохраненого необязательно в этой ячейке. <br />
# бит продолжения {{---}} равен единице, если ячейка занята, но не первым элементов пробеге.<br />
# бит сдвига {{---}} равен единице, если пробег сдвинут относительно канонического слота.<br />
<br />
<br />
Возможные состояния:<br />
0 0 0 : Пустая ячейка. <br />
0 0 1 : Ячейка содержит начало пробега, сдвинутого относительно канонического слота. <br />
0 1 0 : не используется. <br />
0 1 1 : Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота. <br />
1 0 0 : Ячейка содержит первый элемет пробега в его каноническом слоте. <br />
1 0 1 : Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо. <br />
1 1 0 : не используется. <br />
1 1 1 : Ячейка содержит элем ент пробега(не первый), сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо. <br />
<br />
=== Поиск ===<br />
<br />
Пусть мы ищем ключ <tex>D</tex>. Смотрим в его каноническую ячейку <tex>Dq</tex>. Если бит занятости не единица, то элемент точно не содержится в множестве.<br />
Если бит занятости единица, то нам нужно найти пробег для <tex>Dq</tex>. Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки <tex>Dq</tex> и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от <tex>Dq</tex> будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на <tex>1</tex>. После того как мы нашли начало кластера, пойдем от него в лево, каждая ячейка с битом продолжения равным нулю говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нужный нам пробег для <tex>Dq</tex>. Если в этом пробеге содержится <tex>Dr</tex>, то <tex>D</tex> ,вероятно, содержится в множестве, иначе <tex>D</tex> точно не содержится в множестве.<br />
<br />
=== Вставка ===<br />
<br />
Аналогично с поиском: найдем позицию для <tex>Dr</tex>, сдвигаем на одну позицию влево все эллементы кластера, начиная с выбранного, обновляем дополнительные биты. <br />
<br />
* Сдвиг не влияет на бит занятости. Выставляем бит занятости в ячейке <tex>Dq</tex> в единицу.<br />
* Если мы вставляем <tex>Dr</tex> в начало пробега, следовательно предыдущий элемент пробега стал вторым, у него нужно выставить бит продолжения.<br />
* Мы выставляем бит сдвига в единицу для каждой ячейки, что мы сдвинули.<br />
<br />
<br />
== Преимущества ==<br />
<br />
* Последовательное расположение данных. Можно загружать только 1 кластер, уменьшая количество кеш промахов.<br />
* Простое увеличение или уменьшение хеш таблицы, достаточно перенести один бит из остатка в частное или наоборот.<br />
* Простое слияние двух фильтров.<br />
<br />
== Источники ==<br />
<br />
* [http://en.wikipedia.org/wiki/Quotient_filter Quotient filter — Wikipedia]<br />
* [http://habrahabr.ru/post/242285/ Quotient filter — Habrahabr]<br />
[[Категория: Дискретная математика и алгоритмы ]]<br />
[[Категория: Хеширование]]</div>Kurkinhttp://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Kurkin&diff=47818Обсуждение участника:Kurkin2015-06-06T17:29:06Z<p>Kurkin: </p>
<hr />
<div>=Quotient filter=<br />
{{Определение<br />
|definition =<br />
'''Quotient filter''' {{---}} вероятностная структура данных, позволяющая проверить принадлежность элемента множеству. При этом существует возможность получить ложноположительное срабатывание (элемента в множестве нет, но структура данных сообщает, что он есть), но не ложноотрицательное.<br />
}}<br />
<br />
Существует связь между размером хранилища и шансом ложноположительного срабатывания. Поддерживаются операции добавления нового элемента в множество. С увеличением размера хранимого множества повышается вероятность ложного срабатывания. <br />
Структура разработана в 2011 году Бендером как замена [[:Фильтр_Блума|фильтра Блума]].<br />
<br />
==Описание структуры данных==<br />
<br />
Фильтр представляет собой хеш таблицу, в которой харанится часть ключа и 3 бита дополнительной информации. Они используются для разрешения ситуации, когда хеш различных ключей указывает на одну ячейку в хеш таблице. В <tex>Quotient filter</tex> хеш функция возвращает <tex>p</tex> битовый хеш, последние r бит которого называются остатком, а <tex>q = p - r</tex> старших бит называются частным (англ. ''quotient''), отсюда название структуры Quotient filter(придумано Кнутом в The Art of Computer Programming:Searching and Sorting, volume 3. Section 6.4, exercise 13). Размер хеш таблицы составляет <tex>2^q</tex>.<br />
<br />
Пусть у нас есть ключ <tex>D</tex>, его хеш обозначим <tex>Dh</tex>, остаток <tex>Dr</tex> и частное <tex>Dq</tex>. Попробуем поместить остаток в хеш таблицу в ячейку <tex>Dq</tex>, называемую канонической. Возможно, ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа.<br />
<br />
Последовательность ячеек, имеющих одинаковые частные называется пробегом (англ. ''run''). Возможно, что начало пробега не занимает канонический слот, если он уже занят каким-то другим пробегом. <br />
<br />
Пробег, у которого первый элемент занимает каноническую ячейку, является началом кластера. Кластер (англ. ''cluster'') {{---}} объединение последовательных пробегов, концом кластера является пустая ячейка или начало другого кластера.<br />
<br />
Три дополнительных бита имеют следующие функции:<br />
# бит занятости {{---}} равно единице, если ячейка является канонической для некого ключа в фильтре, сохраненого необязательно в этой ячейке. <br />
# бит продолжения {{---}} равно единице, если ячейка занята, но не первым элементов пробеге.<br />
# бит сдвига {{---}} равно единице, если пробег сдвинут относительно канонического слота.<br />
<br />
<br />
Возможные состояния:<br />
0 0 0 : Пустая ячейка. <br />
0 0 1 : Ячейка содержит начало пробега, сдвинутого относительно канонического слота. <br />
0 1 0 : не используется. <br />
0 1 1 : Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота. <br />
1 0 0 : Ячейка содержит первый элемет пробега в его каноническом слоте. <br />
1 0 1 : Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо. <br />
1 1 0 : не используется. <br />
1 1 1 : Ячейка содержит элем ент пробега(не первый), сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо. <br />
<br />
=== Поиск ===<br />
<br />
Пусть мы ищем ключ <tex>D</tex>. Смотрим в его каноническую ячейку <tex>Dq</tex>. Если бит занятости не единица, то элемент точно не содержится в множестве.<br />
Если бит занятости единица, то нам нужно найти пробег для <tex>Dq</tex>. Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки <tex>Dq</tex> и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от <tex>Dq</tex> будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на <tex>1</tex>. После того как мы нашли начало кластера, пойдем от него в лево, каждая ячейка с битом продолжения равным нулю говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нужный нам пробег для <tex>Dq</tex>. Если в этом пробеге содержится <tex>Dr</tex>, то <tex>D</tex> ,вероятно, содержится в множестве, иначе <tex>D</tex> точно не содержится в множестве.<br />
<br />
=== Вставка ===<br />
<br />
Аналогично с поиском: найдем позицию для <tex>Dr</tex>, сдвигаем на одну позицию влево все эллементы кластера, начиная с выбранного, обновляем дополнительные биты. <br />
<br />
* Сдвиг не влияет на бит занятости. Выставляем бит занятости в ячейке <tex>Dq</tex> в единицу.<br />
* Если мы вставляем <tex>Dr</tex> в начало пробега, следовательно предыдущий элемент пробега стал вторым, у него нужно выставить бит продолжения.<br />
* Мы выставляем бит сдвига в единицу для каждой ячейки, что мы сдвинули.<br />
<br />
<br />
== Преимущества ==<br />
<br />
* Последовательное расположение данных. Можно загружать только 1 кластер, уменьшая количество кеш промахов.<br />
* Простое увеличение или уменьшение хеш таблицы, достаточно перенести один бит из остатка в частное или наоборот.<br />
* Простое слияние двух фильтров.<br />
<br />
== Источники ==<br />
<br />
* [http://en.wikipedia.org/wiki/Quotient_filter Quotient filter — Wikipedia]<br />
* [http://habrahabr.ru/post/242285/ Quotient filter — Habrahabr]<br />
[[Категория: Дискретная математика и алгоритмы ]]<br />
[[Категория: Хеширование]]</div>Kurkinhttp://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Kurkin&diff=47817Обсуждение участника:Kurkin2015-06-06T17:28:37Z<p>Kurkin: </p>
<hr />
<div>=Quotient filter=<br />
{{Определение<br />
|definition =<br />
'''Quotient filter''' {{---}} вероятностная структура данных, позволяющая проверить принадлежность элемента множеству. При этом существует возможность получить ложноположительное срабатывание (элемента в множестве нет, но структура данных сообщает, что он есть), но не ложноотрицательное.<br />
}}<br />
<br />
Существует связь между размером хранилища и шансом ложноположительного срабатывания. Поддерживаются операции добавления нового элемента в множество. С увеличением размера хранимого множества повышается вероятность ложного срабатывания. <br />
Структура разработана в 2011 году Бендером как замена [[:Фильтр_Блума|фильтра Блума]].<br />
<br />
==Описание структуры данных==<br />
<br />
Фильтр представляет собой хеш таблицу, в которой харанится часть ключа и 3 бита дополнительной информации. Они используются для разрешения ситуации, когда хеш различных ключей указывает на одну ячейку в хеш таблице. В <tex>Quotient filter</tex> хеш функция возвращает <tex>p</tex> битовый хеш, последние r бит которого называются остатком, а <tex>q = p - r</tex> старших бит называются частным (англ. ''quotient''), отсюда название структуры Quotient filter(придумано Кнутом в The Art of Computer Programming:Searching and Sorting, volume 3. Section 6.4, exercise 13). Размер хеш таблицы составляет <tex>2^q</tex>.<br />
<br />
Пусть у нас есть ключ <tex>D</tex>, его хеш обозначим <tex>Dh</tex>, остаток <tex>Dr</tex> и частное <tex>Dq</tex>. Попробуем поместить остаток в хеш таблицу в ячейку <tex>Dq</tex>, называемую канонической. Возможно, ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа.<br />
<br />
Последовательность ячеек, имеющих одинаковые частные называется пробегом (англ. ''run''). Возможно, что начало пробега не занимает канонический слот, если он уже занят каким-то другим пробегом. <br />
<br />
Пробег, у которого первый элемент занимает каноническую ячейку, является началом кластера. Кластер (англ. ''cluster'') {{---}} объединение последовательных пробегов, концом кластера является пустая ячейка или начало другого кластера.<br />
<br />
Три дополнительных бита имеют следующие функции:<br />
# бит занятости {{---}} равно единице, если ячейка является канонической для некого ключа в фильтре, сохраненого необязательно в этой ячейке. <br />
# бит продолжения {{---}} равно единице, если ячейка занята, но не первым элементов пробеге.<br />
# бит сдвига {{---}} равно единице, если пробег сдвинут относительно канонического слота.<br />
<br />
<br />
Возможные состояния:<br />
0 0 0 : Пустая ячейка. <br />
0 0 1 : Ячейка содержит начало пробега, сдвинутого относительно канонического слота. <br />
0 1 0 : не используется. <br />
0 1 1 : Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота. <br />
1 0 0 : Ячейка содержит первый элемет пробега в его каноническом слоте. <br />
1 0 1 : Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо. <br />
1 1 0 : не используется. <br />
1 1 1 : Ячейка содержит элем ент пробега(не первый), сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо. <br />
<br />
=== Поиск ===<br />
<br />
Пусть мы ищем ключ <tex>D</tex>. Смотрим в его каноническую ячейку <tex>Dq</tex>. Если бит занятости не единица, то элемент точно не содержится в множестве.<br />
Если бит занятости единица, то нам нужно найти пробег для <tex>Dq</tex>. Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки <tex>Dq</tex> и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от <tex>Dq</tex> будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на 1. После того как мы нашли начало кластера, пойдем от него в лево, каждая ячейка с битом продолжения равным нулю говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нужный нам пробег для <tex>Dq</tex>. Если в этом пробеге содержится <tex>Dr</tex>, то <tex>D</tex> ,вероятно, содержится в множестве, иначе <tex>D</tex> точно не содержится в множестве.<br />
<br />
=== Вставка ===<br />
<br />
Аналогично с поиском: найдем позицию для <tex>Dr</tex>, сдвигаем на одну позицию влево все эллементы кластера, начиная с выбранного, обновляем дополнительные биты. <br />
<br />
* Сдвиг не влияет на бит занятости. Выставляем бит занятости в ячейке <tex>Dq</tex> в единицу.<br />
* Если мы вставляем <tex>Dr</tex> в начало пробега, следовательно предыдущий элемент пробега стал вторым, у него нужно выставить бит продолжения.<br />
* Мы выставляем бит сдвига в единицу для каждой ячейки, что мы сдвинули.<br />
<br />
<br />
== Преимущества ==<br />
<br />
* Последовательное расположение данных. Можно загружать только 1 кластер, уменьшая количество кеш промахов.<br />
* Простое увеличение или уменьшение хеш таблицы, достаточно перенести один бит из остатка в частное или наоборот.<br />
* Простое слияние двух фильтров.<br />
<br />
== Источники ==<br />
<br />
* [http://en.wikipedia.org/wiki/Quotient_filter Quotient filter — Wikipedia]<br />
* [http://habrahabr.ru/post/242285/ Quotient filter — Habrahabr]<br />
[[Категория: Дискретная математика и алгоритмы ]]<br />
[[Категория: Хеширование]]</div>Kurkinhttp://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Kurkin&diff=47816Обсуждение участника:Kurkin2015-06-06T17:27:49Z<p>Kurkin: </p>
<hr />
<div>=Quotient filter=<br />
{{Определение<br />
|definition =<br />
'''Quotient filter''' {{---}} вероятностная структура данных, позволяющая проверить принадлежность элемента множеству. При этом существует возможность получить ложноположительное срабатывание (элемента в множестве нет, но структура данных сообщает, что он есть), но не ложноотрицательное.<br />
}}<br />
<br />
Существует связь между размером хранилища и шансом ложноположительного срабатывания. Поддерживаются операции добавления нового элемента в множество. С увеличением размера хранимого множества повышается вероятность ложного срабатывания. <br />
Структура разработана в 2011 году Бендером как замена [[:Фильтр_Блума|фильтра Блума]].<br />
<br />
==Описание структуры данных==<br />
<br />
Фильтр представляет собой хеш таблицу, в которой харанится часть ключа и 3 бита дополнительной информации. Они используются для разрешения ситуации, когда хеш различных ключей указывает на одну ячейку в хеш таблице. В <tex>Quotient filter</tex> хеш функция возвращает <tex>p</tex> битовый хеш, последние r бит которого называются остатком, а <tex>q = p - r</tex> старших бит называются частным (англ. ''quotient''), отсюда название структуры Quotient filter(придумано Кнутом в The Art of Computer Programming:Searching and Sorting, volume 3. Section 6.4, exercise 13). Размер хеш таблицы составляет <tex>2^q</tex>.<br />
<br />
Пусть у нас есть ключ <tex>D</tex>, его хеш обозначим <tex>Dh</tex>, остаток <tex>Dr</tex> и частное <tex>Dq</tex>. Попробуем поместить остаток в хеш таблицу в ячейку <tex>Dq</tex>, называемую канонической. Возможно, ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа.<br />
<br />
Последовательность ячеек, имеющих одинаковые частные называется пробегом (англ. ''run''). Возможно, что начало пробега не занимает канонический слот, если он уже занят каким-то другим пробегом. <br />
<br />
Пробег, у которого первый элемент занимает каноническую ячейку, является началом кластера. Кластер (англ. ''cluster'') {{---}} объединение последовательных пробегов, концом кластера является пустая ячейка или начало другого кластера.<br />
<br />
Три дополнительных бита имеют следующие функции:<br />
# бит занятости {{---}} равно единице, если ячейка является канонической для некого ключа в фильтре, сохраненого необязательно в этой ячейке. <br />
# бит продолжения {{---}} равно единице, если ячейка занята, но не первым элементов пробеге.<br />
# бит сдвига {{---}} равно единице, если пробег сдвинут относительно канонического слота.<br />
<br />
<br />
Возможные состояния:<br />
0 0 0 : Пустая ячейка. <br />
0 0 1 : Ячейка содержит начало пробега, сдвинутого относительно канонического слота. <br />
0 1 0 : не используется. <br />
0 1 1 : Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота. <br />
1 0 0 : Ячейка содержит первый элемет пробега в его каноническом слоте. <br />
1 0 1 : Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо. <br />
1 1 0 : не используется. <br />
1 1 1 : Ячейка содержит элем ент пробега(не первый), сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо. <br />
<br />
=== Поиск ===<br />
<br />
Пусть мы ищем ключ <tex>D</tex>. Смотрим в его каноническую ячейку <tex>Dq</tex>. Если бит занятости не единица, то элемент точно не содержится в множестве.<br />
Если бит занятости единица, то нам нужно найти пробег для <tex>Dq</tex>. Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки <tex>Dq</tex> и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от <tex>Dq</tex> будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на 1. После того как мы нашли начало кластера, пойдем от него в лево, каждая ячейка с битом продолжения равным нулю говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нужный нам пробег для <tex>Dq</tex>. Если в этом пробеге содержится <tex>Dr</tex>, то <tex>D</tex> ,вероятно, содержится в множестве, иначе <tex>D</</tex> точно не содержится в множестве.<br />
<br />
=== Вставка ===<br />
<br />
Аналогично с поиском: найдем позицию для <tex>Dr</tex>, сдвигаем на одну позицию влево все эллементы кластера, начиная с выбранного, обновляем дополнительные биты. <br />
<br />
* Сдвиг не влияет на бит занятости. Выставляем бит занятости в ячейке <tex>Dq</tex> в единицу.<br />
* Если мы вставляем <tex>Dr</tex> в начало пробега, следовательно предыдущий элемент пробега стал вторым, у него нужно выставить бит продолжения.<br />
* Мы выставляем бит сдвига в единицу для каждой ячейки, что мы сдвинули.<br />
<br />
<br />
== Преимущества ==<br />
<br />
* Последовательное расположение данных. Можно загружать только 1 кластер, уменьшая количество кеш промахов.<br />
* Простое увеличение или уменьшение хеш таблицы, достаточно перенести один бит из остатка в частное или наоборот.<br />
* Простое слияние двух фильтров.<br />
<br />
== Источники ==<br />
<br />
* [http://en.wikipedia.org/wiki/Quotient_filter Quotient filter — Wikipedia]<br />
* [http://habrahabr.ru/post/242285/ Quotient filter — Habrahabr]<br />
[[Категория: Дискретная математика и алгоритмы ]]<br />
[[Категория: Хеширование]]</div>Kurkinhttp://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Kurkin&diff=47815Обсуждение участника:Kurkin2015-06-06T17:21:33Z<p>Kurkin: </p>
<hr />
<div>=Quotient filter=<br />
{{Определение<br />
|definition =<br />
'''Quotient filter''' {{---}} вероятностная структура данных, позволяющая проверить принадлежность элемента множеству. При этом существует возможность получить ложноположительное срабатывание (элемента в множестве нет, но структура данных сообщает, что он есть), но не ложноотрицательное.<br />
}}<br />
<br />
Существует связь между размером хранилища и шансом ложноположительного срабатывания. Поддерживаются операции добавления нового элемента в множество. С увеличением размера хранимого множества повышается вероятность ложного срабатывания. <br />
Структура разработана в 2011 году Бендером как замена [[:Фильтр_Блума|фильтра Блума]].<br />
<br />
==Описание структуры данных==<br />
<br />
Фильтр представляет собой хеш таблицу в которой харанится часть ключа и 3 бита дополнительной информации. Они используются для разрешения ситуации, когда хеш различных ключей указывает на одну ячейку в хеш таблице. В <tex>Quotient filter</tex> хеш функция возвращает <tex>p</tex> битовый хеш, последние r бит которого называются остаток, а <tex>q = p - r</tex> старших бит называются частное (англ. ''quotient''), отсюда название структуры Quotient filter(придумано Кнутом в The Art of Computer Programming:Searching and Sorting, volume 3. Section 6.4, exercise 13). Размер хеш таблицы составляет <tex>2^q</tex>.<br />
<br />
Пусть у нас есть ключ <tex>D</tex>, его хеш обозначим <tex>Dh</tex>, остаток <tex>Dr</tex> и частное <tex>Dq</tex>. Попробуем поместить остаток в хеш таблицу в ячейку <tex>Dq</tex>, называемую канонической. Возможно ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа.<br />
<br />
Последовательность ячеек имеющих одинаковые частные называется пробегом (англ. ''run''). Возможно, что начало пробега не занимает канонический слот, если он уже занят каким-то другим пробегом. <br />
<br />
Пробег у которого первый элемент занимает каноническую ячейку является началом кластера. Кластер (англ. ''cluster'') {{---}} объединение последовательных пробегов, концом кластера является пустая ячейка или начало другого кластера.<br />
<br />
Три дополнительных бита имеют следующие функции:<br />
# бит занятости {{---}} равно единице, если ячейка является канонической для некого ключа в фильтре, сохраненого необязательно в этой ячейке. <br />
# бит продолжения {{---}} равно единице, если ячейка занята, но не первым элементов пробеге.<br />
# бит сдвига {{---}} равно единице, если пробег сдвинут относительно канонического слота.<br />
<br />
<br />
Возможные состояния:<br />
0 0 0 : Пустая ячейка. <br />
0 0 1 : Ячейка содержит начало пробега, сдвинутого относительно канонического слота. <br />
0 1 0 : не используется. <br />
0 1 1 : Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота. <br />
1 0 0 : Ячейка содержит первый элемет пробега в его каноническом слоте. <br />
1 0 1 : Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо. <br />
1 1 0 : не используется. <br />
1 1 1 : Ячейка содержит элем ент пробега(не первый), сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо. <br />
<br />
=== Поиск ===<br />
<br />
Пусть мы ищем ключ <tex>D</tex>. Смотрим в его каноническую ячейку <tex>Dq</tex>. Если бит занятости не единица, то элемент точно не содержится в множестве.<br />
Если бит занятости единица, то нам нужно найти пробег для <tex>Dq</tex>. Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки <tex>Dq</tex> и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от <tex>Dq</tex> будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на 1. После того как мы нашли начало кластера, пойдем от него в лево, каждая ячейка с битом продолжения равным нулю, говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нажный нам пробег для <tex>Dq</tex>. Если в этом пробеге содержится <tex>Dr</tex>, то <tex>D</tex> вероятно содержится в множестве, иначе <tex>D</</tex> точно не содержится в множестве.<br />
<br />
=== Вставка ===<br />
<br />
Анологично с поиском найдем найдем позицию для <tex>Dr</tex>, сдвигаем на одну позицию влево все эллементы кластера, начиная с выбранного, обновляем дополнительные биты. <br />
<br />
* Сдвиг не влияет на бит занятости. Выставляем бит занятости в ячейке <tex>Dq</tex> в единицу.<br />
* Усли мы вставляем <tex>Dr</tex> в начало пробега, следовательно предыдущий элемент пробега стал вторым, у него нужно выставить бит продолжения.<br />
* Мы выставляем бит сдвига в единицу для каждой ячейки, что мы сдвинули.<br />
<br />
<br />
== Преимущества ==<br />
<br />
* Последовательное расположение данных. Можно загружать только 1 кластер, умменьшая количество кеш промахов.<br />
* Простое увеличение или уменьшение хеш таблицы, достаточно перенести один бит из остатка в частное или наоборот.<br />
* Простое слияние двух фильтров.<br />
<br />
== Источники ==<br />
<br />
* [http://en.wikipedia.org/wiki/Quotient_filter Quotient filter — Wikipedia]<br />
* [http://habrahabr.ru/post/242285/ Quotient filter — Habrahabr]<br />
[[Категория: Дискретная математика и алгоритмы ]]<br />
[[Категория: Хеширование]]</div>Kurkinhttp://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Kurkin&diff=47814Обсуждение участника:Kurkin2015-06-06T17:09:43Z<p>Kurkin: </p>
<hr />
<div>=Quotient filter=<br />
{{Определение<br />
|definition =<br />
'''Quotient filter''' {{---}} вероятностная структура данных, позволяющая проверить принадлежность элемента множеству. При этом существует возможность получить ложноположительное срабатывание (элемента в множестве нет, но структура данных сообщает, что он есть), но не ложноотрицательное.<br />
}}<br />
<br />
Существует связь между размером хранилища и шансом ложноположительного срабатывания. Поддерживаются операции добавления нового элемента в множество. С увеличением размера хранимого множества повышается вероятность ложного срабатывания. <br />
Структура разработана в 2011 году Бендером как замена [[:Фильтр_Блума|фильтра Блума]].<br />
<br />
==Описание структуры данных==<br />
<br />
Фильтр представляет собой хеш таблицу в которой харанится часть ключа и 3 бита дополнительной информации. Они используются для разрешения ситуации, когда хеш различных ключей указывает на одну ячейку в хеш таблице. В <tex>Quotient filter</tex> хеш функция возвращает <tex>p</tex> битовый хеш, последние r бит которого называются остаток, а <tex>q = p - r</tex> старших бит называются частное (англ. ''quotient''), отсюда название структуры Quotient filter(придумано Кнутом в The Art of Computer Programming:Searching and Sorting, volume 3. Section 6.4, exercise 13). Размер хеш таблицы составляет 2^q.<br />
<br />
Пусть у нас есть ключ <tex>D</tex>, его хеш обозначим <tex>Dh</tex>, остаток <tex>Dr</tex> и частное <tex>Dq</tex>. Попробуем поместить остаток в хеш таблицу в ячейку <tex>Dq</tex>, называемую канонической. Возможно ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа.<br />
<br />
Последовательность ячеек имеющих одинаковые частные называется пробегом (англ. ''run''). Возможно, что начало пробега не занимает канонический слот, если он уже занят каким-то другим пробегом. <br />
<br />
Пробег у которого первый элемент занимает каноническую ячейку является началом кластера. Кластер (англ. ''cluster'') {{---}} объединение последовательных пробегов, концом кластера является пустая ячейка или начало другого кластера.<br />
<br />
Три дополнительных бита имеют следующие функции:<br />
# бит занятости {{---}} равно единице, если ячейка является канонической для некого ключа в фильтре, сохраненого необязательно в этой ячейке. <br />
# бит продолжения {{---}} равно единице, если ячейка занята, но не первым элементов пробеге.<br />
# бит сдвига {{---}} равно единице, если пробег сдвинут относительно канонического слота.<br />
<br />
бит занятости <br />
бит продолжения <br />
бит сдвига <br />
0 0 0 : Пустая ячейка. <br />
0 0 1 : Ячейка содержит начало пробега, сдвинутого относительно канонического слота. <br />
0 1 0 : не используется. <br />
0 1 1 : Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота. <br />
1 0 0 : Ячейка содержит первый элемет пробега в его каноническом слоте. <br />
1 0 1 : Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота. <br />
Ячейка является канонической, для существующего пробега сдвинутого вправо. <br />
1 1 0 : не используется. <br />
1 1 1 : Ячейка содержит элем ент пробега(не первый), сдвинутого относительно канонического слота. <br />
Ячейка является канонической, для существующего пробега сдвинутого вправо. <br />
<br />
=== Поиск ===<br />
<br />
Пусть мы ищем ключ D. Смотрим в его каноническую ячейку Dq. Если бит занятости не единица, то элемент точно не содержится в множестве.<br />
Если бит занятости единица, то нам нужно найти пробег для Dq. Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки Dq и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от Dq будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на 1. После того как мы нашли начало кластера, пойдем от него в лево, каждая ячейка с битом продолжения равным нулю, говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нажный нам пробег для Dq. Если в этом пробеге содержится Dr, то D вероятно содержится в множестве, иначе D точно не содержится в множестве.<br />
<br />
=== Вставка ===<br />
<br />
Анологично с поиском найдем найдем позицию для Dr, сдвигаем на одну позицию влево все эллементы кластера, начиная с выбранного, обновляем дополнительные биты. <br />
<br />
* Сдвиг не влияет на бит занятости. Выставляем бит занятости в ячейке Dq в единицу.<br />
* Усли мы вставляем Dr в начало пробега, следовательно предыдущий элемент пробега стал вторым, у него нужно выставить бит продолжения.<br />
* Мы выставляем бит сдвига в единицу для каждой ячейки, что мы сдвинули.<br />
<br />
<br />
== Преимущества ==<br />
<br />
* Последовательное расположение данных. Можно загружать только 1 кластер, умменьшая количество кеш промахов.<br />
* Простое увеличение или уменьшение хеш таблицы, достаточно перенести один бит из остатка в частное или наоборот.<br />
* Простое слияние двух фильтров.<br />
<br />
== Источники ==<br />
<br />
* [http://en.wikipedia.org/wiki/Quotient_filter Quotient filter — Wikipedia]<br />
* [http://habrahabr.ru/post/242285/ Quotient filter — Habrahabr]<br />
[[Категория: Дискретная математика и алгоритмы ]]<br />
[[Категория: Хеширование]]</div>Kurkinhttp://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Kurkin&diff=47813Обсуждение участника:Kurkin2015-06-06T17:04:05Z<p>Kurkin: </p>
<hr />
<div>=Quotient filter=<br />
{{Определение<br />
|definition =<br />
'''Quotient filter''' {{---}} вероятностная структура данных, позволяющая проверить принадлежность элемента множеству. При этом существует возможность получить ложноположительное срабатывание (элемента в множестве нет, но структура данных сообщает, что он есть), но не ложноотрицательное.<br />
}}<br />
<br />
Существует связь между размером хранилища и шансом ложноположительного срабатывания. Поддерживаются операции добавления нового элемента в множество. С увеличением размера хранимого множества повышается вероятность ложного срабатывания. <br />
Структура разработана в 2011 году Бендером как замена [[:Фильтр_Блума|фильтра Блума]].<br />
<br />
==Описание структуры данных==<br />
<br />
Фильтр представляет собой хеш таблицу в которой харанится часть ключа и 3 бита дополнительной информации. Они используются для разрешения ситуации, когда хеш различных ключей указывает на одну ячейку в хеш таблице. В <tex>Quotient filter</tex> хеш функция возвращает <tex>p</tex> битовый хеш, последние r бит которого называются остаток, а <tex>q = p - r</tex> старших бит называются частное (англ. ''quotient''), отсюда название структуры Quotient filter(придумано Кнутом в The Art of Computer Programming:Searching and Sorting, volume 3. Section 6.4, exercise 13). Размер хеш таблицы составляет 2^q.<br />
<br />
Пусть у нас есть ключ <tex>D</tex>, его хеш обозначим <tex>Dh</tex>, остаток <tex>Dr</tex> и частное <tex>Dq</tex>. Попробуем поместить остаток в хеш таблицу в ячейку <tex>Dq</tex>, называемую канонической. Возможно ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа.<br />
<br />
Последовательность ячеек имеющих одинаковые частные называется пробегом (англ. ''run''). Возможно, что начало пробега не занимает канонический слот, если он уже занят каким-то другим пробегом. <br />
<br />
Пробег у которого первый элемент занимает каноническую ячейку является началом кластера. Кластер (англ. ''cluster'') {{---}} объединение последовательных пробегов, концом кластера является пустая ячейка или начало другого кластера.<br />
<br />
Три дополнительных бита имеют следующие функции:<br />
# бит занятости {{---}} равно единице, если ячейка является канонической для некого ключа в фильтре, сохраненого необязательно в этой ячейке. <br />
# бит продолжения {{---}} равно единице, если ячейка занята, но не первым элементов пробеге.<br />
# бит сдвига {{---}} равно единице, если пробег сдвинут относительно канонического слота.<br />
<br />
бит занятости<br />
бит продолжения<br />
бит сдвига<br />
0 0 0 : Пустая ячейка.<br />
0 0 1 : Ячейка содержит начало пробега, сдвинутого относительно канонического слота.<br />
0 1 0 : не используется.<br />
0 1 1 : Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота.<br />
1 0 0 : Ячейка содержит первый элемет пробега в его каноническом слоте.<br />
1 0 1 : Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота.<br />
Ячейка является канонической, для существующего пробега сдвинутого вправо.<br />
1 1 0 : не используется.<br />
1 1 1 : Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота.<br />
Ячейка является канонической, для существующего пробега сдвинутого вправо.<br />
<br />
=== Поиск ===<br />
<br />
Пусть мы ищем ключ D. Смотрим в его каноническую ячейку Dq. Если бит занятости не единица, то элемент точно не содержится в множестве.<br />
Если бит занятости единица, то нам нужно найти пробег для Dq. Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки Dq и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от Dq будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на 1. После того как мы нашли начало кластера, пойдем от него в лево, каждая ячейка с битом продолжения равным нулю, говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нажный нам пробег для Dq. Если в этом пробеге содержится Dr, то D вероятно содержится в множестве, иначе D точно не содержится в множестве.<br />
<br />
=== Вставка ===<br />
<br />
Анологично с поиском найдем найдем позицию для Dr, сдвигаем на одну позицию влево все эллементы кластера, начиная с выбранного, обновляем дополнительные биты. <br />
<br />
* Сдвиг не влияет на бит занятости. Выставляем бит занятости в ячейке Dq в единицу.<br />
* Усли мы вставляем Dr в начало пробега, следовательно предыдущий элемент пробега стал вторым, у него нужно выставить бит продолжения.<br />
* Мы выставляем бит сдвига в единицу для каждой ячейки, что мы сдвинули.<br />
<br />
<br />
== Преимущества ==<br />
<br />
* Последовательное расположение данных. Можно загружать только 1 кластер, умменьшая количество кеш промахов.<br />
* Простое увеличение или уменьшение хеш таблицы, достаточно перенести один бит из остатка в частное или наоборот.<br />
* Простое слияние двух фильтров.<br />
<br />
== Источники ==<br />
<br />
* [http://en.wikipedia.org/wiki/Quotient_filter Quotient filter — Wikipedia]<br />
* [http://habrahabr.ru/post/242285/ Quotient filter — Habrahabr]<br />
[[Категория: Дискретная математика и алгоритмы ]]<br />
[[Категория: Хеширование]]</div>Kurkinhttp://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Kurkin&diff=47812Обсуждение участника:Kurkin2015-06-06T17:00:31Z<p>Kurkin: </p>
<hr />
<div>=Quotient filter=<br />
{{Определение<br />
|definition =<br />
'''Quotient filter''' {{---}} вероятностная структура данных, позволяющая проверить принадлежность элемента множеству. При этом существует возможность получить ложноположительное срабатывание (элемента в множестве нет, но структура данных сообщает, что он есть), но не ложноотрицательное.<br />
}}<br />
<br />
Существует связь между размером хранилища и шансом ложноположительного срабатывания. Поддерживаются операции добавления нового элемента в множество. С увеличением размера хранимого множества повышается вероятность ложного срабатывания. <br />
Структура разработана в 2011 году Бендером как замена [[:Фильтр_Блума|фильтра Блума]].<br />
<br />
==Описание структуры данных==<br />
<br />
Фильтр представляет собой хеш таблицу в которой харанится часть ключа и 3 бита дополнительной информации. Они используются для разрешения ситуации, когда хеш различных ключей указывает на одну ячейку в хеш таблице. В <tex>Quotient filter</tex> хеш функция возвращает <tex>p</tex> битовый хеш, последние r бит которого называются остаток, а <tex>q = p - r</tex> старших бит называются частное (англ. ''quotient''), отсюда название структуры Quotient filter(придумано Кнутом в The Art of Computer Programming:Searching and Sorting, volume 3. Section 6.4, exercise 13). Размер хеш таблицы составляет 2^q.<br />
<br />
Пусть у нас есть ключ <tex>D</tex>, его хеш обозначим <tex>Dh</tex>, остаток <tex>Dr</tex> и частное <tex>Dq</tex>. Попробуем поместить остаток в хеш таблицу в ячейку <tex>Dq</tex>, называемую канонической. Возможно ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа.<br />
<br />
Последовательность ячеек имеющих одинаковые частные называется пробегом (англ. ''run''). Возможно, что начало пробега не занимает канонический слот, если он уже занят каким-то другим пробегом. <br />
<br />
Пробег у которого первый элемент занимает каноническую ячейку является началом кластера. Кластер (англ. ''cluster'') {{---}} объединение последовательных пробегов, концом кластера является пустая ячейка или начало другого кластера.<br />
<br />
Три дополнительных бита имеют следующие функции:<br />
# бит занятости {{---}} равно единице, если ячейка является канонической для некого ключа в фильтре, сохраненого необязательно в этой ячейке. <br />
# бит продолжения {{---}} равно единице, если ячейка занята, но не первым элементов пробеге.<br />
# бит сдвига {{---}} равно единице, если пробег сдвинут относительно канонического слота.<br />
<br />
бит занятости<br />
бит продолжения<br />
бит сдвига<br />
0 0 0 : Пустая ячейка.<br />
0 0 1 : Ячейка содержит начало пробега, сдвинутого относительно канонического слота.<br />
0 1 0 : не используется.<br />
0 1 1 : Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота.<br />
1 0 0 : Ячейка содержит первый элемет пробега в его каноническом слоте.<br />
1 0 1 : Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота.<br />
Ячейка является канонической, для существующего пробега сдвинутого вправо.<br />
1 1 0 : не используется.<br />
1 1 1 : Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота.<br />
Ячейка является канонической, для существующего пробега сдвинутого вправо.<br />
<br />
=== Поиск ===<br />
<br />
Пусть мы ищем ключ D. Смотрим в его каноническую ячейку Dq. Если бит занятости не единица, то элемент точно не содержится в множестве.<br />
Если бит занятости единица, то нам нужно найти пробег для Dq. Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки Dq и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от Dq будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на 1. После того как мы нашли начало кластера, пойдем от него в лево, каждая ячейка с битом продолжения равным нулю, говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нажный нам пробег для Dq. Если в этом пробеге содержится Dr, то D вероятно содержится в множестве, иначе D точно не содержится в множестве.<br />
<br />
=== Вставка ===<br />
<br />
Анологично с поиском найдем найдем позицию для Dr, сдвигаем на одну позицию влево все эллементы кластера, начиная с выбранного, обновляем дополнительные биты. <br />
<br />
* Сдвиг не влияет на бит занятости. Выставляем бит занятости в ячейке Dq в единицу.<br />
* Усли мы вставляем Dr в начало пробега, следовательно предыдущий элемент пробега стал вторым, у него нужно выставить бит продолжения.<br />
* Мы выставляем бит сдвига в единицу для каждой ячейки, что мы сдвинули.<br />
<br />
<br />
== Преимущества ==<br />
<br />
*<br />
*<br />
*<br />
<br />
== Источники ==<br />
<br />
* [http://en.wikipedia.org/wiki/Quotient_filter Quotient filter — Wikipedia]<br />
* [http://habrahabr.ru/post/242285/ Quotient filter — Habrahabr]<br />
[[Категория: Дискретная математика и алгоритмы ]]<br />
[[Категория: Хеширование]]</div>Kurkinhttp://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Kurkin&diff=47788Обсуждение участника:Kurkin2015-06-06T15:16:04Z<p>Kurkin: </p>
<hr />
<div>=Quotient filter=<br />
{{Определение<br />
|definition =<br />
'''Quotient filter''' {{---}} вероятностная структура данных, позволяющая проверить принадлежность элемента множеству. При этом существует возможность получить ложноположительное срабатывание (элемента в множестве нет, но структура данных сообщает, что он есть), но не ложноотрицательное.<br />
}}<br />
<br />
Существует связь между размером хранилища и шансом ложноположительного срабатывания. Поддерживаются операции добавления и удаления элементов в множество. С увеличением размера хранимого множества повышается вероятность ложного срабатывания. <br />
Структура разработана в 2011 году Бендером как замена [[:Фильтр_Блума|фильтра Блума]].<br />
<br />
==Описание структуры данных==<br />
<br />
Фильтр представляет собой хеш таблицу в которой харанится часть ключа и 3 бита дополнительной информации. Они используются для разрешения ситуации, когда хеш различных ключей указывает на одну ячейку в хеш таблице. В <tex>Quotient filter</tex> хеш функция возвращает <tex>p</tex> битовый хеш, последние r бит которого называются остаток, а <tex>q = p - r</tex> старших бит называются частное (англ. ''quotient''), отсюда название структуры Quotient filter(придумано Кнутом в The Art of Computer Programming:Searching and Sorting, volume 3. Section 6.4, exercise 13). Размер хеш таблицы составляет 2^q.<br />
<br />
Пусть у нас есть ключ <tex>D</tex>, его хеш обозначим <tex>Dh</tex>, остаток <tex>Dr</tex> и частное <tex>Dq</tex>. Попробуем поместить остаток в хеш таблицу в ячейку <tex>Dq</tex>, называемую канонической. Возможно ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа.<br />
<br />
Последовательность ячеек имеющих одинаковые частные называется пробегом (англ. ''run''). Возможно, что начало пробега не занимает канонический слот, если он уже занят каким-то другим пробегом. <br />
<br />
Пробег у которого первый элемент занимает каноническую ячейку является началом кластера. Кластер (англ. ''cluster'') {{---}} объединение последовательных пробегов, концом кластера является пустая ячейка или начало другого кластера.<br />
<br />
Три дополнительных бита имеют следующие функции:<br />
# <tex>is</tex> <tex>occupied</tex> {{---}} равно единице, если ячейка является канонической для некого ключа в фильтре, сохраненого необязательно в этой ячейке. <br />
# <tex>is</tex> <tex>continuation</tex> {{---}} равно единице, если ячейка занята, но не первым элементов пробеге.<br />
# <tex>is</tex> <tex>shifted</tex> {{---}} равно единице, если пробег сдвинут относительно канонического слота.<br />
== Источники ==<br />
<br />
* [http://en.wikipedia.org/wiki/Quotient_filter Quotient filter — Wikipedia]<br />
* [http://habrahabr.ru/post/242285/ Quotient filter — Habrahabr]<br />
[[Категория: Дискретная математика и алгоритмы ]]<br />
[[Категория: Хеширование]]</div>Kurkinhttp://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Kurkin&diff=47765Обсуждение участника:Kurkin2015-06-06T13:36:37Z<p>Kurkin: Новая страница: «=Quotient filter= kghfkyufk»</p>
<hr />
<div>=Quotient filter=<br />
kghfkyufk</div>Kurkin