Статические выпуклые оболочки: Джарвис, Грэхем, Эндрю, Чен, QuickHull — различия между версиями
Yurik (обсуждение | вклад) (→Алгоритм Джарвиса) |
Yurik (обсуждение | вклад) (→Алгоритм Джарвиса) |
||
Строка 6: | Строка 6: | ||
== Описание Алгоритма == | == Описание Алгоритма == | ||
− | + | [[File:Temp.gif|thumb|250px|Промежуточный шаг алгоритма]] | |
− | 2) На каждом следующем шаге для последнего добавленного <tex>p_i</tex> ищем <tex>p_{i + 1}</tex> с максимальным полярным углом относительно <tex>p_i</tex> (Если углы равны, надо сравнивать по расстоянию). Добавляем <tex>p_{i + 1}</tex> в ответ. Если <tex>p_{i + 1} == p_0</tex> , заканчиваем алгоритм. | + | 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> , заканчиваем алгоритм. | ||
+ | |||
+ | == Корректность == | ||
+ | |||
+ | Точка <tex>p_0</tex>, очевидно, принадлежит оболочке. На каждом шаге мы получаем прямую <tex>p_{i-1}p_i</tex>, по построениению которой все точки множества лежат слева от нее. Значит эти точки принадлежат выпуклой оболочке. | ||
+ | |||
+ | == Псевдокод == | ||
+ | |||
+ | Подаем в функцию исходное множество S, возвращаем позицию <tex>k</tex> - в <tex>S[1..k - 1]</tex> будет хранится наша оболочка. | ||
+ | <tex>turn(a, b, c)</tex> - модифицированная функция поворота, учитывающая случай, когда точки лежат на одной прямой. | ||
+ | |||
+ | Jarvis(S) | ||
+ | for i = 1..n | ||
+ | if S[i] is right and higher than S[1] | ||
+ | swap(S[1], S[i]) | ||
+ | k = 1 | ||
+ | do | ||
+ | for i = 1 and k+1..n | ||
+ | if (turn(S[k+1], S[i], S[k])) | ||
+ | swap(S[k+1], S[k]) | ||
+ | k++; | ||
+ | while S[k-1] != S[1] | ||
+ | |||
+ | |||
+ | == Сложность == | ||
+ | |||
+ | Добавление каждой точки в ответ занимает <tex>O(n)</tex> времени, всего точек будет <tex>k</tex>, поэтому итоговая сложность <tex>O(nk)</tex>. | ||
= Алгоритм Грехэма = | = Алгоритм Грехэма = |
Версия 09:36, 13 января 2014
Конспект не готов. |
Содержание
Алгоритм Джарвиса
По-другому "Заворачивание подарка"
Описание Алгоритма
1) Возьмем самую правую нижнюю точку
нашего множества. Добавляем ее в ответ.2) На каждом следующем шаге для последнего добавленного
ищем среди всех недобавленных точек и с максимальным полярным углом относительно (Если углы равны, надо сравнивать по расстоянию). Добавляем в ответ. Если , заканчиваем алгоритм.Корректность
Точка
, очевидно, принадлежит оболочке. На каждом шаге мы получаем прямую , по построениению которой все точки множества лежат слева от нее. Значит эти точки принадлежат выпуклой оболочке.Псевдокод
Подаем в функцию исходное множество S, возвращаем позицию
- в будет хранится наша оболочка. - модифицированная функция поворота, учитывающая случай, когда точки лежат на одной прямой.Jarvis(S) for i = 1..n if S[i] is right and higher than S[1] swap(S[1], S[i]) k = 1 do for i = 1 and k+1..n if (turn(S[k+1], S[i], S[k])) swap(S[k+1], S[k]) k++; while S[k-1] != S[1]
Сложность
Добавление каждой точки в ответ занимает
времени, всего точек будет , поэтому итоговая сложность .