Динамическая выпуклая оболочка (достаточно log^2 на добавление/удаление) — различия между версиями
Dima (обсуждение | вклад) (→Левая и правая выпуклые оболочки) |
Dima (обсуждение | вклад) |
||
Строка 19: | Строка 19: | ||
Основная идея алгоритма заключается в эффективном (за <tex>O(\log{n})</tex>) отыскании моста, соединяющего две такие оболочки. | Основная идея алгоритма заключается в эффективном (за <tex>O(\log{n})</tex>) отыскании моста, соединяющего две такие оболочки. | ||
+ | |||
+ | == Структура данных == | ||
+ | |||
+ | Будем хранить отсортированные лексикографически (<tex>p < q \Leftrightarrow p_y < q_y \lor p_y = q_y \land p_x < q_x</tex>) точки в листьях сбалансированного бинарного дерева поиска (например, [[Красно-черное дерево|красно-черного]] или [[АВЛ-дерево|AVL]]). Во внутренних вершинах будем хранить вспомогательную информацию: во-первых, наименьшую точку в поддереве с корнем в данной вершине; а во-вторых, мост между выпуклыми оболочками точек левого и правого поддеревьев данной вершины. Формально вершина дерева описывается так: | ||
+ | |||
+ | '''struct''' bridge | ||
+ | point left | ||
+ | point right | ||
+ | |||
+ | '''struct''' node | ||
+ | node parent, left, right | ||
+ | boolean leaf // true, если лист, иначе false | ||
+ | point p // поле валидно для листа | ||
+ | bridge b // поле валидно для внутренней вершины | ||
{|border="0" cellpadding="5" width=30% align=center | {|border="0" cellpadding="5" width=30% align=center | ||
Строка 40: | Строка 54: | ||
| | | | ||
|} | |} | ||
− | + | ||
− | |||
− | |||
− | |||
== Операции == | == Операции == |
Версия 04:14, 29 марта 2014
Пусть дано множество точек , изначально пустое, и последовательность точек , которые последовательно добавляются или удаляются из (естественно, точка может быть удалена, если она уже принадлежит ). Требуется динамически поддерживать выпуклую оболочку .
В статье описан алгоритм, требующий
времени на добавление/удаление точки.Содержание
Левая и правая выпуклые оболочки
Определим левую (правую) выпуклую оболочку множества точек
, как выпуклую оболочку множества , где . Тогда задачу можно свести к поддержанию отдельно левой и правой выпуклых оболочек. Далее будем рассматривать только динамическое поддержание левой оболочки (далее, для краткости, будем называть её просто выпуклой оболочкой). Заметим также, что точки вдоль выпуклой оболочки отсортированы по ординате.Пусть множество точек
разбито горизонтальной прямой на два множества и . Рассмотрим выпуклые оболочки и . Будем называть мостом (bridge) отрезок общей касательной к этим оболочкам, заключённый между точками касания. Тогда выпуклая оболочка ко всему множеству естественным образом получается объединением частей оболочек и , и моста .Основная идея алгоритма заключается в эффективном (за
) отыскании моста, соединяющего две такие оболочки.Структура данных
Будем хранить отсортированные лексикографически (красно-черного или AVL). Во внутренних вершинах будем хранить вспомогательную информацию: во-первых, наименьшую точку в поддереве с корнем в данной вершине; а во-вторых, мост между выпуклыми оболочками точек левого и правого поддеревьев данной вершины. Формально вершина дерева описывается так:
) точки в листьях сбалансированного бинарного дерева поиска (например,struct bridge point left point right
struct node node parent, left, right boolean leaf // true, если лист, иначе false point p // поле валидно для листа bridge b // поле валидно для внутренней вершины
Операции
Получение выпуклой оболочки
Принадлежность точки выпуклой оболочке
Вставка точки
Вставим точку в дерево, как в обычное сбалансированное дерево поиска. Из-за балансировки мосты в
вершинах дерева могут оказаться неактуальными, поэтому, возвращаясь по пути вверх до корня, будем пересчитывать мосты в таких вершинах методом, описанным выше, пользуясь тем, что всё поддерево рассматриваемой вершины уже содержит корректную информацию. Каждый пересчет моста требует времени, откуда итоговая асимптотика вставки: .Удаление точки
Удаление точки производится по аналогии с вставкой: сначала мы удалим точку из сбалансированного дерева поиска, а затем пересчитаем мосты, хранящиеся в вершинах, которые затронула балансировка. Очевидно, что удаление, как и вставка, работает за
.Источники
- Реализация Антона Ковшарова
- Ф. Препарата, М. Шеймос. Вычислительная геометрия (1989). стр. 151 (тут описан более сложный алгоритм с двухуровневой структурой данных, но с такой же асимптотикой)
- Overmars, M. H.; van Leeuwen, J. (1981), "Maintenance of configurations in the plane" (и тут тоже)