Алгоритм Бентли – Оттмана - Bentley–Ottmann algorithm

В вычислительная геометрия, то Алгоритм Бентли – Оттмана это алгоритм линии развертки для перечисления всех переходы в наборе линейных сегментов, т.е. находит точки пересечения (или просто перекрестки) отрезков. Это расширяет Алгоритм Шамоса – Хои,[1] аналогичный предыдущий алгоритм для проверки наличия пересечений у набора отрезков. Для входа, состоящего из отрезки с пересечений (или пересечений) алгоритм Бентли – Оттмана требует времени . В случаях, когда , это усовершенствование наивного алгоритма, который проверяет каждую пару сегментов, что требует .

Первоначально алгоритм был разработан Джон Бентли и Томас Оттманн (1979 ); более подробно описано в учебниках Препарата и Шамос (1985), О'Рурк (1998), и де Берг и др. (2000). Несмотря на то что асимптотически более быстрые алгоритмы теперь известны Шазель и Эдельсбруннер (1992) и Балабан (1995), алгоритм Бентли – Оттмана остается практичным выбором из-за его простоты и низких требований к памяти.[нужна цитата ].

Общая стратегия

Основная идея алгоритма Бентли – Оттмана заключается в использовании линия развертки подход, при котором вертикальная линия L перемещается слева направо (или, например, сверху вниз) по плоскости, последовательно пересекая входные линейные сегменты по мере своего движения.[2] Алгоритм проще всего описать в общая позиция, смысл:

  1. Нет двух конечных точек или пересечений линейных сегментов, имеющих одинаковые Икс-координат
  2. Конечная точка линейного сегмента не лежит на другом линейном сегменте
  3. Три отрезка прямых не пересекаются в одной точке.

В таком случае, L всегда будет пересекать сегменты входной линии в наборе точек, чей вертикальный порядок изменяется только в конечном наборе дискретных События. В частности, дискретное событие может быть связано либо с конечной точкой (левой или правой) линейного сегмента, либо с точкой пересечения двух линейных сегментов. Таким образом, непрерывное движение L может быть разбит на конечную последовательность шагов и смоделирован алгоритмом, работающим за конечное время.

В ходе этого моделирования могут произойти события двух типов. Когда L проходит через конечную точку линейного сегмента s, пересечение L с участием s добавляется или удаляется из вертикально упорядоченного набора точек пересечения. Эти события легко предсказать, поскольку конечные точки известны уже из входных данных алгоритма. Остальные события происходят, когда L проходит через пересечение (или пересечение) двух сегментов линии s и т. Эти события также можно предсказать, исходя из того факта, что непосредственно перед событием точки пересечения L с участием s и т смежны в вертикальном порядке точек пересечения[требуется разъяснение ].

Сам алгоритм Бентли – Оттмана поддерживает структуры данных, представляющие текущий вертикальный порядок точек пересечения линии развертки с входными сегментами линии, а также набор потенциальных будущих событий, образованных смежными парами точек пересечения. Он обрабатывает каждое событие по очереди, обновляя свои структуры данных, чтобы представить новый набор точек пересечения.

Структуры данных

Чтобы эффективно поддерживать точки пересечения линии развертки L с входными линейными сегментами и последовательностью будущих событий алгоритм Бентли – Оттмана поддерживает два структуры данных:

  • А двоичное дерево поиска («дерево состояния линии развертки»), содержащее набор сегментов входной линии, пересекающих Lпо заказу y-координаты точек пересечения этих отрезков L. Сами точки пересечения не явно представлены в двоичном дереве поиска. Алгоритм Бентли – Оттмана вставит новый сегмент s в эту структуру данных, когда линия развертки L пересекает левую конечную точку п этого сегмента (т. е. конечная точка сегмента с наименьшим Икс-координата при условии, что линия развертки L начинается слева, как описано выше в этой статье). Правильное положение сегмента s в двоичном дереве поиска может быть определен двоичным поиском, каждый шаг которого проверяет, п находится выше или ниже другого сегмента, который пересекает L. Таким образом, вставка может выполняться за логарифмическое время. Алгоритм Бентли – Оттмана также удаляет сегменты из двоичного дерева поиска и использует двоичное дерево поиска для определения сегментов, которые находятся непосредственно над или под другими сегментами; эти операции могут выполняться только с использованием самой древовидной структуры без ссылки на базовую геометрию сегментов.
  • А приоритетная очередь («очередь событий»), используемая для поддержания последовательности потенциальных будущих событий в алгоритме Бентли – Оттмана. Каждое событие связано с точкой п в плоскости либо конечная точка сегмента, либо точка пересечения, и событие происходит, когда линия L проносится п. Таким образом, события могут иметь приоритет по Икс-координаты точек, связанных с каждым событием. В алгоритме Бентли – Оттмана потенциальные будущие события состоят из конечных точек отрезков линии, которые еще не прошли, и точек пересечения пар линий, содержащих пары отрезков, которые находятся непосредственно над или под друг друга.

Алгоритму не требуется явно поддерживать представление линии развертки. L или его положение в плоскости. Скорее позиция L представлен косвенно: это вертикальная линия, проходящая через точку, связанную с последним обработанным событием.

Дерево двоичного поиска может быть любым сбалансированное двоичное дерево поиска структура данных, такая как красно-черное дерево; все, что требуется, - это чтобы вставки, удаления и поиск занимали логарифмическое время. Точно так же приоритетная очередь может быть двоичная куча или любая другая очередь с логарифмическим временем приоритета; более сложные очереди приоритетов, такие как Куча Фибоначчи не нужны. Обратите внимание, что сложность пространства приоритетной очереди зависит от структуры данных, используемой для ее реализации.

Подробный алгоритм

Алгоритм Бентли – Оттмана выполняет следующие шаги.

  1. Инициализировать приоритетную очередь Q потенциальных будущих событий, каждое из которых связано с определенной точкой на плоскости и имеет приоритет Икс-координата точки. Итак, изначально Q содержит событие для каждой из конечных точек входных сегментов.
  2. Инициализировать самобалансирующееся двоичное дерево поиска Т отрезков, пересекающих линию сдвига Lпо заказу y-координаты пунктов пропуска. Первоначально, Т пусто. (Даже если линия развертки L не представлен явно, может быть полезно представить его как вертикальную линию, которая изначально находится слева от всех входных сегментов.)
  3. В то время как Q непусто, найдите и удалите событие из Q связанный с точкой п с минимумом Икс-координат. Определите, что это за тип события, и обработайте его в соответствии со следующим анализом случая:
    • Если п это левая конечная точка линейного сегмента s, вставить s в Т. Найдите отрезки р и т которые находятся соответственно непосредственно выше и ниже s в Т (если они есть); если пересечение р и т (соседи s в структуре данных статуса) формирует потенциальное будущее событие в очереди событий, удалите это возможное будущее событие из очереди событий. Если s кресты р или т, добавьте эти точки пересечения как потенциальные будущие события в очередь событий.
    • Если п это правая конечная точка линейного сегмента s, удалять s от Т. Найдите сегменты р и т что (до удаления s) были соответственно непосредственно над и под ним в Т (если они есть). Если р и т крестик, добавьте эту точку пересечения как потенциальное будущее событие в очередь событий.
    • Если п точка пересечения двух отрезков s и т (с участием s ниже т слева от перекрестка) поменяйте местами s и т в Т. После обмена найдите сегменты р и ты (если они есть), которые находятся непосредственно ниже и выше т и sсоответственно. Удалите все точки пересечения RS (т.е. точка пересечения между р и s) и ту (т.е. точка пересечения т и ты) из очереди событий, а если р и т крест или s и ты крестик, добавьте эти точки пересечения в очередь событий.

Анализ

Алгоритм обрабатывает одно событие на конечную точку сегмента или точку пересечения в отсортированном порядке -координаты этих точек, что можно доказать по индукции. Это следует потому, что когда-то -ое событие было обработано, следующее событие (если это точка пересечения) должно быть пересечением двух сегментов, которые являются смежными в порядке следования сегментов, представленных , и поскольку алгоритм поддерживает все пересечения между соседними сегментами как потенциальные будущие события в очереди событий; следовательно, правильное следующее событие всегда будет присутствовать в очереди событий. Как следствие, он правильно находит все пересечения сегментов входной линии - проблему, для решения которой он был разработан.

Алгоритм Бентли – Оттмана обрабатывает последовательность события, где обозначает количество входных сегментов линии и обозначает количество переходов. Каждое событие обрабатывается постоянным числом операций в двоичном дереве поиска и очереди событий, и (поскольку оно содержит только конечные точки сегментов и пересечения между соседними сегментами) очередь событий никогда не содержит более События. Все операции требуют времени . Следовательно, общее время работы алгоритма равно .

Если пересечения, найденные алгоритмом, не нужно сохранять после того, как они были найдены, пространство, используемое алгоритмом в любой момент времени, равно : каждый из сегменты входной линии соответствуют не более чем одному узлу двоичного дерева поиска Т, и, как указано выше, очередь событий содержит не более элементы. Это ограничение пространства связано с Коричневый (1981); исходная версия алгоритма немного отличалась (она не удаляла события пересечения из когда какое-то другое событие приводит к тому, что два пересекающихся сегмента становятся несмежными), заставляя его использовать больше места.[3]

Чен и Чан (2003) описал очень компактную версию алгоритма Бентли – Оттмана, который кодирует большую часть своей информации в порядке сегментов в массиве, представляющем вход, требуя только дополнительные ячейки памяти. Однако для доступа к закодированной информации алгоритм замедляется на логарифмический коэффициент.

Особое положение

В приведенном выше описании алгоритма предполагается, что сегменты линии не являются вертикальными, что конечные точки сегмента линии не лежат на других сегментах линии, что пересечения образуются только двумя сегментами линии и что никакие две точки событий не имеют одинаковых Икс-координат. Другими словами, он не учитывает угловые случаи, т.е. предполагает общая позиция конечных точек входных сегментов. Однако эти предположения об общем положении не подходят для большинства применений пересечения отрезков прямой. Bentley & Ottmann (1979) предложили слегка изменить ввод, чтобы избежать подобных числовых совпадений, но не описали подробно, как выполнять эти возмущения. de Berg et al. (2000) более подробно опишите следующие меры для обработки входов с особыми позициями:

  • Разорвать связи между точками событий Икс-координировать с помощью y-координат. События с разными y-координаты обрабатываются как и раньше. Эта модификация решает проблему нескольких точек событий с одним и тем же Икс-координата, и проблема сегментов вертикальной линии: левая конечная точка вертикального сегмента определяется как точка с нижним y-координат, и шаги, необходимые для обработки такого сегмента, по существу те же, что и шаги, необходимые для обработки невертикального сегмента с очень большим наклоном.
  • Определите линейный сегмент как закрытый набор, содержащий его конечные точки. Следовательно, два линейных сегмента, которые имеют общую конечную точку, или линейный сегмент, содержащий конечную точку другого сегмента, считаются пересечением двух линейных сегментов.
  • Когда несколько сегментов линии пересекаются в одной точке, создайте и обработайте одну точку события для этого пересечения. Обновления двоичного дерева поиска, вызванные этим событием, могут включать удаление любых сегментов линии, для которых это правая конечная точка, вставка новых сегментов линии, для которых это левая конечная точка, и изменение порядка остальных сегментов линии, содержащих эту точку события. . Выход из версии алгоритма, описанной de Berg et al. (2000) состоит из набора точек пересечения линейных сегментов, помеченных сегментами, которым они принадлежат, а не из набора пар пересекающихся отрезков.

Похожий подход к вырождениям использовался в LEDA реализация алгоритма Бентли – Оттмана.[4]

Проблемы с числовой точностью

Для правильности алгоритма необходимо определить без аппроксимации отношения между конечной точкой линейного сегмента и другими линейными сегментами, а также правильно расставить приоритеты для различных точек событий. По этой причине стандартно использовать целочисленные координаты для конечных точек входных сегментов линии и представлять рациональное число точные координаты точек пересечения двух отрезков, используя арифметика произвольной точности. Однако можно ускорить вычисление и сравнение этих координат, используя плавающая точка вычисления и проверка того, достаточно ли далеки от нуля рассчитанные таким образом значения, чтобы их можно было использовать без какой-либо возможности ошибки.[4] Точные арифметические вычисления, требуемые наивной реализацией алгоритма Бентли-Оттмана, могут потребовать в пять раз больше битов точности, чем входные координаты, но Буассонат и Препарата (2000) Опишите модификации алгоритма, которые снижают необходимую точность до двойного числа битов, чем входные координаты.

Более быстрые алгоритмы

О (п журнал п) часть временной границы для алгоритма Бентли – Оттмана необходима, поскольку есть соответствующие нижняя граница для задачи обнаружения пересекающихся отрезков прямых в алгебраическое дерево решений модели вычислений.[5] Однако зависимость от k, количество переходов, может быть улучшено. Кларксон (1988) и Малмули (1988) оба предоставили рандомизированные алгоритмы для построения планарный граф чьи вершины являются конечными точками и пересечениями отрезков прямых, а ребра являются частями отрезков, соединяющих эти вершины, в ожидаемое время O (п журнал п + k), и эта проблема договоренность строительство было решено детерминированно в том же O (п журнал п + k) время ограничено Шазель и Эдельсбруннер (1992). Однако для построения всего этого устройства требуется пространство O (п + k), больше, чем O (п) пространственная граница алгоритма Бентли – Оттмана; Балабан (1995) описал другой алгоритм, который перечисляет все пересечения за время O (п журнал п + k) и пространство O (п).

Если входные линейные сегменты и их конечные точки образуют ребра и вершины связный граф (возможно с пересечениями), O (п журнал п) часть временной границы для алгоритма Бентли – Оттмана также может быть уменьшена. Так как Кларксон, Коул и Тарджан (1992) покажем, что в этом случае существует рандомизированный алгоритм решения задачи за ожидаемое время O (п журнал* п + k), где журнал* обозначает повторный логарифм, функция растет гораздо медленнее, чем логарифм. Тесно связанный рандомизированный алгоритм Эппштейн, Гудрич и Страш (2009) решает ту же задачу за время O (п + k журнал(я)п) для любой постоянной я, где журнал(я) обозначает функцию, полученную повторением логарифмической функции я раз. Первый из этих алгоритмов требует линейного времени, когда k больше чем п по бревну(я)п коэффициент, для любой постоянной я, а второй алгоритм требует линейного времени всякий раз, когда k меньше чем п по бревну(я)п фактор. Оба этих алгоритма включают применение алгоритма Бентли – Оттмана к небольшим случайным выборкам входных данных.

Заметки

  1. ^ Шамос и Хоуи (1976).
  2. ^ В описании алгоритма в de Berg et al. (2000), линия развертки горизонтальна и движется вертикально; это изменение влечет за собой замену использования Икс- и y-координаты согласованно на протяжении всего алгоритма, но в остальном не имеют большого значения для описания или анализа алгоритма.
  3. ^ Нелинейная пространственная сложность исходной версии алгоритма была проанализирована Пах и Шарир (1991).
  4. ^ а б Бартушка, Мельхорн и Нээр (1997).
  5. ^ Препарата и Шамос (1985), Теорема 7.6, с. 280.

использованная литература

внешние ссылки