Статические выпуклые оболочки: Джарвис, Грэхем, Эндрю, Чен, QuickHull — различия между версиями
Yurik (обсуждение | вклад) (→Алгоритм Грехэма) |
Yurik (обсуждение | вклад) (→Алгоритм Джарвиса) |
||
Строка 4: | Строка 4: | ||
= Алгоритм Джарвиса = | = Алгоритм Джарвиса = | ||
− | + | "Gift wrapping" (Заворачивание подарка). | |
== Описание Алгоритма == | == Описание Алгоритма == | ||
+ | [[File:Graham1.png|right|250px|Промежуточный шаг алгоритма]] <br/><br/> | ||
+ | 1) Возьмем самую правую нижнюю точку <tex>p_0</tex> нашего множества. Добавляем ее в ответ. | ||
− | + | 2) На каждом следующем шаге для последнего добавленного <tex>p_i</tex> ищем <tex>p_{i + 1}</tex> среди всех недобавленных точек и <tex>p_0</tex> с максимальным полярным углом относительно <tex>p_i</tex> (Если углы равны, надо сравнивать по расстоянию). Добавляем <tex>p_{i + 1}</tex> в ответ. Если <tex>p_{i + 1} == p_0</tex> , заканчиваем алгоритм. | |
− | |||
− | |||
+ | <br/><br/><br/><br/> | ||
== Корректность == | == Корректность == | ||
− | Точка <tex>p_0</tex>, очевидно, принадлежит оболочке. На каждом шаге мы получаем прямую <tex>p_{i-1}p_i</tex>, по | + | Точка <tex>p_0</tex>, очевидно, принадлежит оболочке. На каждом последующем шаге алгоритма мы получаем прямую <tex>p_{i-1}p_i</tex>, по построению которой все точки множества лежат слева от нее. Значит, выпуклая оболочка состоит из <tex>p_{i}</tex>-ых и только из них. |
== Псевдокод == | == Псевдокод == | ||
− | + | Inplace-реализация алгоритма. <tex>S[1..n]</tex> - исходное множество. | |
− | |||
Jarvis(S) | Jarvis(S) | ||
− | + | find i such that S[i] has the lowest y-coordinate and highest x-coordinate | |
− | + | p0 = S[i] | |
− | + | pi = p0 | |
− | k = | + | k = 0 |
do | do | ||
− | for i = | + | k++ |
− | if | + | for i = k..n |
− | swap(S[ | + | if S[i] has lower angle and higher distance than S[k] in relation to pi |
− | k | + | swap(S[i], S[k]) |
− | while | + | pi = S[k] |
+ | while pi != p0 | ||
return k | return k | ||
Версия 11:44, 16 января 2014
Конспект не готов. |
Ниже приводятся основные алгоритмы построения выпуклых оболочек статического множества. Используются обозначения:
- размер входных данных, - размер оболочки.Содержание
Алгоритм Джарвиса
"Gift wrapping" (Заворачивание подарка).
Описание Алгоритма
1) Возьмем самую правую нижнюю точку
нашего множества. Добавляем ее в ответ.2) На каждом следующем шаге для последнего добавленного
ищем среди всех недобавленных точек и с максимальным полярным углом относительно (Если углы равны, надо сравнивать по расстоянию). Добавляем в ответ. Если , заканчиваем алгоритм.
Корректность
Точка
, очевидно, принадлежит оболочке. На каждом последующем шаге алгоритма мы получаем прямую , по построению которой все точки множества лежат слева от нее. Значит, выпуклая оболочка состоит из -ых и только из них.Псевдокод
Inplace-реализация алгоритма.
- исходное множество.Jarvis(S) find i such that S[i] has the lowest y-coordinate and highest x-coordinate p0 = S[i] pi = p0 k = 0 do k++ for i = k..n if S[i] has lower angle and higher distance than S[k] in relation to pi swap(S[i], S[k]) pi = S[k] while pi != p0 return k
Сложность
Добавление каждой точки в ответ занимает
времени, всего точек будет , поэтому итоговая сложность .Алгоритм Грэхема
Описание Алгоритма
1)Находим самую правую нижнюю точку множества
, добавляем в ответ. 2)Сортируем все остальные точки по полярному углу относительно . 3)Добавляем в ответ - самую первую из отсортированных точек. 4)Берем следующую по счету точку в массиве . Пока и две последних точке в ответе образуют неправый поворот, удаляем из ответа последнюю точку. 5)Делаем п.4, пока не закончатся точки.Корректность
Псевдокод
Подаем в функцию исходное множество S, возвращаем позицию
- в будет хранится наша оболочка. - модифицированная функция поворота, учитывающая случай, когда точки лежат на одной прямой.
Сложность
Сортировка точек занимает
времени. При обходе каждая точка добавляется в ответ не более одного раза, поэтому сложность этой части - . Суммарное время - .