Fusion tree — различия между версиями
Lena (обсуждение | вклад) (→Вычисление sketch(x)) |
Lena (обсуждение | вклад) (→Индекс наиболее значащего бита) |
||
Строка 79: | Строка 79: | ||
==Индекс наиболее значащего бита== | ==Индекс наиболее значащего бита== | ||
− | Чтобы найти в w-битном числе | + | Чтобы найти в w-битном числе <tex>x</tex> индекс самого старшего бита, содержащего еденицу, разделим <tex>x</tex> на <tex>\sqrt{w}</tex> блоков по <tex>\sqrt{w}</tex> бит. <tex>x = \underbrace{0101}_{\sqrt{w}}\; \underbrace{0000}_{\sqrt{w}}\; \underbrace{1000}_{\sqrt{w}}\; \underbrace{1101}_{\sqrt{w}}</tex>. Далее найдем первый непустой блок и индекс первого еденичного бита в нем. |
− | <tex>x = \underbrace{0101}_{\sqrt{w}}\; \underbrace{0000}_{\sqrt{w}}\; \underbrace{1000}_{\sqrt{w}}\; \underbrace{1101}_{\sqrt{w}}</tex>. Далее найдем первый непустой блок и индекс первого еденичного бита в нем. | ||
− | 1)Поиск непустых блоков. | + | '''1)''' Поиск непустых блоков. |
− | a. Определим какие блоки имеют еденицу в первом бите. Применим побитовое AND | + | '''a.''' Определим, какие блоки имеют еденицу в первом бите. Применим побитовое ''AND'' к <tex>x</tex> и константе <tex>F</tex>. |
− | <tex> | + | |
− | $$ | + | <tex>$$ |
\begin{array}{r} | \begin{array}{r} | ||
AND | AND | ||
\begin{array}{r} | \begin{array}{r} | ||
x = 0101\; 0000\; 1000\; 1101\\ | x = 0101\; 0000\; 1000\; 1101\\ | ||
− | F = 1000\; 1000\; 1000\; 1000\\ | + | F = 1000\; 1000\; 1000\; 1000\\ |
− | \end{array} \\ | + | \end{array}\\ |
− | \hline | + | \hline |
− | \begin{array}{r} | + | \begin{array}{r} |
− | t_1 = \underline{0}000\; \underline{0}000\; \underline{1}000\; \underline{1}000 | + | t_1 = \underline{0}000\; \underline{0}000\; \underline{1}000\; \underline{1}000 \end{array}\end{array} |
− | \end{array} | ||
− | \end{array} | ||
$$</tex> | $$</tex> | ||
− | |||
− | Вычислим <tex>x | + | '''b.''' Определим, содержат ли остальные биты еденицы. |
+ | |||
+ | Вычислим <tex>x</tex> ''XOR'' <tex>t_1</tex>. | ||
+ | |||
<tex> | <tex> | ||
Строка 119: | Строка 118: | ||
\end{array} | \end{array} | ||
$$</tex> | $$</tex> | ||
+ | |||
Вычтем от <tex>F\; t_2</tex>. Если какой-нибудь бит <tex>F</tex> обнулится, значит, соответствующий блок содержит еденицы. | Вычтем от <tex>F\; t_2</tex>. Если какой-нибудь бит <tex>F</tex> обнулится, значит, соответствующий блок содержит еденицы. | ||
+ | |||
<tex> | <tex> | ||
Строка 137: | Строка 138: | ||
$$</tex> | $$</tex> | ||
− | Чтобы найти блоки, содержащие еденицы, вычислим <tex>t_3 | + | |
+ | Чтобы найти блоки, содержащие еденицы, вычислим <tex>t_3</tex> ''XOR'' <tex>F</tex>. | ||
+ | |||
<tex> | <tex> | ||
Строка 154: | Строка 157: | ||
$$</tex> | $$</tex> | ||
− | c. Первый бит в каждом блоке <tex>y = t_1 | + | |
+ | '''c.''' Первый бит в каждом блоке <tex>y = t_1</tex> ''OR'' <tex>t_4</tex> содержит еденицу, если соответствующий блок <tex>x</tex> ненулевой. | ||
+ | |||
<tex>$$ | <tex>$$ | ||
Строка 170: | Строка 175: | ||
$$</tex> | $$</tex> | ||
− | |||
− | Будем использовать <tex>m_j = w - (\sqrt{w}-1) - j\sqrt{w} +j</tex>. Тогда <tex>b_i + m_j = w + (i - j)\sqrt{w} + j</tex>. Все суммы различны при <tex>0\leqslant i, j < \sqrt{w} </tex>. Все <tex>b_i + m_i = w + i</tex> возрастают, и <tex>(b_{\sqrt{w} - 1} + m_{\sqrt{w} - 1}) - (b_0 + m_0) = \sqrt{w} - 1</tex>. Чтобы найти sketch(y), умножим y на m и сдвинем вправо на w бит. | + | '''2)''' Найдем <tex>sketch(y)</tex>, чтобы сместить все нужные биты в один блок. Существенными битами в данном случае будут первые биты каждого блока, поэтому <tex>b_i = \sqrt{w} - 1 + i\sqrt{w}</tex>. |
+ | |||
+ | Будем использовать <tex>m_j = w - (\sqrt{w}-1) - j\sqrt{w} +j</tex>. Тогда <tex>b_i + m_j = w + (i - j)\sqrt{w} + j</tex>. Все суммы различны при <tex>0\leqslant i, j < \sqrt{w} </tex>. Все <tex>b_i + m_i = w + i</tex> возрастают, и <tex>(b_{\sqrt{w} - 1} + m_{\sqrt{w} - 1}) - (b_0 + m_0) = \sqrt{w} - 1</tex>. | ||
+ | |||
+ | Чтобы найти <tex>sketch(y)</tex>, умножим <tex>y</tex> на <tex>m</tex> и сдвинем вправо на <tex>w</tex> бит. | ||
− | 3)Найдем первый ненулевой блок. Для этого надо найти первую еденицу в sketch(y). Как и при поиске succ(sketch(q)) и pred(sketch(q)) используем параллельное сравнение sketch(y) с <tex>2^0, 2^1 \ldots 2^{\sqrt{w} - 1}</tex>. В результате сравнения получим номер первого ненулевого блока <tex>c</tex>. | + | '''3)''' Найдем первый ненулевой блок. Для этого надо найти первую еденицу в <tex>sketch(y)</tex>. Как и при поиске <tex>succ(sketch(q))</tex> и <tex>pred(sketch(q))</tex> используем параллельное сравнение <tex>sketch(y)</tex> с <tex>2^0, 2^1 \ldots 2^{\sqrt{w} - 1}</tex>. В результате сравнения получим номер первого ненулевого блока <tex>c</tex>. |
− | 4) | + | '''4)''' Найдем номер <tex>d</tex> первого еденичного бита в найденном блоке так же как и в предыдущем пункте. |
− | 5) | + | '''5)''' Индекс наиболее значащего бита будет равен <tex>c\sqrt{w}+d</tex>. |
Каждый шаг выполняется за <tex>O(1)</tex>, поэтому всего потребуется <tex>O(1)</tex> времени, чтобы найти индекс. | Каждый шаг выполняется за <tex>O(1)</tex>, поэтому всего потребуется <tex>O(1)</tex> времени, чтобы найти индекс. |
Версия 18:34, 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-битном числе
индекс самого старшего бита, содержащего еденицу, разделим на блоков по бит. . Далее найдем первый непустой блок и индекс первого еденичного бита в нем.1) Поиск непустых блоков.
a. Определим, какие блоки имеют еденицу в первом бите. Применим побитовое AND к
и константе .
b. Определим, содержат ли остальные биты еденицы.
Вычислим
XOR .
Вычтем от . Если какой-нибудь бит обнулится, значит, соответствующий блок содержит еденицы.
Чтобы найти блоки, содержащие еденицы, вычислим XOR .
c. Первый бит в каждом блоке OR содержит еденицу, если соответствующий блок ненулевой.
2) Найдем , чтобы сместить все нужные биты в один блок. Существенными битами в данном случае будут первые биты каждого блока, поэтому .
Будем использовать
. Тогда . Все суммы различны при . Все возрастают, и .Чтобы найти
, умножим на и сдвинем вправо на бит.3) Найдем первый ненулевой блок. Для этого надо найти первую еденицу в
. Как и при поиске и используем параллельное сравнение с . В результате сравнения получим номер первого ненулевого блока .4) Найдем номер
первого еденичного бита в найденном блоке так же как и в предыдущем пункте.5) Индекс наиболее значащего бита будет равен
.Каждый шаг выполняется за
, поэтому всего потребуется времени, чтобы найти индекс.Ссылки
MIT CS 6.897: Advanced Data Structures: Lecture 4, Fusion Trees, Prof. Erik Demaine (Spring 2003)