Fusion tree — различия между версиями
Zernov (обсуждение | вклад) м |
Zernov (обсуждение | вклад) (→Индекс наиболее значащего бита) |
||
Строка 78: | Строка 78: | ||
Чтобы найти в <tex>w</tex>-битном числе <tex>x</tex> индекс самого старшего бита, содержащего единицу (это понадобится в дальнейшем, для нахождения <tex>sketch(y)</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>w</tex>-битном числе <tex>x</tex> индекс самого старшего бита, содержащего единицу (это понадобится в дальнейшем, для нахождения <tex>sketch(y)</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>\&</tex> к <tex>x</tex> и константе <tex> F </tex>: <tex> | |
− | + | $$ | |
− | |||
− | |||
− | <tex>$$ | ||
\begin{array}{r} | \begin{array}{r} | ||
\& | \& | ||
Строка 94: | Строка 91: | ||
t_1 = \underline{0}000\; \underline{0}000\; \underline{1}000\; \underline{1}000 \end{array}\end{array} | t_1 = \underline{0}000\; \underline{0}000\; \underline{1}000\; \underline{1}000 \end{array}\end{array} | ||
$$</tex> | $$</tex> | ||
− | + | ##Определим, содержат ли остальные биты единицы. | |
− | + | ###Вычислим <tex>x \oplus t_1</tex>: <tex> | |
− | |||
− | |||
− | Вычислим <tex>x \oplus t_1</tex> | ||
− | |||
− | |||
− | <tex> | ||
$$ | $$ | ||
\begin{array}{r} | \begin{array}{r} | ||
Строка 115: | Строка 106: | ||
\end{array} | \end{array} | ||
$$</tex> | $$</tex> | ||
− | + | ### Вычтем из <tex>F\; t_2</tex>. Если какой-нибудь бит <tex>F</tex> обнулится, значит, соответствующий блок содержит единицы: <tex> | |
− | |||
− | Вычтем из <tex>F\; t_2</tex>. Если какой-нибудь бит <tex>F</tex> обнулится, значит, соответствующий блок содержит единицы | ||
− | |||
− | |||
− | <tex> | ||
$$ | $$ | ||
\begin{array}{r} | \begin{array}{r} | ||
Строка 134: | Строка 120: | ||
\end{array} | \end{array} | ||
$$</tex> | $$</tex> | ||
− | + | ###Чтобы найти блоки, содержащие единицы, вычислим <tex>t_3 \oplus F</tex>: <tex> | |
− | |||
− | Чтобы найти блоки, содержащие единицы, вычислим <tex>t_3 \oplus F</tex> | ||
− | |||
− | |||
− | <tex> | ||
$$ | $$ | ||
\begin{array}{r} | \begin{array}{r} | ||
Строка 153: | Строка 134: | ||
\end{array} | \end{array} | ||
$$</tex> | $$</tex> | ||
− | + | ##Первый бит в каждом блоке <tex>y = t_1 \lor t_4</tex> содержит единицу, если соответствующий блок <tex>x</tex> ненулевой: <tex>$$ | |
− | |||
− | |||
− | |||
− | |||
− | <tex>$$ | ||
\begin{array}{r} | \begin{array}{r} | ||
\lor | \lor | ||
Строка 171: | Строка 147: | ||
\end{array} | \end{array} | ||
$$</tex> | $$</tex> | ||
− | + | # Найдем <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> бит. | |
− | + | # Найдем первый ненулевой блок. Для этого надо найти первую единицу в <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>. | |
− | + | #Найдем номер <tex>d</tex> первого единичного бита в найденном блоке так же как и в предыдущем пункте. | |
− | + | #Индекс наиболее значащего бита будет равен <tex>c\sqrt{w}+d</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> бит. | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
Каждый шаг выполняется за <tex>O(1)</tex>, поэтому всего потребуется <tex>O(1)</tex> времени, чтобы найти индекс. | Каждый шаг выполняется за <tex>O(1)</tex>, поэтому всего потребуется <tex>O(1)</tex> времени, чтобы найти индекс. |
Версия 19:14, 6 июня 2015
Fusion tree — дерево поиска, позволяющее хранить
-битных чисел, используя памяти, и выполнять операции поиска за время . Эта структура данных была впервые предложена в 1990 году М. Фредманом (M. Fredman) и Д. Уиллардом (D. Willard).Содержание
Структура
Fusion tree — это B-дерево, такое что:
- у всех вершин, кроме листьев, детей,
- время, за которое определяется, в каком поддереве находится вершина, равно .
Такое время работы достигается за счет хранения дополнительной информации в вершинах. Построим цифровой бор из ключей узла дерева. Всего ветвящихся вершин. Биты, соответствующие уровням дерева, в которых происходит ветвление, назовем существенными и обозначим их номера (индексация идет от листьев, которые соответствуют концу числа, т.е. младшему разряду). Количество существенных битов не больше (все ребра на уровне детей ветвящейся вершины — обведены на рисунке — являются существенными битами, и так как ветвящихся вершин , значит, и количество уровней с детьми не больше , поскольку на одном уровне могут быть несколько ветвящихся вершин).
В Fusion tree вместе с ключом
хранится — последовательность битов .Утверждение: |
сохраняет порядок, то есть , если . |
Рассмотрим наибольший общий префикс | и . Тогда следующий бит определяет их порядок и одновременно является существенным битом. Поэтому, если , то и .
Поиск вершины
Пусть
— множество ключей узла, отсортированных по возрастанию, — ключ искомой вершины, — количество бит в . Сначала найдем такой ключ , что . Хотя положение среди не всегда эквивалентно положению среди , зная соседние элементы , мы можем найти и .Поиск следующего и предыдущего
Утверждение: |
Пусть . Тогда среди всех ключей наибольший общий префикс с будет иметь или или . |
Предположим, что Рассмотрим имеет наибольший общий префикс с . Тогда будет иметь больше общих битов со . Значит, ближе по значению к , чем или , что приводит к противоречию. . У него есть существенные биты и некоторый элемент , с которым у наибольший общий префикс (настоящий, а не по ). Биты из , находящиеся в префиксе совпадают, значит и среди должны быть такими же среди , и один из них имеет дальше бит (а другой ) и с ним может быть больше других общих бит в . То есть либо , либо имеют следующий существенный бит такой же, как и у . Поэтому если значение равно , то наибольший среди значений с меньшим , и, аналогично для , наименьший среди больших. |
Сравнивая
и , найдем какой из ключей и имеет наибольший общий префикс с (наименьшее значение соответствует наибольшей длине, так как одинаковые старшие биты обнулятся, следовательно, если , то у первый несовпадающий бит старше, чем у ).Предположим, что
— наибольший общий префикс, а его длина, — ключ, имеющий наибольший общий префикс с ( или ).- если , то бит равен единице, а бит равен нулю. Так как общий префикс и является наибольшим, то не существует ключа с префиксом . Значит, больше всех ключей с префиксом меньшим либо равным . Найдем , , который одновременно будет ,
- если — найдем , . Это будет .
Длина наибольшего общего префикса двух
-битных чисел и может быть вычислена с помощью нахождения индекса наиболее значащего бита в побитовом и .Сравнение значений sketch двух чисел
В предыдущем абзаце мы научились считать
и , теперь найдем их. Определим как число, составленное из единиц и , то есть . Вычтем из число . В начале каждого блока, где , сохранятся единицы. Применим к получившемуся побитовое c , чтобы убрать лишние биты.
Если
, то , в противном случае . Теперь надо найти количество единиц в . Умножим на , тогда все единицы сложатся в первом блоке результата, и, чтобы получить количество единиц, сдвинем его вправо на бит.Вычисление sketch(x)
Чтобы найти sketch за константное время, будем вычислять
, имеющий все существенные биты в нужном порядке, но содержащий лишние нули. Хотя содержит лишние нули, мы сможем вычислять его быстрее, чем обычный , потому что нам не придется каждый раз идти по всем битам числа, выбирая стоящие на нужных нам местах- Уберем все несущественные биты .
- Умножением на некоторое заранее вычисленное число сместим все существенные биты в блок меньшего размера: .
- Применив побитовое , уберем лишние биты, появившиеся в результате умножения: .
- Сделаем сдвиг вправо на бит.
Утверждение: |
Дана последовательность из чисел . Тогда существует последовательность , такая что:
|
Выберем некоторые Чтобы получить , таким образом, чтобы . Предположим, что мы выбрали . Тогда . Всего недопустимых значений для , поэтому всегда можно найти хотя бы одно значение. , выбираем каждый раз наименьшее и прибавляем подходящее число кратное , такое что . |
Первые два условия необходимы для того, чтобы сохранить все существенные биты в нужном порядке. Третье условие позволит поместить
узла в -битный тип. Так как , то будет занимать бит, при всехИндекс наиболее значащего бита
Чтобы найти в
-битном числе индекс самого старшего бита, содержащего единицу (это понадобится в дальнейшем, для нахождения ), разделим на блоков по бит. . Далее найдем первый непустой блок и индекс первого единичного бита в нем.- Поиск непустых блоков.
- Определим, какие блоки имеют единицу в первом бите. Применим побитовое к и константе :
- Определим, содержат ли остальные биты единицы.
- Вычислим :
- Вычтем из . Если какой-нибудь бит обнулится, значит, соответствующий блок содержит единицы:
- Чтобы найти блоки, содержащие единицы, вычислим :
- Первый бит в каждом блоке содержит единицу, если соответствующий блок ненулевой:
- Найдем , чтобы сместить все нужные биты в один блок. Существенными битами в данном случае будут первые биты каждого блока, поэтому . Будем использовать . Тогда . Все суммы различны при . Все возрастают, и . Чтобы найти , умножим на и сдвинем вправо на бит.
- Найдем первый ненулевой блок. Для этого надо найти первую единицу в . Как и при поиске и используем параллельное сравнение с . В результате сравнения получим номер первого ненулевого блока .
- Найдем номер первого единичного бита в найденном блоке так же как и в предыдущем пункте.
- Индекс наиболее значащего бита будет равен .
Каждый шаг выполняется за
, поэтому всего потребуется времени, чтобы найти индекс.Циклы де Брёйна
Последовательность де Брёйна — последовательность
, элементы которой принадлежат заданному конечному множеству (обычно рассматривают множество ), и все подпоследовательности заданной длины различны.Часто рассматриваются периодические последовательности с периодом
, содержащие различных подпоследовательностей , — то есть такие периодические последовательности, в которых любой отрезок длины является последовательностью де Брёйна с теми же параметрами и .Свойства
Очевидно, что длина (период) такого цикла не может превосходить
— числа́ всех различных векторов длины с элементами из ; несложно доказать, что эта оценка достигается. Циклы этой максимально возможной длины обычно называют циклами де Брёйна (впрочем, иногда этот термин применяют и к циклам меньшей длины).При
существуют такие циклы де Брёйна с длиной, на единицу меньшей максимума, которые выражаются линейными рекуррентными соотношениями порядка : так, при соотношение порождает последовательности с периодом 7, например 0010111001011100… (цикл де Брёйна 0010111). На основе таких последовательностей построен, в частности, циклический избыточный код.Примеры
Примеры циклов де Брёйна для
с периодом 2, 4, 8, 16:- 01 (содержит подпоследовательности 0 и 1)
- 0011 (содержит подпоследовательности 00, 01, 11, 10)
- 00010111 (000, 001, 010, 101, 011, 111, 110, 100)
- 0000100110101111
Граф де Брёйна
Существует удобная интерпретация последовательностей и циклов де Брёйна, основанная на так называемом графе де Брёйна — ориентированном графе с
вершинами, соответствующими различных наборов длины с элементами из , в котором из вершины в вершину ребро ведёт в том и только том случае, когда ( ); при этом самому ребру можно сопоставить набор длины : . Для такого графа не проходящие дважды через одно и то же ребро эйлеровы пути (эйлеровы циклы) соответствуют последовательности (циклу) де Брёйна с параметрами и , а не проходящие дважды через одну и ту же вершину гамильтоновы пути (гамильтоновы циклы) — последовательности (циклу) де Брёйна с параметрами и .Граф де Брёйна широко применяется в биоинформатике в задачах сборки генома.