Изменения

Перейти к: навигация, поиск
м
Нет описания правки
== Описание Алгоритма ==
[[File:Graham1.png|thumb|250px|Промежуточный шаг алгоритма. Для точки <tex>p_i</tex> ищем следующую перебором.]] <br/><br/>
1) # Возьмем точку <tex>p_0</tex> нашего множества с самой маленькой у-координатой (если таких несколько, берем самую правую из них). Добавляем ее в ответ. 2) # На каждом следующем шаге для последнего добавленного <tex>p_i</tex> ищем <tex>p_{i + 1}</tex> среди всех недобавленных точек и <tex>p_0</tex> {{Acronym|с максимальным полярным углом относительно <tex>p_i</tex> (Если углы равны, надо сравнивать по расстоянию)|Считать углы не нужно, можно просто подставить в функцию сравнения предикат поворота}}. Добавляем <tex>p_{i + 1}</tex> в ответ. Если <tex>p_{i + 1} == p_0</tex> , заканчиваем алгоритм.
Докажем, что на каждом шаге множество <tex>p_i</tex>-тых является выпуклой оболочкой всех уже рассмотренных точек. Доказательство проведем по индукции.
1)* База. Для трех первых точек утверждение, очевидно, выполняется.
2)* Переход. Пусть для <tex>i-1</tex> точек оболочки совпадают. Докажем, что и для <tex>i</tex> точек они совпадут.
Рассмотрим истинную оболочку <tex>ch(S \cup {i}) = ch(S) \cup i \setminus P</tex>, где <tex>P</tex> - множество всех точек из <tex>ch(S)</tex>, видимых из <tex>i</tex>. Так как мы добавляли точки в нашу оболочку против часовой стрелки и так как <tex>i</tex>-тая точка лежит в <tex>ch(S \cup i)</tex>, то <tex>P</tex> состоит из нескольких подряд идущих последних добавленных в оболочку точек, и именно их мы удаляем на текущем шаге. Поэтому наша оболочка и истинная для <tex>i</tex> точек совпадают.
== Описание Алгоритма ==
[[File:andrew1.png|thumb|400px|Промежуточный шаг алгоритма. Зелеными линиями обозначена текущая выпуклая оболочка, синими - промежуточные соединения точек, красными - те отрезки, которые раньше входили в оболочку, а сейчас нет. На текущем шаге при добавлении точки <tex>p</tex> последовательно убираем из оболочки точки с <tex>i+3</tex>-ей до <tex>i+1</tex>-ой]]
1)# Находим самую левую и самую правую точки множества - <tex>p_0</tex> и <tex>p_1</tex>. 2)# Делим множество на две части: точки над и под прямой. 3)# Для каждой половины ищем выпуклую оболочку Грехемом с условием, что сортируем не по полярному углу, а по координате. 4)# Сливаем получившиеся оболочки.
<br/>
== Описание Алгоритма ==
1)# Разобьем все множество на произвольные группы по <tex>m</tex> штук в каждой. Будем считать, что <tex>m</tex> нам известно. Тогда всего групп окажется <tex>r = n / m</tex>. 2)# Для каждой группы запускаем Грехема.  3)# Начиная с самой нижней точки ищем саму выпуклую оболочку Джарвисом, но перебираем не все точки, а по одной из каждой группы.
== Сложность ==
[[File:hull.png|thumb|250px|Промежуточный шаг алгоритма. Для прямой <tex>p_i p_1</tex> нашли точку <tex>p</tex>. Над прямыми <tex>p_i p</tex> и <tex>p p_1</tex> точек нет, поэтому переходим к следующей прямой <tex>p_0 p_i</tex>.]]
1)# Найдем самую левую точку <tex>p_0</tex> и самую правую точку <tex>p_1</tex> (Если таких несколько, выберем среди таких нижнюю и верхнюю соответственно). 2)# Возьмем все точки выше прямой <tex>p_0 p_1</tex>. 3)# Найдем среди этого множества точку <tex>p_i</tex>, наиболее отдаленную от прямой (если таких несколько, взять самую правую). 4)# Рекурсивно повторить шаги 2-3 для прямых <tex>p_0 p_i</tex> и <tex>p_i p_1</tex>, пока есть точки. 5)# Добавить в ответ точки <tex>p_0 .. p_i .. p_1</tex>, полученные в п. 3. 6)# Повторить пункты 2-5 для <tex>p_1 p_0</tex> (то есть для "нижней" половины). 7)# Ответ - объединение списков из п. 5 для верхней и нижней половины.
<br/><br/>
222
правки

Навигация