Алгоритм Форчуна
![](http://upload.wikimedia.org/wikipedia/commons/0/0c/Fortunes-algorithm-slowed.gif)
Алгоритм Форчуна — это алгоритм заметающей прямой для генерации диаграммы Вороного из набора точек на плоскости за время O с использованием памяти O(n)[1][2]. Алгоритм первоначально опубликовал Стивен Форчун в 1986 в своей статье «Алгоритм заметающей прямой для диаграмм Вороного»[3].
Описание алгоритма
[править | править код]Алгоритм поддерживает заметающую прямую и береговую линию, которые двигаются по плоскости в процессе работы алгоритма. Заметающая прямая — это прямая, которую мы по традиции можем считать вертикальной и движущейся слева направо. В любой момент работы алгоритма точки из набора слева от заметающей прямой будут включены в диаграмму Вороного, в то время как точки справа от заметающей прямой ещё не отработаны. Береговая линия не является прямой, а является сложной, состоящей из кусочков парабол, кусочно-заданной кривой слева от заметающей прямой. Она отделяет порцию плоскости, внутри которой диаграмма Вороного может быть известна, независимо от других точек справа от заметающей прямой. Для каждой точки слева от заметающей прямой можно определить параболу для точки, которая равноудалена как от этой точки, так и от заметающей прямой. Береговая линия — это граница объединений этих парабол. По мере движения прямой вершины береговой линии, в которых две параболы пересекаются, вычерчивают рёбра диаграммы Вороного. Береговая линия продвигается, сохраняя основание каждой параболы в точности на половину пути между начальным положением заметающей прямой и новой позицией заметающей прямой. Математически это значит, что каждая парабола образуется с помощью заметающей прямой как директрисы, а заданная точка из набора служит фокусом.
Алгоритм поддерживает структуру данных двоичного дерева, описывающего комбинаторную структуру береговой линии, и очередь с приоритетом, перечисляющую потенциальные события в будущем, которые могли бы изменить структуру береговой линии. Эти события включают добавление другой параболы в береговую линию (когда заметающая прямая проходит через другую входную точку) и удаление кривой из береговой линии (когда заметающая прямая становится касательной к окружности через некоторые три входных точки, параболы которых образуют последовательные сегменты береговой линии). Каждому такому событию может быть присвоен приоритет по x-координате заметающей прямой в точке, где событие произошло. Алгоритм состоит из последовательного удаления события из очереди с приоритетом, нахождения изменений событий в береговой линии и обновление структуры данных.
Так как имеется O(n) событий для обработки (каждое ассоциировано с некоторым свойством диаграммы Вороного) и времени O(log n) для обработки события (которое состоит из постоянного числа поисков по двоичному дереву и операций очереди с приоритетом), общее время равно .
Псевдокод
[править | править код]Пусть будет преобразованием , где — евклидово расстояние между z и ближайшей точкой Пусть T будет «береговой линией» Пусть будет областью, покрывающей точку p. Пусть будет граничным лучом между точками p и q. Пусть будут точками с минимальной y-координатой, упорядоченными по x-координате создаёт начальные вертикальные граничные лучи пока не IsEmpty(Q) выполнить в случае если p является точкой в : Находим область в T, содержащую p, ограниченную кривой слева и кривой справа создаём новые граничные лучи и с основанием p заменяем на в T удаляем из Q любое пересечение между и вставляем в Q любое пересечение и вставляем в Q любое пересечение и p является вершиной Вороного в : пусть p будет пересечением слева и справа пусть будет левым соседом и пусть будет правым соседом в T создаём новый граничный луч , если , или создаём , если p правая часть более высокой из q и s, в противном случае создаём заменяем на вновь созданную в T удаляем из Q любое пересечение и удаляем из Q любое пересечение и вставляем в Q любое пересечение и вставляем в Q любое пересечение и записываем p как вершину и и основание выводим сегменты границ и конец в случае конец пока выводим оставшиеся граничные лучи из T
Взвешенные стороны и диски
[править | править код]Как указывает Форчун[5], модифицированная версия алгоритма заметающей прямой может быть использована для построения аддитивно взвешенной диаграммы Вороного, в которой расстояние до каждой точки нейтрализуется весом точки. Это можно рассматривать эквивалентно как диаграмма Вороного набора дисков с центрами в точках и радиусом, равным весу точки.
Взвешенные точки можно использовать для контроля площадей ячеек Вороного, когда диаграммы Вороного используются для построения древовидных карт[англ.]. В аддитивно взвешенной диаграмме Вороного биссектрисой между точками в общем случае является гипербола, в противоположность невзвешенным диаграммам Вороного и энергетическим диаграммам[англ.] дисков, для которых это прямая.
Примечания
[править | править код]- ↑ de Berg, van Kreveld, Overmars, Schwarzkopf, 2000, с. 151—160.
- ↑ Austin - Feature Column.
- ↑ Fortune, 1986, с. 313—322.
- ↑ Wong, Müller.
- ↑ de Berg, van Kreveld, Overmars, Schwarzkopf, 2000, с. 151-160.
Литература
[править | править код]- Mark de Berg, Marc van Kreveld, Mark Overmars, Otfried Schwarzkopf. Computational Geometry. — 2nd revised. — Springer-Verlag, 2000. — ISBN 3-540-65620-0.
- David Austin. Voronoi Diagrams and a Day at the Beach. — American Mathematical Society.
- Steven Fortune. A sweepline algorithm for Voronoi diagrams // ACM Digital Library Proceedings of the second annual symposium on Computational geometry. — Yorktown Heights, New York, United States, 1986. — ISBN 0-89791-194-6. SpringerLink (недоступная ссылка)
- Kenny Wong, Hausi A. Müller. An Efficient Implementation of Fortune's Plane-Sweep Algorithm for Voronoi Diagrams.
Ссылки
[править | править код]- Реализация Стивена Форчуна на C
- Алгоритм Форчуна для диаграмм Вороного, реализованный на C++
- Алгоритм Форчуна, реализованный на JavaScript
Для улучшения этой статьи желательно:
|