Fusion tree — различия между версиями
Lena (обсуждение | вклад) (→Параллельное сравнение) |
Lena (обсуждение | вклад) (→Вычисление sketch(x)) |
||
| Строка 49: | Строка 49: | ||
Чтобы найти sketch за константное время, будем вычислять <tex>sketch(x)</tex>, имеющий все существенные биты в нужном порядке, но содержащий лишние нули. | Чтобы найти sketch за константное время, будем вычислять <tex>sketch(x)</tex>, имеющий все существенные биты в нужном порядке, но содержащий лишние нули. | ||
| − | 1) уберем все несущественные биты <tex>x' = x</tex> AND <tex>\displaystyle \sum_{i=0}^{r-1}2^{b_i}</tex>; | + | 1) уберем все несущественные биты <tex>x' = x</tex> ''AND'' <tex>\displaystyle \sum_{i=0}^{r-1}2^{b_i}</tex>; |
2) умножением на некоторое число <tex>M = \displaystyle\sum_{i=0}^{r-1}2^{m_i}</tex> сместим все существенные биты в блок меньшего размера | 2) умножением на некоторое число <tex>M = \displaystyle\sum_{i=0}^{r-1}2^{m_i}</tex> сместим все существенные биты в блок меньшего размера | ||
| Строка 55: | Строка 55: | ||
<tex>x'\times M = \displaystyle(\sum_{i=0}^{r-1}x_{b_i}2^{b_i})(\sum_{i=0}^{r-1}2^{m_i}) = \sum_{i=0}^{r-1}\sum_{j=0}^{r-1}x_{b_i}2^{b_i+m_j}</tex>; | <tex>x'\times M = \displaystyle(\sum_{i=0}^{r-1}x_{b_i}2^{b_i})(\sum_{i=0}^{r-1}2^{m_i}) = \sum_{i=0}^{r-1}\sum_{j=0}^{r-1}x_{b_i}2^{b_i+m_j}</tex>; | ||
| − | 3) применив побитовое AND уберем лишние биты, появившиеся в результате умножения; | + | 3) применив побитовое ''AND'' уберем лишние биты, появившиеся в результате умножения; |
| − | <tex>\displaystyle\sum_{i=0}^{r-1}\sum_{j=0}^{r-1}x_{b_i}2^{b_i+m_j} | + | <tex>\displaystyle\sum_{i=0}^{r-1}\sum_{j=0}^{r-1}x_{b_i}2^{b_i+m_j}</tex> ''AND'' <tex>\displaystyle\sum_{i=0}^{r-1}2^{b_i+m_i} = \sum_{i=0}^{r-1}x_{b_i}2^{b_i+m_i}</tex>; |
4) сделаем сдвиг вправо на <tex>m_0 + b_0</tex> бит. | 4) сделаем сдвиг вправо на <tex>m_0 + b_0</tex> бит. | ||
| Строка 77: | Строка 77: | ||
}} | }} | ||
Первые два условия необходимы для того, чтобы сохранить все существенные биты в нужном порядке. Третье условие позволит поместить sketch узла в w-битный тип. Так как <tex>r \leqslant B-1</tex>, то <tex>sketch(node)</tex> будет занимать <tex>B(r^4 + 1) \leqslant B((B-1)^4 + 1) \leqslant B^5 = (w^{1/5})^5 = w </tex> бит. | Первые два условия необходимы для того, чтобы сохранить все существенные биты в нужном порядке. Третье условие позволит поместить sketch узла в w-битный тип. Так как <tex>r \leqslant B-1</tex>, то <tex>sketch(node)</tex> будет занимать <tex>B(r^4 + 1) \leqslant B((B-1)^4 + 1) \leqslant B^5 = (w^{1/5})^5 = w </tex> бит. | ||
| + | |||
==Индекс наиболее значащего бита== | ==Индекс наиболее значащего бита== | ||
Чтобы найти в w-битном числе ''x'' индекс самого старшего бита, содержащего еденицу, разделим ''x'' на <tex>\sqrt{w}</tex> блоков по <tex>\sqrt{w}</tex> бит. | Чтобы найти в w-битном числе ''x'' индекс самого старшего бита, содержащего еденицу, разделим ''x'' на <tex>\sqrt{w}</tex> блоков по <tex>\sqrt{w}</tex> бит. | ||
Версия 17:51, 11 июня 2013
Fusion tree — дерево поиска, позволяющее хранить -битных положительных чисел, используя памяти, и выполнять операции поиска за время . Эта структура данных была впервые предложенна в 1990 году М. Фредманом (M. Fredman) и Д. Уиллардом (D. Willard).
Содержание
Структура
Fusion tree — это B-дерево, такое что:
- у всех вершин, кроме листьев, детей;
- время, за которое определяется в каком поддереве находится вершина, равно .
Такое время работы достигается за счет хранения дополнительной информации в вершинах. Построим цифровой бор из ключей узла дерева. Всего ветвящихся вершин. Биты, соответствующие уровням дерева, в которых происходит ветвление, назовем существенными и обозначим их номера . Количество существенных битов не больше чем .
В Fusion tree вместе с ключом хранится - последовательность битов .
| Утверждение: |
сохраняет порядок, то есть , если . |
| Рассмотрим наибольший общий префикс и . Тогда следующий бит определяет их порядок и одновременно является существенным битом. |
Поиск вершины
Пусть - множество ключей узла, отсортированных по возрастанию, - ключ искомой вершины, - количество бит в . Сначала найдем такой ключ , что . Но положение среди не всегда эквивалентно положению среди , поэтому, зная соседние элементы , найдем и .
Параллельное сравнение
Найдем и . Определим как число, составленное из едениц и , то есть . Вычтем из число . В начале каждого блока, где , сохранятся еденицы. Применим к получившемуся побитовое AND c , чтобы убрать лишние биты.
AND
Если , то , в противном случае . Теперь надо найти количество едениц в L. Умножим L на , тогда все еденицы сложатся в первом блоке результата, и, чтобы получить количество едениц, сдвинем его вправо.
Succ(q) и pred(q)
Пусть .
| Утверждение: |
Среди всех ключей наибольший общий префикс с будет иметь или или . |
| Педположим, что имеет наибольший общий префикс с . Тогда будет иметь больше общих битов со . Значит, ближе по значению к , чем или , что приводит к противоречию. |
Сравнивая XOR и XOR , найдем какой из ключей имеет наибольший общий префикс с (наименьшнее значение соответствует наибольшей длине).
Предположим, что - наибольший общий перфикс, а его длина, - ключ, имеющий наибольший общий префикс с ( или ).
- если , то бит равен еденице, а бит равен нулю. Так как общий префикс и является наибольшим, то не существет ключа с префиксом . Значит, больше всех ключей с префиксом меньшим либо равным . Найдем , , который одновременно будет ;
- если - найдем , . Это будет .
Длина наибольшего общего префикса двух w-битных чисел и может быть вычислена с помощью нахождения индекса наиболее значащего бита в побитовом XOR и .
Вычисление sketch(x)
Чтобы найти sketch за константное время, будем вычислять , имеющий все существенные биты в нужном порядке, но содержащий лишние нули.
1) уберем все несущественные биты AND ;
2) умножением на некоторое число сместим все существенные биты в блок меньшего размера
;
3) применив побитовое AND уберем лишние биты, появившиеся в результате умножения;
AND ;
4) сделаем сдвиг вправо на бит.
| Утверждение: |
Дана последовательность из r чисел . Тогда существует последовательность , такая что:
1) все различны, для ; 2) ; 3) . |
|
Выберем некоторые , таким образом, чтобы . Предположим, что мы выбрали . Тогда . Всего недопустимых значений для , поэтому всегда можно найти хотя бы одно значение. Чтобы получить , выбираем каждый раз наименьшее и прибавляем подходящее число кратное , такое что . |
Первые два условия необходимы для того, чтобы сохранить все существенные биты в нужном порядке. Третье условие позволит поместить sketch узла в w-битный тип. Так как , то будет занимать бит.
Индекс наиболее значащего бита
Чтобы найти в w-битном числе x индекс самого старшего бита, содержащего еденицу, разделим x на блоков по бит. . Далее найдем первый непустой блок и индекс первого еденичного бита в нем.
1)Поиск непустых блоков.
a. Определим какие блоки имеют еденицу в первом бите. Применим побитовое AND к x и константой F
b. Определим, содержат ли остальные биты еденицы.
Вычислим .
Вычтем от . Если какой-нибудь бит обнулится, значит, соответствующий блок содержит еденицы.
Чтобы найти блоки, содержащие еденицы, вычислим .
c. Первый бит в каждом блоке содержит еденицу, если соответствующий блок x ненулевой.
2) найдем sketch(y), чтобы сместить все нужные биты в один блок. Существенными битами в данном случае будут первые биты каждого блока, поэтому .
Будем использовать . Тогда . Все суммы различны при . Все возрастают, и . Чтобы найти sketch(y), умножим y на m и сдвинем вправо на w бит.
3)Найдем первый ненулевой блок. Для этого надо найти первую еденицу в sketch(y). Как и при поиске succ(sketch(q)) и pred(sketch(q)) используем параллельное сравнение sketch(y) с . В результате сравнения получим номер первого ненулевого блока .
4) найдем номер первого еденичного бита в найденном блоке так же как и в предыдущем пункте.
5) инедекс наиболее значащего бита будет равен .
Каждый шаг выполняется за , поэтому всего потребуется времени, чтобы найти индекс.
Ссылки
MIT CS 6.897: Advanced Data Structures: Lecture 4, Fusion Trees, Prof. Erik Demaine (Spring 2003)