Алгоритм Джарвиса
Алгоритм Джарвиса (или алгоритм обхода Джарвиса, или алгоритм заворачивания подарка) определяет последовательность элементов множества, образующих выпуклую оболочку для этого множества. Метод можно представить как обтягивание верёвкой множества вбитых в доску гвоздей. Алгоритм работает за время [math]\displaystyle{ O(nh) }[/math], где [math]\displaystyle{ n }[/math] — общее число точек на плоскости, [math]\displaystyle{ h }[/math] — число точек в выпуклой оболочке.
Описание алгоритма
Пусть дано множество точек [math]\displaystyle{ P = \{\,p_1, p_2, \ldots, p_n\,\} }[/math]. В качестве начальной берётся самая левая нижняя точка [math]\displaystyle{ p_1 }[/math] (её можно найти за [math]\displaystyle{ O(n) }[/math] обычным проходом по всем точкам), она точно является вершиной выпуклой оболочки. Следующей точкой ([math]\displaystyle{ p_2 }[/math]) берём такую точку, которая имеет наименьший положительный полярный угол относительно точки [math]\displaystyle{ p_1 }[/math] как начала координат. После этого для каждой точки [math]\displaystyle{ p_i }[/math] (2<i<=|P|) против часовой стрелки ищется такая точка [math]\displaystyle{ p_{i+1} }[/math], путём нахождения за [math]\displaystyle{ O(n) }[/math] среди оставшихся точек (+ самая левая нижняя), в которой будет образовываться наибольший угол между прямыми [math]\displaystyle{ p_{i-1} p_{i} }[/math] и [math]\displaystyle{ p_{i} p_{i+1} }[/math]. Она и будет следующей вершиной выпуклой оболочки. Сам угол при этом не ищется, а ищется только его косинус через скалярное произведение между лучами [math]\displaystyle{ p_{i-1} p_{i} }[/math] и [math]\displaystyle{ p_{i} p'_{i+1} }[/math], где [math]\displaystyle{ p_{i} }[/math] — последний найденный минимум, [math]\displaystyle{ p_{i-1} }[/math] — предыдущий минимум, а [math]\displaystyle{ p'_{i+1} }[/math] — претендент на следующий минимум. Новым минимумом будет та точка, в которой косинус будет принимать наименьшее значение (чем меньше косинус, тем больше его угол). Нахождение вершин выпуклой оболочки продолжается до тех пор, пока [math]\displaystyle{ p_{i+1} \neq p_1 }[/math]. В тот момент, когда следующая точка в выпуклой оболочке совпала с первой, алгоритм останавливается — выпуклая оболочка построена.
Псевдокод
Jarvis(P) 1) p[1] = самая левая нижняя точка множества P; 2) p[2] = соседняя точка от p[1] справа (находится через минимальный положительный полярный угол) 3) i = 2; 4) do: (a)for для каждой точки j от 1 до |P|, кроме уже попавших в выпуклую оболочку, но включая p[1] p[i+1] = point_with_min_cos(p[i-1], p[i], P[j]); //точка, образующая минимальный косинус с прямой p[i-1]p[i], (b)i = i + 1; while p[i] != p[1] 5) return p;
Анализ
Цикл (4) выполнится [math]\displaystyle{ h }[/math] раз, при этом цикл (a) каждый раз выполняется за [math]\displaystyle{ \Theta(n) }[/math]. Все остальные операции выполняются за [math]\displaystyle{ O(1) }[/math]. Следовательно, алгоритм работает за [math]\displaystyle{ \Theta(hn) }[/math] или [math]\displaystyle{ \Theta(n^2) }[/math] в худшем случае, когда в выпуклую оболочку попадут все точки.
См. также
Литература
- Препарата Ф., Шеймос М. Вычислительная геометрия: Введение = Computational Geometry An introduction. — М.: Мир, 1989. — 478 с.
- Ласло М. Вычислительная геометрия и компьютерная графика на C++. — М.: БИНОМ, 1997. — 304 с.
- Т. Кормен, Ч. Лейзерсон, Р. Ривест, К. Штайн. Алгоритмы. Построение и анализ = Introduction to Algorithms. — 2-e изд. — “Вильямс”, 2005. — 1296 с.
Ссылки
Для улучшения этой статьи желательно: |