Техника частичного каскадирования — различия между версиями
(Закончено описание "Ответ на запрос", исправлены недопонимания с головой. Исправлены пункты 1, 2, 5, 7, 8, 12) |
(Добавлена часть псевдокода не в tex) |
||
Строка 36: | Строка 36: | ||
* 1) Мы можем проводить ссылки из каталога номер <tex> i </tex> в <tex> (i + 1) </tex>-ый каталог таким образом, что разница между элементами, соединенными ссылками минимальна, что, очевидно, в некоторых случаях уменьшит время поиска. <br> | * 1) Мы можем проводить ссылки из каталога номер <tex> i </tex> в <tex> (i + 1) </tex>-ый каталог таким образом, что разница между элементами, соединенными ссылками минимальна, что, очевидно, в некоторых случаях уменьшит время поиска. <br> | ||
* 2) Мы можем для оптимизации пункта 1 создать модифицированные каталоги <tex> M_i </tex>, где <tex> i </tex>-ый каталог будет представлять каталог <tex> C_i </tex> слитый с <tex> M_{i + 1} </tex> | * 2) Мы можем для оптимизации пункта 1 создать модифицированные каталоги <tex> M_i </tex>, где <tex> i </tex>-ый каталог будет представлять каталог <tex> C_i </tex> слитый с <tex> M_{i + 1} </tex> | ||
− | |||
− | === Построение === | + | === Построение === |
− | |||
Введем определения: | Введем определения: | ||
{{Определение | {{Определение | ||
Строка 60: | Строка 58: | ||
<br> <tex> C_5 = \{1, 2, 4, 6, 9\} </tex> | <br> <tex> C_5 = \{1, 2, 4, 6, 9\} </tex> | ||
<br> Для наглядности заведем таблицу, где в <tex>i</tex>-ой строке <tex> j </tex>-ая ячейка будет окрашена в зеленый цвет, если она присутствует в каталоге <tex> C_i </tex>. Тогда результатом построения будет таблица, которая представлена на рисунке. | <br> Для наглядности заведем таблицу, где в <tex>i</tex>-ой строке <tex> j </tex>-ая ячейка будет окрашена в зеленый цвет, если она присутствует в каталоге <tex> C_i </tex>. Тогда результатом построения будет таблица, которая представлена на рисунке. | ||
− | + | <br> | |
+ | Из-за необходимости хранения ссылок будет удобно завести структуру для хранения элементов в модифицированных каталогах. | ||
+ | struct node : | ||
+ | element key | ||
+ | node *left, *right, *down | ||
+ | bool is_alien | ||
=== Ответ на запрос === | === Ответ на запрос === | ||
В первом каталоге ответ на запрос найдем с помощью бинарного поиска по <tex> C_1 </tex>. Пусть ответом для этого каталога будет ячейка <tex> cell </tex>. Далее проитерируемся по оставшимся каталогам. Для того, чтобы перейти в новый ''модифицированный каталог'' мы перейдем из <tex> cell </tex> по ссылке влево, чтобы попасть в ''подставную вершину'', а потом из нее перейдем по ссылке вниз, чтобы попасть в следующий каталог. Если теперь <tex> cell </tex> {{---}} ''неподставная вершина'', то нам достаточно рассмотреть двух ее соседей справа в <tex> C_i </tex>, так как <tex> cell.key < x </tex>, а каждая вторая ячейка из <tex> M_i </tex> попадает в <tex> M_{i - 1} </tex>, т.е. мы бы встретили ее ранее и перешли мы вниз по ней, но это не случилось. Обновив cell максимальным из подходящих значений нужно проверить, является ли она ''подставным элементом'', если да, то перейдем по ссылке влево, попав в ответ для текущего каталога, иначе это и будет ответ. | В первом каталоге ответ на запрос найдем с помощью бинарного поиска по <tex> C_1 </tex>. Пусть ответом для этого каталога будет ячейка <tex> cell </tex>. Далее проитерируемся по оставшимся каталогам. Для того, чтобы перейти в новый ''модифицированный каталог'' мы перейдем из <tex> cell </tex> по ссылке влево, чтобы попасть в ''подставную вершину'', а потом из нее перейдем по ссылке вниз, чтобы попасть в следующий каталог. Если теперь <tex> cell </tex> {{---}} ''неподставная вершина'', то нам достаточно рассмотреть двух ее соседей справа в <tex> C_i </tex>, так как <tex> cell.key < x </tex>, а каждая вторая ячейка из <tex> M_i </tex> попадает в <tex> M_{i - 1} </tex>, т.е. мы бы встретили ее ранее и перешли мы вниз по ней, но это не случилось. Обновив cell максимальным из подходящих значений нужно проверить, является ли она ''подставным элементом'', если да, то перейдем по ссылке влево, попав в ответ для текущего каталога, иначе это и будет ответ. | ||
+ | |||
+ | node cell = binary_search(M[1], x) | ||
+ | if (cell.is_alien) | ||
+ | cell = cell.left | ||
+ | ans[1] = cell.key; | ||
+ | '''for''' i = 2 '''to''' k | ||
+ | cell = cell.left.down | ||
+ | if (cell.right <= x) | ||
+ | cell = cell.right | ||
+ | if (cell.right <= x) | ||
+ | cell = cell.right | ||
+ | if (cell.is_alien) | ||
+ | cell = cell.left | ||
+ | ans[i] = cell.key |
Версия 23:08, 7 июня 2017
Определение: |
Каталог (англ. catalog)— упорядоченный массив из элементов, на которых введено отношение порядка. В данной статье предполагается, что массив упорядочен по неубыванию. |
Определение: |
Техника частичного каскадирования (англ. fractional cascading technique) — это способ организации структуры данных, который предназначен для быстрого итеративного поиска в | каталогах.
Задача: |
Дано | каталогов , каталог имеет размер . Поступают запросы, которые представляют собой один элемент . Требуется для каждого запроса определить в каждом каталоге максимальный элемент меньше либо равный .
Содержание
Различные подходы к решению
Пусть
1) Для ответа на запрос последовательно посетим все каталоги. Пусть мы находимся в -ом каталоге, тогда мы можем ответить на запрос для данного каталога за , используя бинарный поиск. Так как каталогов штук, то для ответа на запрос понадобится времени. Для хранения всех каталогов понадобится памяти.
2) Для второго способа построим сбалансированное бинарное дерево поиска из всех элементов всех каталогов. В каждой вершине дерева будет хранится дополнительно кортеж из элементов — максимальных представителей каталогов меньше либо равных ключу вершины. Таким образом такая структура будет занимать на дерево поиска и на дополнительные кортежи.Тогда для ответа на запрос найдем в дереве поиска максимальный ключ меньше либо равный и выведем элементов соответствующего кортежа, итого ответ на запрос производится за .
Итого имеем:
Тип подхода к решению | Необходимая память | Время ответа на один запрос |
---|---|---|
|
|
|
|
|
|
Решение с помощью техники частичного каскадирования
Как будет показано далее, эта техника берет лучшее от подходов к решению этой задачи, что были рассмотрены выше, а именно она требует
Идея данной техники построена на следующем:
- 1) Мы можем проводить ссылки из каталога номер
- 2) Мы можем для оптимизации пункта 1 создать модифицированные каталоги , где -ый каталог будет представлять каталог слитый с
Построение
Введем определения:
Определение: |
Подставной элемент — элемент каталога | , который пришел из каталога . А также каталоги будем называть модифицированными каталогами.
Первый этап построения:
- : Данный каталог не имеет никаких ссылок и равен .
- : Для построения данного каталога будем сливать каталог с каждым вторым элементом каталога . Каждый элемент из каталога оснастим ссылкой на позицию, откуда мы его взяли, такие ссылки будет называть ссылками вниз.
Второй этап построения:
В каждом модифицированном каталоге для каждого элемента заведем две ссылки. Для неподставных элементов это будут ссылки на максимальныйподставной элемент меньше текущего и на минимальный любого типа больше текущего. Если элемент подставной, то ссылки будут на минимальный неподставной элемент" больше текущего и на максимальный неподставной элемент меньше текущего. Назовем их ссылками влево и вправо.
Рассмотрим на процесс построения на примере.
Пусть дано каталогов:
Для наглядности заведем таблицу, где в -ой строке -ая ячейка будет окрашена в зеленый цвет, если она присутствует в каталоге . Тогда результатом построения будет таблица, которая представлена на рисунке.
Из-за необходимости хранения ссылок будет удобно завести структуру для хранения элементов в модифицированных каталогах.
struct node : element key node *left, *right, *down bool is_alien
Ответ на запрос
В первом каталоге ответ на запрос найдем с помощью бинарного поиска по
. Пусть ответом для этого каталога будет ячейка . Далее проитерируемся по оставшимся каталогам. Для того, чтобы перейти в новый модифицированный каталог мы перейдем из по ссылке влево, чтобы попасть в подставную вершину, а потом из нее перейдем по ссылке вниз, чтобы попасть в следующий каталог. Если теперь — неподставная вершина, то нам достаточно рассмотреть двух ее соседей справа в , так как , а каждая вторая ячейка из попадает в , т.е. мы бы встретили ее ранее и перешли мы вниз по ней, но это не случилось. Обновив cell максимальным из подходящих значений нужно проверить, является ли она подставным элементом, если да, то перейдем по ссылке влево, попав в ответ для текущего каталога, иначе это и будет ответ.node cell = binary_search(M[1], x) if (cell.is_alien) cell = cell.left ans[1] = cell.key; for i = 2 to k cell = cell.left.down if (cell.right <= x) cell = cell.right if (cell.right <= x) cell = cell.right if (cell.is_alien) cell = cell.left ans[i] = cell.key