Обсуждение участника:Kurkin — различия между версиями

Материал из Викиконспекты
Перейти к: навигация, поиск
 
(не показаны 4 промежуточные версии этого же участника)
Строка 1: Строка 1:
=Quotient filter=
+
'''Quotient filter''' {{---}} вероятностная структура данных, позволяющая проверить принадлежность элемента множеству. При этом существует возможность получить ложноположительное срабатывание (элемента в множестве нет, но структура данных сообщает, что он есть), но не ложноотрицательное(элемент в множестве есть, но структура данных сообщает, что его нет).
{{Определение
 
|definition =
 
'''Quotient filter''' {{---}} вероятностная структура данных, позволяющая проверить принадлежность элемента множеству. При этом существует возможность получить ложноположительное срабатывание (элемента в множестве нет, но структура данных сообщает, что он есть), но не ложноотрицательное.
 
}}
 
  
 
Существует связь между размером хранилища и шансом ложноположительного срабатывания. Поддерживаются операции добавления нового элемента в множество. С увеличением размера хранимого множества повышается вероятность ложного срабатывания.  
 
Существует связь между размером хранилища и шансом ложноположительного срабатывания. Поддерживаются операции добавления нового элемента в множество. С увеличением размера хранимого множества повышается вероятность ложного срабатывания.  
Строка 19: Строка 15:
  
 
Три дополнительных бита имеют следующие функции:
 
Три дополнительных бита имеют следующие функции:
# бит занятости {{---}} равно единице, если ячейка является канонической для некого ключа в фильтре, сохраненого необязательно в этой ячейке.  
+
# бит занятости {{---}} равен единице, если ячейка является канонической для некого ключа в фильтре, сохраненого необязательно в этой ячейке.  
# бит продолжения {{---}} равно единице, если ячейка занята, но не первым элементов пробеге.
+
# бит продолжения {{---}} равен единице, если ячейка занята, но не первым элементов пробеге.
# бит сдвига {{---}} равно единице, если пробег сдвинут относительно канонического слота.
+
# бит сдвига {{---}} равен единице, если пробег сдвинут относительно канонического слота.
  
  
Строка 32: Строка 28:
 
  1 0 1 : Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.  
 
  1 0 1 : Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.  
 
  1 1 0 : не используется.  
 
  1 1 0 : не используется.  
  1 1 1 : Ячейка содержит элем ент пробега(не первый), сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.  
+
  1 1 1 : Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.  
  
 
=== Поиск ===
 
=== Поиск ===
  
 
Пусть мы ищем ключ <tex>D</tex>. Смотрим в его каноническую ячейку <tex>Dq</tex>. Если бит занятости не единица, то элемент точно не содержится в множестве.
 
Пусть мы ищем ключ <tex>D</tex>. Смотрим в его каноническую ячейку <tex>Dq</tex>. Если бит занятости не единица, то элемент точно не содержится в множестве.
Если бит занятости единица, то нам нужно найти пробег для <tex>Dq</tex>. Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки <tex>Dq</tex> и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от <tex>Dq</tex> будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на <tex>1</tex>. После того как мы нашли начало кластера, пойдем от него в лево, каждая ячейка с битом продолжения равным нулю говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нужный нам пробег для <tex>Dq</tex>. Если в этом пробеге содержится <tex>Dr</tex>, то <tex>D</tex> ,вероятно, содержится в множестве, иначе <tex>D</tex> точно не содержится в множестве.
+
Если бит занятости единица, то нам нужно найти пробег для <tex>Dq</tex>. Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки <tex>Dq</tex> и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от <tex>Dq</tex> будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на <tex>1</tex>. После того как мы нашли начало кластера, пойдем от него влево, каждая ячейка с битом продолжения равным нулю говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нужный нам пробег для <tex>Dq</tex>. Если в этом пробеге содержится <tex>Dr</tex>, то <tex>D</tex> ,вероятно, содержится в множестве, иначе <tex>D</tex> точно не содержится в множестве.
  
 
=== Вставка ===
 
=== Вставка ===
Строка 53: Строка 49:
 
* Простое увеличение или уменьшение хеш таблицы, достаточно перенести один бит из остатка в частное или наоборот.
 
* Простое увеличение или уменьшение хеш таблицы, достаточно перенести один бит из остатка в частное или наоборот.
 
* Простое слияние двух фильтров.
 
* Простое слияние двух фильтров.
 +
 +
==См. Также==
 +
 +
*[[:Идеальное_хеширование|Идеальное хеширование]]
 +
*[[:Универсальное_хеширование|Универсальное хеширование]]
 +
  
 
== Источники ==
 
== Источники ==

Текущая версия на 20:46, 6 июня 2015

Quotient filter — вероятностная структура данных, позволяющая проверить принадлежность элемента множеству. При этом существует возможность получить ложноположительное срабатывание (элемента в множестве нет, но структура данных сообщает, что он есть), но не ложноотрицательное(элемент в множестве есть, но структура данных сообщает, что его нет).

Существует связь между размером хранилища и шансом ложноположительного срабатывания. Поддерживаются операции добавления нового элемента в множество. С увеличением размера хранимого множества повышается вероятность ложного срабатывания. Структура разработана в 2011 году Бендером как замена фильтра Блума.

Описание структуры данных

Фильтр представляет собой хеш таблицу, в которой харанится часть ключа и 3 бита дополнительной информации. Они используются для разрешения ситуации, когда хеш различных ключей указывает на одну ячейку в хеш таблице. В [math]Quotient filter[/math] хеш функция возвращает [math]p[/math] битовый хеш, последние r бит которого называются остатком, а [math]q = p - r[/math] старших бит называются частным (англ. quotient), отсюда название структуры Quotient filter(придумано Кнутом в The Art of Computer Programming:Searching and Sorting, volume 3. Section 6.4, exercise 13). Размер хеш таблицы составляет [math]2^q[/math].

Пусть у нас есть ключ [math]D[/math], его хеш обозначим [math]Dh[/math], остаток [math]Dr[/math] и частное [math]Dq[/math]. Попробуем поместить остаток в хеш таблицу в ячейку [math]Dq[/math], называемую канонической. Возможно, ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа.

Последовательность ячеек, имеющих одинаковые частные называется пробегом (англ. run). Возможно, что начало пробега не занимает канонический слот, если он уже занят каким-то другим пробегом.

Пробег, у которого первый элемент занимает каноническую ячейку, является началом кластера. Кластер (англ. cluster) — объединение последовательных пробегов, концом кластера является пустая ячейка или начало другого кластера.

Три дополнительных бита имеют следующие функции:

  1. бит занятости — равен единице, если ячейка является канонической для некого ключа в фильтре, сохраненого необязательно в этой ячейке.
  2. бит продолжения — равен единице, если ячейка занята, но не первым элементов пробеге.
  3. бит сдвига — равен единице, если пробег сдвинут относительно канонического слота.


Возможные состояния:
0 0 0 : Пустая ячейка. 
0 0 1 : Ячейка содержит начало пробега, сдвинутого относительно канонического слота. 
0 1 0 : не используется. 
0 1 1 : Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота. 
1 0 0 : Ячейка содержит первый элемет пробега в его каноническом слоте. 
1 0 1 : Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо. 
1 1 0 : не используется. 
1 1 1 : Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо. 

Поиск

Пусть мы ищем ключ [math]D[/math]. Смотрим в его каноническую ячейку [math]Dq[/math]. Если бит занятости не единица, то элемент точно не содержится в множестве. Если бит занятости единица, то нам нужно найти пробег для [math]Dq[/math]. Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки [math]Dq[/math] и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от [math]Dq[/math] будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на [math]1[/math]. После того как мы нашли начало кластера, пойдем от него влево, каждая ячейка с битом продолжения равным нулю говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нужный нам пробег для [math]Dq[/math]. Если в этом пробеге содержится [math]Dr[/math], то [math]D[/math] ,вероятно, содержится в множестве, иначе [math]D[/math] точно не содержится в множестве.

Вставка

Аналогично с поиском: найдем позицию для [math]Dr[/math], сдвигаем на одну позицию влево все эллементы кластера, начиная с выбранного, обновляем дополнительные биты.

  • Сдвиг не влияет на бит занятости. Выставляем бит занятости в ячейке [math]Dq[/math] в единицу.
  • Если мы вставляем [math]Dr[/math] в начало пробега, следовательно предыдущий элемент пробега стал вторым, у него нужно выставить бит продолжения.
  • Мы выставляем бит сдвига в единицу для каждой ячейки, что мы сдвинули.


Преимущества

  • Последовательное расположение данных. Можно загружать только 1 кластер, уменьшая количество кеш промахов.
  • Простое увеличение или уменьшение хеш таблицы, достаточно перенести один бит из остатка в частное или наоборот.
  • Простое слияние двух фильтров.

См. Также

Источники