Верхнее дерево — это структура данных, основанная на двоичном дереве для некорневых динамических деревьев , которая используется в основном для различных операций, связанных с путями. Она позволяет использовать простые алгоритмы «разделяй и властвуй» . С тех пор она была расширена для динамического поддержания различных свойств дерева, таких как диаметр, центр и медиана.
Верхнее дерево определяется для базового дерева и набора из не более чем двух вершин, называемых внешними граничными вершинами.
Глоссарий
Граничный узел
См. Граничную вершину
Граничная вершина
Вершина в связанном поддереве является граничной вершиной, если она соединена с вершиной вне поддерева ребром.
Внешние граничные вершины
До пары вершин в верхнем дереве можно назвать внешними граничными вершинами, их можно рассматривать как граничные вершины кластера, представляющего все верхнее дерево.
Кластер
Кластер — это связанное поддерево с максимум двумя граничными вершинами. Набор граничных вершин данного кластера обозначается как
С каждым кластером пользователь может связать некоторую метаинформацию и указать методы для ее поддержания в рамках различных внутренних операций.
Путь Кластера
Если содержит хотя бы одно ребро, то это называется кластером путей .
Точечный кластер
См. кластер листьев
Скопление листьев
Если кластер не содержит ни одного ребра, т.е. имеет только одну граничную вершину, то он называется листовым кластером .
Крайний кластер
Кластер, содержащий одно ребро, называется краевым кластером .
Кластер края листа
Лист в исходном кластере представлен кластером с единственной граничной вершиной и называется кластером граничных листьев .
Кластер края пути
Краевые кластеры с двумя граничными узлами называются краевыми кластерами пути .
Внутренний узел
Узел в \ называется внутренним узлом
Путь кластера
Путь между граничными вершинами называется кластерным путем и обозначается как
Объединяемые кластеры
Два кластера и являются объединяемыми, если — одноэлементный набор (у них есть ровно один общий узел), а — кластер.
Введение
Верхние деревья используются для поддержания динамического леса (набора деревьев) при операциях по связыванию и рубке.
Основная идея заключается в поддержании сбалансированного бинарного дерева логарифмической высоты по числу узлов в исходном дереве (т.е. по времени); верхнее дерево по сути представляет собой рекурсивное подразделение исходного дерева на кластеры.
В целом дерево может иметь нагрузку на края.
Существует однозначное соответствие между ребрами исходного дерева и конечными узлами верхнего дерева , а каждый внутренний узел представляет собой кластер, образованный в результате объединения кластеров, являющихся его дочерними узлами.
Структура данных верхнего дерева может быть инициализирована вовремя .
Следовательно, верхнее дерево над ( ) является бинарным деревом, таким что
Узлы представляют собой кластеры ( );
Листья - это края
Родственные кластеры являются соседями в том смысле, что они пересекаются в одной вершине, а их родительский кластер является их объединением.
Корнем является само дерево с набором из не более чем двух внешних граничных вершин.
Дерево с одной вершиной имеет пустую вершину, а дерево с одним ребром — всего один узел.
Эти деревья можно свободно дополнять, что обеспечивает пользователю большую гибкость и производительность, не вдаваясь в детали внутренней работы структуры данных, которую также называют « черным ящиком» .
Динамические операции
Ниже приведены три допустимых пользователем обновления леса.
Link(v, w): где и являются вершинами в разных деревьях 1 и 2. Возвращает одно верхнее дерево, представляющее v w
Cut(v, w) : удаляет ребро из дерева с верхним деревом, тем самым превращая его в два дерева v и w и возвращая два верхних дерева v и w .
Expose(S) : Вызывается как подпрограмма для реализации большинства запросов на верхнем дереве. Содержит не более 2 вершин. Он делает исходные внешние вершины обычными вершинами и делает вершины из новых внешних граничных вершин верхнего дерева. Если непусто, он возвращает новый корневой кластер с Expose({v,w}) завершается неудачей, если вершины принадлежат разным деревьям.
Внутренние операции
Все обновления леса выполняются последовательностью не более чем внутренних операций, последовательность которых вычисляется в дальнейшем времени. Может случиться, что во время обновления дерева кластер листьев может измениться на кластер путей и наоборот. Обновления верхнего дерева выполняются исключительно этими внутренними операциями.
Обновление выполняется путем вызова пользовательской функции, связанной с каждой внутренней операцией.
Слияние Здесь и являются объединяемыми кластерами , он возвращает как родительский кластер и и с граничными вершинами в качестве граничных вершин Вычисляет с помощью и
Разделить Вот корневой кластер Он обновляет и использует , а затем удаляет кластер из .
Split обычно реализуется с помощью метода Clean , который вызывает пользовательский метод для обновлений и с помощью обновлений и таким образом, что становится известно, что в его дочерних элементах нет необходимости в ожидающем обновлении. Затем отбрасывается без вызова пользовательских функций. Clean часто требуется для запросов без необходимости Split . Если Split не использует подпрограмму Clean, а Clean требуется, его эффект может быть достигнут с накладными расходами путем объединения Merge и Split .
Следующие две функции аналогичны двум предыдущим и используются для базовых кластеров.
Создать Создает кластер для ребра . Наборы вычисляются с нуля.
Eradicate — это краевой кластер. Для обработки вызывается определяемая пользователем функция , после чего кластер удаляется из верхнего дерева.
Нелокальный поиск
Пользователь может определить операцию Choose , которая для корневого (нелистового) кластера выбирает один из его дочерних кластеров. Черный ящик верхнего дерева предоставляет процедуру Search , которая организует запросы Choose и реорганизацию верхнего дерева (используя внутренние операции) таким образом, что оно находит единственное ребро в пересечении всех выбранных кластеров. Иногда поиск должен быть ограничен путем. Для таких целей существует вариант нелокального поиска. Если в корневом кластере есть две внешние граничные вершины , ребро ищется только на пути . Достаточно выполнить следующую модификацию: если только один из дочерних узлов корневого кластера является кластером пути, он выбирается по умолчанию без вызова операции Choose .
Примеры нелокального поиска
Поиск i-го ребра на более длинном пути от до может быть выполнен с помощью =Expose({v,w}) с последующим Search( ) с соответствующим Choose . Для реализации Choose мы используем глобальную переменную, представляющую , и глобальная переменная, представляющая Choose, выбирает кластер с , если длина не менее . Для поддержки операции длина должна поддерживаться в .
Аналогичную задачу можно сформулировать для графа с ребрами неединичной длины. В этом случае расстояние может относиться к ребру или вершине между двумя ребрами. Мы могли бы определить Choose таким образом, чтобы в последнем случае возвращалось ребро, ведущее к вершине. Можно было бы определить update, увеличивающее все длины ребер вдоль пути на константу. В таком сценарии эти обновления выполняются за постоянное время только в корневом кластере. Clean требуется для распространения отложенного обновления на потомков. Clean следует вызывать до вызова Choose . Для поддержания длины в в этом случае потребуется также поддерживать единичную длину в .
Поиск центра дерева, содержащего вершину, может быть выполнен путем поиска либо бицентрического ребра, либо ребра с центром в качестве одной из конечных точек. Ребро может быть найдено с помощью =Expose({v}), за которым следует Search( ) с соответствующим Choose . Выбор выбирает между потомками с потомком с более высоким maxdistance . Для поддержки операции максимальное расстояние в поддереве кластера от граничной вершины должно поддерживаться в . Это также требует поддержания длины пути кластера.
Интересные результаты и приложения
Ряд интересных приложений, изначально реализованных другими методами, были легко реализованы с использованием интерфейса верхнего дерева. Некоторые из них включают
([SLEATOR AND TARJAN 1983]). Мы можем поддерживать динамическую коллекцию взвешенных деревьев во времени для каждой ссылки и разреза, поддерживая запросы о максимальном весе ребра между любыми двумя вершинами во времени.
Схема доказательства: Она включает в себя поддержание в каждом узле максимального веса (max_wt) на его кластерном пути, если это точечный кластер, то max_wt( ) инициализируется как Когда кластер является объединением двух кластеров, то это максимальное значение двух объединенных кластеров. Если нам нужно найти максимальный вес между и , то мы делаем Expose и сообщаем max_wt
([SLEATOR AND TARJAN 1983]). В сценарии вышеприведенного приложения мы также можем добавить общий вес ко всем ребрам на заданном пути · · · во времени.
Схема доказательства: Мы вводим вес, называемый extra( ), который добавляется ко всем ребрам в , который поддерживается соответствующим образом; split( ) требует, чтобы для каждого дочернего пути мы установили max_wt(A) := max_wt( ) + extra( ) и extra( ) := extra( ) + extra( ). Для := join( ) мы устанавливаем max_wt( ) := max {max_wt( ), max_wt( )} и extra( ) := 0. Наконец, чтобы найти максимальный вес на пути · · · мы устанавливаем := Expose и возвращаем max_wt( ).
([GOLDBERG ET AL. 1991]). Мы можем запросить максимальный вес в базовом дереве, содержащем заданную вершину во времени.
Схема доказательства: Для этого требуется сохранение дополнительной информации о максимальном весе некластерного пути-ребра в кластере при операциях слияния и разделения.
Расстояние между двумя вершинами можно найти за время как length(Expose ).
Схема доказательства: Мы будем поддерживать длину length( ) кластерного пути. Длина поддерживается как максимальный вес, за исключением того, что если создается с помощью join(Merge), length( ) является суммой длин, сохраненных с его потомками пути.
Запросы относительно диаметра дерева и его последующего ухода требуют времени.
Центр и медиану можно сохранить с помощью операций «Связать» (Объединить) и «Разделить» (Разделить) и запросить с помощью нелокального поиска во времени.
Верхние деревья используются в современных алгоритмах для динамической двухреберной связности . В этой задаче, аналогично динамической связности , граф подвергается удалению и вставке ребер, а также запросам, спрашивающим, являются ли пара вершин двухреберно связанными или есть мост, разделяющий их. Холм, де Лихтенберг и Торуп [1] дают детерминированный алгоритм с амортизированным временем обновления и временем запроса. Последующая работа Холма, Ротенберга и Торупа улучшает его до амортизированного времени обновления , также используя верхние деревья [2] [3]
Граф можно поддерживать, позволяя обновлять набор ребер и задавать запросы на связность вершины 2. Амортизированная сложность обновлений составляет . Запросы можно реализовать еще быстрее. Алгоритм нетривиальный, использует пространство. [4]
Верхние деревья можно использовать для сжатия деревьев способом, который никогда не будет намного хуже сжатия DAG , но может быть экспоненциально лучше. [5]
Выполнение
Деревья вершин были реализованы различными способами, некоторые из них включают реализацию с использованием многоуровневого разбиения (Алгоритмы деревьев вершин и динамических графов Якоба Хольма и Кристиана де Лихтенберга. Технический отчет) и даже с использованием деревьев Слейтора-Тарьяна (обычно с амортизированными временными ограничениями), деревьев топологии Фредериксона (с наихудшими временными ограничениями) (Альструп и др., Поддержание информации в полностью динамических деревьях с помощью деревьев вершин).
Амортизированные реализации более просты и имеют небольшие мультипликативные факторы временной сложности. Напротив, реализации в худшем случае позволяют ускорить запросы, отключая ненужные обновления информации во время запроса (реализуется методами сохранения ). После ответа на запрос используется исходное состояние верхнего дерева, а версия запроса отбрасывается.
Использование многоуровневого разбиения
Любое разбиение кластеров дерева может быть представлено Cluster Partition Tree CPT путем замены каждого кластера в дереве ребром. Если мы используем стратегию P для разбиения , то CPT будет CPT P Это делается рекурсивно, пока не останется только одно ребро.
Мы бы заметили, что все узлы соответствующего верхнего дерева однозначно отображаются в рёбра этого многоуровневого разбиения. В многоуровневом разбиении могут быть некоторые рёбра, которые не соответствуют ни одному узлу в верхнем дереве, это рёбра, которые представляют только одного потомка на уровне ниже, т. е. простой кластер. Только рёбра, соответствующие составным кластерам, соответствуют узлам в верхнем дереве
Стратегия разбиения важна, когда мы разбиваем дерево на кластеры. Только тщательная стратегия гарантирует, что мы придем к многоуровневому разделу высоты (и, следовательно, к верхнему дереву).
Количество ребер на последующих уровнях должно уменьшаться на постоянный коэффициент.
Если более низкий уровень изменяется в результате обновления, то мы должны иметь возможность обновить тот, который находится непосредственно над ним, используя максимум постоянное число вставок и удалений.
Описанная выше стратегия разбиения обеспечивает поддержание главного дерева в актуальном состоянии.
Стивен Альструп, Джейкоб Холм, Кристиан Де Лихтенберг и Миккель Торуп , Поддержание информации в полностью динамических деревьях с верхними деревьями , Транзакции ACM в алгоритмах (TALG), Vol. 1 (2005), 243–264, номер документа : 10.1145/1103963.1103966.
Стивен Альструп, Якоб Холм, Кристиан Де Лихтенберг и Миккель Торуп , Полилогарифмические детерминированные полностью динамические алгоритмы для связности, минимального остовного дерева, 2-ребер и бисвязности , Журнал ACM, т. 48, выпуск 4 (июль 2001 г.), 723–760, doi :10.1145/502090.502095
^ Холм, Дж.; Де Лихтенберг, К.; Торуп, М. (2001). «Полилогарифмические детерминированные полностью динамические алгоритмы для связности, минимального остовного дерева, 2-ребра и бисвязности». Журнал ACM . 48 (4): 723. doi :10.1145/502090.502095. S2CID 7273552.
^ Торуп, Миккель (2000), «Почти оптимальная полностью динамическая связность графа», Труды тридцать второго ежегодного симпозиума {ACM} по теории вычислений
^ Холм, Якоб; Ротенберг, Ева; Торуп, Миккель (2018), «Динамический поиск мостов в амортизированном времени», Труды двадцать девятого ежегодного симпозиума {ACM-SIAM} по дискретным алгоритмам, {SODA} 2018 , doi : 10.1137/1.9781611975031.3 , S2CID 33964042
^ Холм, Дж.; Де Лихтенберг, К.; Торуп, М. (2001). «Полилогарифмические детерминированные полностью динамические алгоритмы для связности, минимального остовного дерева, 2-ребра и бисвязности». Журнал ACM . 48 (4): 723. doi :10.1145/502090.502095. S2CID 7273552.