Fusion tree — различия между версиями
 (→Структура)  | 
				Zernov (обсуждение | вклад)   | 
				||
| Строка 4: | Строка 4: | ||
* у всех вершин, кроме листьев, <tex>B = w^{1/5}</tex> детей,  | * у всех вершин, кроме листьев, <tex>B = w^{1/5}</tex> детей,  | ||
* время, за которое определяется, в каком поддереве находится вершина, равно <tex>O(1)</tex>.  | * время, за которое определяется, в каком поддереве находится вершина, равно <tex>O(1)</tex>.  | ||
| − | Такое время работы достигается за счет хранения дополнительной информации в вершинах. Построим цифровой бор из ключей узла дерева. Всего <tex>B - 1</tex> ветвящихся вершин. Биты, соответствующие уровням дерева,  в которых происходит ветвление, назовем существенными и обозначим их номера <tex>b_0, b_1\ldots b_{r-1}</tex>. Количество существенных битов <tex>r</tex> равно <tex>B - 1</tex> (все ребра на уровне детей ветвящейся вершины являются существенными битами).  | + | Такое время работы достигается за счет хранения дополнительной информации в вершинах. Построим [[:Сверхбыстрый_цифровой_бор|цифровой бор]] из ключей узла дерева. Всего <tex>B - 1</tex> ветвящихся вершин. Биты, соответствующие уровням дерева,  в которых происходит ветвление, назовем существенными и обозначим их номера <tex>b_0, b_1\ldots b_{r-1}</tex>. Количество существенных битов <tex>r</tex> равно <tex>B - 1</tex> (все ребра на уровне детей ветвящейся вершины являются существенными битами).  | 
[[Файл:Fusion.png||500x400px|center|визуализация функции sketch]]  | [[Файл:Fusion.png||500x400px|center|визуализация функции sketch]]  | ||
| Строка 22: | Строка 22: | ||
Пусть <tex>\left \{ a_1,a_2\ldots a_k\right \}</tex> {{---}} множество ключей узла, отсортированных по возрастанию, <tex>q</tex> {{---}} ключ искомой вершины, <tex>l</tex> {{---}} количество бит в <tex>sketch(q)</tex>. Сначала найдем такой ключ <tex>a_i</tex>, что <tex>sketch(a_i) \leqslant sketch(q) \leqslant sketch(a_{i+1})</tex>. Но положение <tex>sketch(q)</tex> среди <tex>sketch(a_j)</tex> не всегда эквивалентно положению <tex>q</tex> среди <tex>a_j</tex>, поэтому, зная соседние элементы <tex>sketch(q)</tex>, найдем <tex>succ(q)</tex> и <tex>pred(q)</tex>.  | Пусть <tex>\left \{ a_1,a_2\ldots a_k\right \}</tex> {{---}} множество ключей узла, отсортированных по возрастанию, <tex>q</tex> {{---}} ключ искомой вершины, <tex>l</tex> {{---}} количество бит в <tex>sketch(q)</tex>. Сначала найдем такой ключ <tex>a_i</tex>, что <tex>sketch(a_i) \leqslant sketch(q) \leqslant sketch(a_{i+1})</tex>. Но положение <tex>sketch(q)</tex> среди <tex>sketch(a_j)</tex> не всегда эквивалентно положению <tex>q</tex> среди <tex>a_j</tex>, поэтому, зная соседние элементы <tex>sketch(q)</tex>, найдем <tex>succ(q)</tex> и <tex>pred(q)</tex>.  | ||
===Параллельное сравнение===  | ===Параллельное сравнение===  | ||
| − | Найдем <tex>succ(sketch(q))</tex> и <tex>pred(sketch(q))</tex>. Определим <tex>sketch(node)</tex> как число, составленное из единиц и <tex>sketch(a_i)</tex>, то есть <tex>sketch(node) = 1sketch(a_1)1sketch(a_2)\ldots 1sketch(a_k)</tex>. Вычтем из <tex>sketch(node)</tex> число <tex>sketch(q) \times \underbrace{\overbrace{00\ldots 1}^{l + 1 bits}\overbrace{00\ldots 1}^{l + 1 bits}\ldots \overbrace{00\ldots 1}^{l + 1 bits}}_{k(l + 1)  bits} = 0sketch(q)\ldots 0sketch(q)</tex>. В начале каждого блока, где <tex>sketch(a_i) \geqslant sketch(q)</tex>, сохранятся единицы. Применим к получившемуся побитовое   | + | Найдем <tex>succ(sketch(q))</tex> и <tex>pred(sketch(q))</tex>. Определим <tex>sketch(node)</tex> как число, составленное из единиц и <tex>sketch(a_i)</tex>, то есть <tex>sketch(node) = 1sketch(a_1)1sketch(a_2)\ldots 1sketch(a_k)</tex>. Вычтем из <tex>sketch(node)</tex> число <tex>sketch(q) \times \underbrace{\overbrace{00\ldots 1}^{l + 1 bits}\overbrace{00\ldots 1}^{l + 1 bits}\ldots \overbrace{00\ldots 1}^{l + 1 bits}}_{k(l + 1)  bits} = 0sketch(q)\ldots 0sketch(q)</tex>. В начале каждого блока, где <tex>sketch(a_i) \geqslant sketch(q)</tex>, сохранятся единицы. Применим к получившемуся побитовое & c <tex>\displaystyle \sum_{i=0}^{k-1}2^{i(l+1)+l}</tex>, чтобы убрать лишние биты.  | 
| − | <tex>L = (1sketch(a_1)\ldots 1sketch(a_k) - 0sketch(q)\ldots 0sketch(q))  | + | <tex>L = (1sketch(a_1)\ldots 1sketch(a_k) - 0sketch(q)\ldots 0sketch(q))</tex>&<tex> \displaystyle \sum_{i=0}^{k-1}2^{i(l+1)+l}=\overbrace{c_10\ldots0}^{l+1 bits} \ldots \overbrace{c_k0\ldots0}^{l+1 bits}</tex>  | 
Если <tex>sketch(a_i)< sketch(q)</tex>, то <tex>c_i = 0</tex>, в противном случае <tex>c_i = 1</tex>.  | Если <tex>sketch(a_i)< sketch(q)</tex>, то <tex>c_i = 0</tex>, в противном случае <tex>c_i = 1</tex>.  | ||
| Строка 45: | Строка 45: | ||
* если <tex>q<a_j</tex> {{---}} найдем <tex>succ(e)</tex>, <tex>e = p10\ldots 00</tex>. Это будет <tex>succ(q)</tex>.  | * если <tex>q<a_j</tex> {{---}} найдем <tex>succ(e)</tex>, <tex>e = p10\ldots 00</tex>. Это будет <tex>succ(q)</tex>.  | ||
| − | Длина наибольшего общего префикса двух ''w''-битных чисел <tex>a</tex> и <tex>b</tex> может быть вычислена с помощью нахождения индекса наиболее значащего бита в побитовом   | + | Длина наибольшего общего префикса двух ''w''-битных чисел <tex>a</tex> и <tex>b</tex> может быть вычислена с помощью нахождения индекса наиболее значащего бита в побитовом <tex>\oplus a</tex> и <tex>b</tex>.  | 
==Вычисление sketch(x)==  | ==Вычисление sketch(x)==  | ||
Чтобы найти sketch за константное время, будем вычислять <tex>sketch(x)</tex>, имеющий все существенные биты в нужном порядке, но содержащий лишние нули.  | Чтобы найти sketch за константное время, будем вычислять <tex>sketch(x)</tex>, имеющий все существенные биты в нужном порядке, но содержащий лишние нули.  | ||
| − | 1) уберем все несущественные биты <tex>x' = x   | + | 1) уберем все несущественные биты <tex>x' = x </tex>&<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> сместим все существенные биты в блок меньшего размера.  | ||
| Строка 56: | Строка 56: | ||
<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) применив побитовое   | + | 3) применив побитовое &, уберем лишние биты, появившиеся в результате умножения,  | 
| − | <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>&<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> бит.  | ||
| Строка 81: | Строка 81: | ||
'''1)''' Поиск непустых блоков.  | '''1)''' Поиск непустых блоков.  | ||
| − | '''a.''' Определим, какие блоки имеют единицу в первом бите. Применим побитовое   | + | '''a.''' Определим, какие блоки имеют единицу в первом бите. Применим побитовое & к <tex>x</tex> и константе <tex>F</tex>.    | 
<tex>$$  | <tex>$$  | ||
\begin{array}{r}  | \begin{array}{r}  | ||
| − | + | AND  | |
\begin{array}{r}  | \begin{array}{r}  | ||
x = 0101\; 0000\; 1000\; 1101\\  | x = 0101\; 0000\; 1000\; 1101\\  | ||
| Строка 213: | Строка 213: | ||
Граф де Брёйна широко применяется в биоинформатике в задачах сборки генома.  | Граф де Брёйна широко применяется в биоинформатике в задачах сборки генома.  | ||
| + | |||
| + | ==См. Также==  | ||
| + | |||
| + | *[[:Сверхбыстрый_цифровой_бор|Сверхбыстрый цифровой бор]]  | ||
| + | |||
| + | *[[:2-3_дерево|2-3 дерево]]  | ||
| + | |||
== Источники информации ==  | == Источники информации ==  | ||
Версия 16:47, 5 июня 2015
Fusion tree — дерево поиска, позволяющее хранить -битных чисел, используя памяти, и выполнять операции поиска за время . Эта структура данных была впервые предложена в 1990 году М. Фредманом (M. Fredman) и Д. Уиллардом (D. Willard).
Содержание
Структура
Fusion tree — это B-дерево, такое что:
- у всех вершин, кроме листьев, детей,
 - время, за которое определяется, в каком поддереве находится вершина, равно .
 
Такое время работы достигается за счет хранения дополнительной информации в вершинах. Построим цифровой бор из ключей узла дерева. Всего ветвящихся вершин. Биты, соответствующие уровням дерева, в которых происходит ветвление, назовем существенными и обозначим их номера . Количество существенных битов равно (все ребра на уровне детей ветвящейся вершины являются существенными битами).
В Fusion tree вместе с ключом хранится — последовательность битов .
| Утверждение: | 
 сохраняет порядок, то есть , если .  | 
| Рассмотрим наибольший общий префикс и . Тогда следующий бит определяет их порядок и одновременно является существенным битом. Поэтому, если , то и . | 
Поиск вершины
Пусть — множество ключей узла, отсортированных по возрастанию, — ключ искомой вершины, — количество бит в . Сначала найдем такой ключ , что . Но положение среди не всегда эквивалентно положению среди , поэтому, зная соседние элементы , найдем и .
Параллельное сравнение
Найдем и . Определим как число, составленное из единиц и , то есть . Вычтем из число . В начале каждого блока, где , сохранятся единицы. Применим к получившемуся побитовое & c , чтобы убрать лишние биты.
&
Если , то , в противном случае . Теперь надо найти количество единиц в L. Умножим L на , тогда все единицы сложатся в первом блоке результата, и, чтобы получить количество единиц, сдвинем его вправо.
succ(q) и pred(q)
Пусть .
| Утверждение: | 
Среди всех ключей наибольший общий префикс с  будет иметь или  или .  | 
| Предположим, что имеет наибольший общий префикс с . Тогда будет иметь больше общих битов со . Значит, ближе по значению к , чем или , что приводит к противоречию. | 
Сравнивая и , найдем какой из ключей имеет наибольший общий префикс с (наименьшее значение соответствует наибольшей длине).
Предположим, что — наибольший общий префикс, а его длина, — ключ, имеющий наибольший общий префикс с ( или ).
- если , то бит равен единице, а бит равен нулю. Так как общий префикс и является наибольшим, то не существует ключа с префиксом . Значит, больше всех ключей с префиксом меньшим либо равным . Найдем , , который одновременно будет ,
 - если — найдем , . Это будет .
 
Длина наибольшего общего префикса двух w-битных чисел и может быть вычислена с помощью нахождения индекса наиболее значащего бита в побитовом и .
Вычисление sketch(x)
Чтобы найти sketch за константное время, будем вычислять , имеющий все существенные биты в нужном порядке, но содержащий лишние нули.
1) уберем все несущественные биты &,
2) умножением на некоторое заранее вычисленное число сместим все существенные биты в блок меньшего размера.
,
3) применив побитовое &, уберем лишние биты, появившиеся в результате умножения,
&,
4) сделаем сдвиг вправо на бит.
| Утверждение: | 
Дана последовательность из  чисел . Тогда существует последовательность , такая что:
 
  | 
|  
 Выберем некоторые , таким образом, чтобы . Предположим, что мы выбрали . Тогда . Всего недопустимых значений для , поэтому всегда можно найти хотя бы одно значение. Чтобы получить , выбираем каждый раз наименьшее и прибавляем подходящее число кратное , такое что . | 
Первые два условия необходимы для того, чтобы сохранить все существенные биты в нужном порядке. Третье условие позволит поместить sketch узла в w-битный тип. Так как , то будет занимать бит.
Индекс наиболее значащего бита
Чтобы найти в w-битном числе индекс самого старшего бита, содержащего единицу, разделим на блоков по бит. . Далее найдем первый непустой блок и индекс первого единичного бита в нем.
1) Поиск непустых блоков.
a. Определим, какие блоки имеют единицу в первом бите. Применим побитовое & к и константе .
b. Определим, содержат ли остальные биты единицы. 
Вычислим .
Вычтем из . Если какой-нибудь бит  обнулится, значит, соответствующий блок содержит единицы.
Чтобы найти блоки, содержащие единицы, вычислим .
c. Первый бит в каждом блоке  содержит единицу, если соответствующий блок  ненулевой.
2) Найдем , чтобы сместить все нужные биты в один блок. Существенными битами в данном случае будут первые биты каждого блока, поэтому . 
Будем использовать . Тогда . Все суммы различны при . Все возрастают, и .
Чтобы найти , умножим на и сдвинем вправо на бит.
3) Найдем первый ненулевой блок. Для этого надо найти первую единицу в . Как и при поиске и используем параллельное сравнение с . В результате сравнения получим номер первого ненулевого блока .
4) Найдем номер первого единичного бита в найденном блоке так же как и в предыдущем пункте.
5) Индекс наиболее значащего бита будет равен .
Каждый шаг выполняется за , поэтому всего потребуется времени, чтобы найти индекс.
Циклы де Брёйна
Последовательность де Брёйна — последовательность , элементы которой принадлежат заданному конечному множеству (обычно рассматривают множество ), и все подпоследовательности заданной длины различны.
Часто рассматриваются периодические последовательности с периодом , содержащие различных подпоследовательностей , — то есть такие периодические последовательности, в которых любой отрезок длины является последовательностью де Брёйна с теми же параметрами и .
Свойства
Очевидно, что длина (период) такого цикла не может превосходить — числа́ всех различных векторов длины с элементами из ; несложно доказать, что эта оценка достигается. Циклы этой максимально возможной длины обычно называют циклами де Брёйна (впрочем, иногда этот термин применяют и к циклам меньшей длины).
При существуют такие циклы де Брёйна с длиной, на единицу меньшей максимума, которые выражаются линейными рекуррентными соотношениями порядка : так, при соотношение порождает последовательности с периодом 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
 
Граф де Брёйна
Существует удобная интерпретация последовательностей и циклов де Брёйна, основанная на так называемом графе де Брёйна — ориентированном графе с вершинами, соответствующими различных наборов длины с элементами из , в котором из вершины в вершину ребро ведёт в том и только том случае, когда (); при этом самому ребру можно сопоставить набор длины : . Для такого графа не проходящие дважды через одно и то же ребро эйлеровы пути (эйлеровы циклы) соответствуют последовательности (циклу) де Брёйна с параметрами и , а не проходящие дважды через одну и ту же вершину гамильтоновы пути (гамильтоновы циклы) — последовательности (циклу) де Брёйна с параметрами и .
Граф де Брёйна широко применяется в биоинформатике в задачах сборки генома.
См. Также