Алгоритмы построения выпуклых оболочек множества точек на плоскости
НЕТ ВОЙНЕ |
24 февраля 2022 года российское руководство во главе с Владимиром Путиным развязало агрессивную войну против Украины. В глазах всего мира это военное преступление совершено от лица всей страны, всех россиян. Будучи гражданами Российской Федерации, мы против своей воли оказались ответственными за нарушение международного права, военное вторжение и массовую гибель людей. Чудовищность совершенного преступления не оставляет возможности промолчать или ограничиться пассивным несогласием. Мы убеждены в абсолютной ценности человеческой жизни, в незыблемости прав и свобод личности. Режим Путина — угроза этим ценностям. Наша задача — обьединить все силы для сопротивления ей. Эту войну начали не россияне, а обезумевший диктатор. И наш гражданский долг — сделать всё, чтобы её остановить. Антивоенный комитет России |
Распространяйте правду о текущих событиях, оберегайте от пропаганды своих друзей и близких. Изменение общественного восприятия войны - ключ к её завершению. |
meduza.io, Популярная политика, Новая газета, zona.media, Майкл Наки. |
Содержание
Выпуклая оболочка множества точек
Определение: |
Выпуклой оболочкой множества точек называется пересечение всех выпуклых множеств, содержащих все заданные точки. |
Еще одно определение:
Определение: |
Выпуклой оболочкой множества точек называется линейная комбинация минимального набора точек, дающая все остальные точки. |
Некоторые свойства выпуклых оболочек:
- Экстремальные всегда принадлежат выпуклой оболочке.
- Для равномерно распределенных в прямоугольнике точек, выпуклая оболочка будет состоять из логарифма точек.
- Если в изначальном массиве точка на 0-й позиции будет самой левой, то после построения выпуклой оболочки in-place она останется там же.
Пусть нам дано конечное множество точек на плоскости
— cамая левая нижняя точка, лежит на выпуклой оболочке.Рассмотрим алгоритмы, позволяющие построить выпуклую оболочку
Алгоритм Джарвиса
Алгоритм Джарвиса определяет последовательность точек, образующую выпуклую оболочку множества точек на плоскости. Так же известен как алгоритм "заворачивания подарка".
Время работы алгоритма —
, где — количество точек в выпуклой оболочке. В случае получаем .Алгоритм в силу своей простоты легко реализуется in-place.
Описание Алгоритма
Будем находить точку, с наименьшим полярным углом от предыдущей стороны. Если таких точек несколько - брать самую дальнюю. И так до тех пор, пока выпуклая оболочка не замкнется.
Псевдокод
dot max_element(int j, int i) { if (left_turn(dots[j - 1], dots[j], dots[i])) return dots[j]; else return dots[i]; } int jarvis(std::vector<dot> &dots) { int last = 0; dots.push_back(dots[0]); int size = dots.size(); do { for(int i = last + 2; i < size; i++) { std::swap(dots[last + 1], max_element(last + 1, i)); } } while(dots[last] != dots[0]); std::swap(dots[last], dots[size - 1]); dots.pop_back(); return last; };
Алгоритм Merge hull
Алгоритм Quick hull
Алгоритм Чена
Алгоритм Чена строит выпуклую оболочку конечного множества точек за
без вырожденных случаев, где — количество точек в выпуклой оболочке. Основная идея заключается в том, чтобы разделить изначальное множество точек на группы по элементов, построить выпуклые оболочки для каждой из групп, потом слить их в одну общую оболочку.Алгоритм состоит из трех этапов
- Разбиение исходного множества точек на группы по элементов в каждой.
- Построение выпуклых оболочек для групп.
- Объединение выпуклых оболочек.
Предположим, что
нам известно.Исходное множество точек можно разбивать на группы любым способом. Для простоты будем выделять группы просто по порядку. Первые
элементов — первая группа, следующие элементов — вторая группа и так далее.Строить выпуклые оболочки для групп можно с помощью алгоритма Грэма за
. Всего групп, получаем суммарную асимптотикуДля объединения оболочек будем использовать обход по Джарвису. Самая левая точка точно лежит на общей внутренней оболочке. Научимся находить следующую точку. предположим, что мы умеем находить опорную прямую за
Всего оболочек . Получается, что точку мы умеем находить за Всего точек на выпуклой оболочке . Получаем объеденение оболочек за .Выбор числа h
Заметим, что нам не обязательно знать точное значение
. Нас утроит любое значение , такое что .Будем использовать следующий метод:
Будем брать
, пока . На каждую итерацию потребуется ..
Посчитаем, сколько нам понадобится времени на поиск