1632
правки
Изменения
м
Пусть <tex>\left \{ a_1,a_2\ldots a_k\right \}</tex> - множество ключей узла, отсортированных по возрастанию, <tex>q</tex> - ключ искомой вершины, <tex>l</tex> - количество бит в <tex>sketch(q)</tex>.
===Succ(sketch(q)) и pred(sketch(q))===
Определим <tex>sketch(node)</tex> как число, составленное из едениц и <tex>sketch(a_i)</tex>, то есть <tex>sketch(node) = 1sketch(a_1)1sketch(a_2)\ldots 1scetch(a_k)</tex>. Вычтем из <tex>sketch(node)</tex> число <tex>shetch(q) * \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>, сохранятся еденицы. Применим к получившемуся побитовое ''AND'' c <tex>\displaystyle \sum_{i=0}^{k-1}2^{i(l+1)+l}</tex>, чтобы убрать лишние биты.
Если <tex>sketch(a_i)< sketch(q)</tex>, то <tex>c_i = 0</tex>, в противном случае <tex>c_i = 1</tex>. Так как ключи отсортированны по возрастанию, получив номер = Индекс наиболее значащего старшего бита, можно найти <tex>succ(sketch(q))</tex>.=с помощью цикла де Брёйна ==Succ(q) и pred(q)===Пусть <tex>sketch(a_i) \leqslant sketch(q) \leqslant sketch(a_{i+1})</tex>. Среди всех ключей наибольший общий префикс с <tex>q</tex> будет иметь или <tex>a_i</tex> или <tex>a_{i+1}</tex>. Сравнивая ''a''XOR''q'' и ''b''XOR''q'', найдем какой из ключей имеет наибольший общий префикс с ''q'' (наименьшнее значение соответствует наибольшей длине).
Предположим, что ''p'Последовательность де Брёйна''' {{--- наибольший общий перфикс}} последовательность <math>a_1, а ''y'' его длина\;\ldots, ''a_j'' - ключ\;a_t</math>, имеющий наибольший общий префикс с ''q'' элементы которой принадлежат заданному конечному множеству (j = i или i+обычно рассматривают множество <math>\{0,\;1). * если ''q>a_j'', то ''y + \;\ldots,\;k-1'' бит ''q'' равен еденице\}</math>), а ''y и все подпоследовательности <math>a_{i+ 1'' бит ''a_j'' равен 0. Так как общий префикс ''a_j'' и ''q'' является наибольшим}, то не существет ключа с префиксом ''p1''.Значит, ''q'' больше всех ключей с префиксом меньшим либо равным ''p''. Найдем pred e = p01\;\ldots 11, который одновременно будет равен pred(q)\;* если a_{i+n}</math> заданной длины <math>n< - найдем succ e = p10\ldots 00. Это будет succ(q)/math> различны.
Длина наибольшего общего префикса двух ''w''-битных чисел ''a'' и ''b'' может быть вычислена с помощью нахождения индекса наиболее значащего бита в побитовом XOR ''a'' и ''b''.==Вычисление sketch(x)==Чтобы найти sketch за константное время, будем вычислять sketch(x), имеющий все существенные биты в нужном порядке, но содержащий лишние нули.Примеры ====
2) умножением на некоторое число <tex>M = \displaystyle\sum_{i=0}^{r-1}2^{m_i}</tex> сместим все существенные биты в блок меньшего размера== Получение индекса по значению степени двойки ====
3==Вычисление sketch(x) применив побитовое AND уберем ==Чтобы найти <tex>sketch</tex> за константное время, будем вычислять <tex>supersketch(x)</tex>, имеющий все существенные биты в нужном порядке, но содержащий лишние нули. Хотя <tex>supersketch</tex> содержит лишние нули, мы сможем вычислять его быстрее, чем обычный <tex>sketch</tex>, потому что нам не придется каждый раз идти по всем битам числа, выбирая стоящие на нужных нам местах. Будем использовать <tex>supersketch</tex> вместо <tex>sketch</tex> {{---}} это никак не повлияет на сравнение, поскольку добавленные биты, появившиеся в результате умножения;равны нулю и стоят на одних и тех же местах для всех <tex>sketch</tex>
4) сделаем сдвиг вправо на <tex>m_0 + b_0</tex> бит.
1)Поиск непустых блоков==См. a. Определим какие блоки имеют еденицу в первом бите. Применим побитовое AND к ''x'' и константой ''F''Также==
<tex> $$\begin{array}{r}AND\begin{array}{r}x = 0101\; 0000\; 1000\; 1101\\F = 1000\; 1000\; 1000\; 1000\\\end{array} \\\hline\begin{array}{r}t_1 = \underline{0}000\; \underline{0}000\; \underline{1}000\; \underline{1}000\end{array}\end{array}$$</tex> b. Определим, содержат ли остальные биты еденицы. *[[:Сверхбыстрый_цифровой_бор|Сверхбыстрый цифровой бор]]
Вычислим <tex>x\; XOR \; t_1</tex>.*[[:2-3_дерево|2-3 дерево]]
<tex> $$\begin{array}{r}XOR\begin{array}{r}t_1 = 0000\; 0000\; 1000\; 1000\\x = 0101\; 0000\; 1000\; 1101\\\end{array} \\\hline\begin{array}{r}t_2 Источники информации == 0\underline{101}\; 0\underline{000}\; 0\underline{000}\; 0\underline{101}\end{array}\end{array}$$</tex>
Вычтем от <tex>F\; t_2<* [http:/tex>/www.sciencedirect.com/science/article/pii/0022000093900404 M. L. Fredman and D. E. Если какой-нибудь бит ''F'' обнулитсяWillard. Surpassing the information theoretic barrier with fusion trees. Journal of Computer and System Sciences, значит, соответствующий блок содержит еденицы.1993]
<tex> $$\begin{array}{r}-\begin{array}{r}F = 1000\; 1000\; 1000\; 1000\\t_2 = 0\underline{101}\; 0\underline{000}\; 0\underline{000}\; 0\underline{101}\\\end{array} \\\hline\begin{array}{r}t_3 = \underline{0}xxx\; \underline{1}000\; \underline{1}000\; \underline{0}xxx\end{array}\end{array}$$<* [http:/tex>/courses.csail.mit.edu/6.897/spring03/scribe_notes/L4/lecture4.pdf MIT CS 6.897: Advanced Data Structures: Lecture 4, Fusion Trees, Prof. Erik Demaine (Spring 2003)]
Чтобы найти блоки* [http://courses.csail.mit.edu/6.851/spring12/scribe/lec12.pdf MIT CS 6.851: Advanced Data Structures: Lecture 12, содержащие еденицыFusion Tree notes, вычислим <tex>t_3\; XOR \; F</tex>Prof.Erik Demaine (Spring 2012)]
<tex> $$\begin{array}{r}XOR\begin{array}{r}F * [http://www.lektorium.tv/lecture/?id= 1000\; 1000\; 1000\; 1000\\t_3 = \underline{0}xxx\; \underline{1}000\; \underline{1}000\; \underline{0}xxx\\\end{array} \\\hline\begin{array}{r}t_4 = \underline{1}000\; \underline{0}000\; \underline{0}000\; \underline{1}000\end{array}\end{array}$$</tex>14292 А.С. Станкевич. Дополнительные главы алгоритмов, лекция 6]
Первый бит в каждом блоке <tex>y = t_1\; OR \;t_4<* [http:/tex> содержит еденицу, если соответствующий блок ''x'' ненулевой/en.wikipedia.org/wiki/Fusion_tree Wikipedia — Fusion tree]
<tex>$$\begin{array}{r}OR\begin{array}{r}t_1 = \underline{0}000\; \underline{0}000\; \underline{1}000\; \underline{1}000\\t_4 = \underline{1}000\; \underline{0}000\; \underline{0}000\; \underline{1}000\\\end{array} \\* [https://en.wikipedia.org/wiki/De_Bruijn_sequence Wikipedia — De Bruijn sequence]\hline[[Категория:Дискретная математика и алгоритмы]]\begin{array}{r}[[Категория:Деревья поиска]]y = \underline{1}000\; \underline{0}000\; \underline{1}000\; \underline{1}000\end{array}\end{array}$$</tex>[[Категория:Структуры данных]]
rollbackEdits.php mass rollback
'''Fusion tree''' {{---}} дерево поиска, позволяющее хранить <tex>n</tex> <tex>w</tex>-битных положительных чисел, используя <tex>O(n)</tex> памяти, и выполнять операции поиска за время <tex>O(\log_{w} n)</tex>. Это статическая структура данных, которая была впервые предложена в 1990 году М. Фредманом (M. Fredman) и Д. Уиллардом (D. Willard).
==Структура==
Fusion tree {{---}} это [[B-дерево|B-дерево]], такое что:
* у всех вершин, кроме листьев, <tex>B = w^{1/5}</tex> детей;,* время, за которое определяется , в каком поддереве находится вершина, равно <tex>O(1)</tex>.Такое время работы достигается за счет хранения дополнительной информации в вершинах. Рассмотрим Построим [[:Сверхбыстрый_цифровой_бор|цифровой бор ]] из ключей узла дерева. Всего <tex>B - 1</tex> ветвящихся вершин. Биты, соответствующие уровням дерева, в которых происходит ветвление, назовем существенными и обозначим их номера <tex>b_0, b_1, b_2\ldots b_rb_{r-1}</tex>(индексация идет от листьев, которые соответствуют концу числа, т.е. младшему разряду). Количество существенных битов <tex>r</tex> не больше чем <tex>B - 1</tex>(все ребра на уровне детей ветвящейся вершины {{---}} обведены на рисунке {{---}} являются существенными битами, и так как ветвящихся вершин <tex>B - 1</tex>, значит, и количество уровней с детьми не больше <tex>B - 1</tex>, поскольку на одном уровне могут быть несколько ветвящихся вершин).
[[Файл:Fusion.png||500x400px|center|визуализация функции sketch]] В Fusion tree вместо ключа вместе с ключом <tex>x</tex> хранится <tex>Sketchsketch(x)</tex> {{--- }} последовательность битов <tex>x_{b_rb_{r-1}}\ldots x_{b_1b_0}</tex>. {{Утверждение|id=sketch. |author=|about=|statement=<tex>Sketchsketch</tex> сохраняет порядок, то есть <tex>sketch(x) < sketch(y)</tex>, если <tex>x < y</tex>.|proof=Рассмотрим наибольший общий префикс <tex>x</tex> и <tex>y</tex>. Тогда следующий бит определяет их порядок и одновременно является существенным битом. Поэтому, если <tex>x < y</tex>, то и <tex>sketch(x) < sketch(y)</tex>.}}
==Поиск вершины==
Пусть <tex>\left \{ a_1,a_2\ldots a_B\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>. ===Поиск следующего и предыдущего по sketch=== {{Утверждение|id=prefix. |author=|about=|statement=Среди значений <tex>succ(y)</tex> и <tex>pred(y)</tex> по <tex>sketch(y)</tex> есть <tex>succ</tex> или <tex>pred</tex> по значению <tex>y</tex>.|proof= Рассмотрим <tex>y</tex>. У него есть существенные биты и некоторый элемент <tex>x</tex>, с которым у <tex>y</tex> наибольший общий префикс (настоящий, а не по <tex>sketch</tex>). Биты из <tex>sketch</tex>, находящиеся в префиксе совпадают, значит <tex>succ</tex> и <tex>pred</tex> <tex>y</tex> среди <tex>sketch</tex> должны быть такими же среди <tex>x</tex>, и один из них имеет дальше бит <tex>0</tex> (а другой <tex>1</tex>) и с ним может быть больше других общих бит в <tex>sketch</tex>. То есть либо <tex>succ</tex>, либо <tex>pred</tex> имеют следующий существенный бит такой же, как и у <tex>y</tex>. Поэтому если значение равно <tex>0</tex>, то <tex>x</tex> наибольший среди значений с меньшим <tex>sketch</tex>, и, аналогично для <tex>1</tex>, наименьший среди больших.}} [[Файл:FusionTree.png|400x400px|thumb|right|Пример случая, когда <tex>sketch(a_i) \leqslant sketch(q) \leqslant sketch(a_{i+1})</tex>, но <tex>a_{i+1}\leqslant q</tex> <tex>sketch(a_i) = 00, sketch(q) = 00, sketch(a_{i+1}) = 01, \\ a_i = 0000, a_{i+1} = 0010, q = 0101</tex> ]] Рассмотрим ключи. Порядок для них по <tex>sketch</tex> совпадает с их порядком. Тогда для некоторых <tex>a_i</tex> и <tex>a_{i+1}</tex>: <tex>sketch(a_i) \leqslant sketch(q) \leqslant sketch(a_{i+1})</tex>, в таком случае <tex>a_i</tex> и <tex>a_{i+1}</tex> его <tex>succ</tex> и <tex>pred</tex> по <tex>sketch</tex>. Тогда среди них есть настоящий (не по <tex>sketch</tex>) <tex>succ</tex> или <tex>pred</tex> по доказанному, а понять это мы можем просто сделав сравнение с <tex>q</tex>. ===Поиск реального следующего и предыдущего===Мы умеем находить реальный <tex>succ</tex> и <tex>pred</tex> по <tex>succ</tex> и <tex>pred</tex> от <tex>sketch(y)</tex>, теперь покажем, как искать <tex>succ</tex> и <tex>pred</tex> от <tex>sketch(y)</tex> за <tex> O(1)</tex>. Определим <tex>sketch(node)</tex> как число, составленное из единиц и <tex>sketch(a_i)</tex>, то есть <tex>sketch(node) = 1sketch(a_1)1sketch(a_2)\ldots 1scetch1sketch(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>\&</tex> c <tex>\displaystyle \sum_{i=0}^{k-1}2^{i(l+1)+l}</tex> ''AND'' , чтобы убрать лишние биты. <tex>L = (1sketch(a_1)\ldots 1sketch(a_k) - 0sketch(q)\ldots 0sketch(q)) \& \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>L</tex>. Умножим <tex>L</tex> на <tex>\underbrace{0\ldots 01}_{l + 1 bits}\ldots \underbrace{0\ldots 01}_{l+1 bits}</tex>, тогда все единицы сложатся в первом блоке результата, и, чтобы получить количество единиц, сдвинем его вправо на <tex>(k-1)\cdot(l + 1)</tex> бит. В таком случае мы получим некоторое <tex>2^i</tex>, где <tex>i</tex> является реальным <tex>pred(x)</tex>, а <tex>i</tex> мы можем получить с помощью цикла де Брёйна
Примеры циклов де Брёйна для <math>k=2</math> с периодом <tex>2, 4, 8, 16</tex>:* <tex>01</tex> (содержит подпоследовательности <tex>0</tex> и <tex>1</tex>) уберем все несущественные биты * <tex>x' = x0011</tex> (содержит подпоследовательности <tex>00, 01, 11, 10</tex>)* <tex>00010111 (000, 001, 010, 101, 011, 111, 110, 100)</tex> AND * <tex>\displaystyle \sum_{i=0}^{r-1}2^{b_i}0000100110101111</tex>;
Возьмем цикл де Брёйна для <tex>n</tex> <tex>x'*M = \displaystyle(\sum_{i=0}^{r\ldots n-1}x_{b_i}2^{b_i})</tex> и запишем его как число <tex>b</tex> (\sum_{iдля <tex>8</tex> цикл де Брёна равен <tex>00010111</tex>, а значение <tex>b =0}23</tex>). Умножим это число на <tex>2^{ri</tex>, сдвинем его влево на <tex>i</tex>, а затем обратно вправо на <tex>n-1}k</tex> (<tex>k</tex> такое, что <tex>n=2^k</tex>). <tex>(b \texttt{m_i<<}i) = \sum_texttt{i=0>>}^{r(n-1}\sum_k)</tex>), тогда получившееся число {j=0}^{r-1--}x_{b_i}<tex>i</tex>-ая подстрока длины <tex>k</tex> данного цикла де Брёйна. Эту перестановку опозначим за <tex>p</tex> и тогда применив ее к <tex>(2^i\cdot x) \texttt{b_i+m_j>>}(n-k))</tex> получим <tex>i</tex>: <tex>p</tex> в данном случае такое, что <tex>k</tex>;подряд идущих бит равны значению, на сколько мы сдвинули.
# Уберем все несущественные биты <tex>x' = x \& \displaystyle\sum_{i=0}^{r-1}2^{b_i}</tex>.# Умножением на некоторое заранее вычисленное число <tex>M = \displaystyle\sum_{i=0}^{r-1}2^{m_i}</tex> сместим все существенные биты в блок меньшего размера: <tex>x'\times M = \displaystyle \left( \sum_{i=0}^{r-1}x_{b_i} 2^{b_i} \right) \left(\sum_{i=0}^{r-1}2^{m_i}\right) = \sum_{i=0}^{r-1}\sum_{j=0}^{r-1}x_{b_i}2^{b_i+m_j}</tex> AND .# Применив побитовое <tex>\&</tex>, уберем лишние биты, появившиеся в результате умножения: <tex>\left(\displaystyle\sum_{i=0}^{r-1}\sum_{j=0}^{r-1}x_{b_i} 2^{b_i+m_j} \right) \& \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>;.# Сделаем сдвиг вправо на <tex>m_0 + b_0</tex> бит.
{{Утверждение
|id=
|author=
|about=
|statement=Дана последовательность из <tex>r </tex> чисел <tex>b_0<b_1<\ldots <b_{r-1}</tex>. Тогда существует последовательность <tex>m_0<m_1\ldots <m_{r-1}</tex>, такая что: 1) # все <tex>b_i + m_j</tex> различны, для <tex>0\leqslant i,j \leqslant r-1</tex>; 2) # <tex>b_1 b_0 + m_2m_0\leqslant b_2 b_1 + m_2m_1\leqslant \ldots \leqslant b_{r-1} + m_{r-1}</tex>; 3) # <tex>(b_{r-1} + m_{r-1}) - (b_0 + m_0) \leqslant r^4</tex>.
|proof=
Выберем некоторые<tex>m_i'</tex>, таким образом, чтобы<tex>m_i' + b_k \not\equiv m_j' + b_p</tex>. Предположим, что мы выбрали<tex>m_1' \ldots m_{t-1}'</tex>. mtТогда <tex>m_t' != mi\ne m_i' + bj b_j - bk A b_k \; \forall i,j,k. В противном случае </tex>. Всего <tex>t*\times r*\times r <= r^3 </tex> недопустимых значений для mt<tex>m_t'</tex>, поэтому всегда можно найти хотя бы одно значение.
Чтобы получить mi<tex>m_i</tex>, выбираем каждый раз наименьшие miнаименьшее <tex>m_i' </tex> и прибавляем подходящее число кратное <tex>r^3</tex>, такое что mi<tex>m_i+cic_i <mim_{i+l1}+Cic_{i+l<=mi1} \leqslant m_i+cic_i+r3r^3</tex>.
}}
Первые два условия необходимы для того, чтобы сохранить все существенные биты в нужном порядке. Третье условие позволит поместить <tex>sketch </tex> узла в <tex>w</tex>-битный тип. Так как <tex>r<=\leqslant B-1</tex>, то <tex>sketch(node) </tex> будет занимать <tex>B*(r*^4 + 1) <= \leqslant B*((B-1)^4 + 1) <= B((B^2 - 2B + 1)^5 2 + 1)= </tex><tex>B(wB^4 + 4B^2 + 1 - 4B^3 + 2B^{2 -4B + 1/5})= B^5 = w бит.==Индекс наиболее значащего бита==Чтобы найти в w-битном числе ''x'' индекс самого старшего бита, содержащего еденицу, разделим ''x'' на <tex>4B^3 + 6B^2 - 4B + 2 \sqrt{w}leqslant B^5 </tex> блоков по <tex>\sqrt= (w^{1/5})^5 = w}</tex> бит., при всех <tex>x = B \underbrace{0101}_{\sqrt{w}}\; \underbrace{0000}_{\sqrt{w}}\; \underbrace{1000}_{\sqrt{w}}\; \underbrace{1101}_{\sqrt{w}}geqslant 1</tex>. Далее найдем первый непустой блок и индекс первого еденичного бита в нем.