Алгоритм Грэхема

Материал из testwiki
Перейти к навигации Перейти к поиску

Алгоритм Грэхема — алгоритм построения выпуклой оболочки в двумерном пространстве. В этом алгоритме задача о выпуклой оболочке решается с помощью стека, сформированного из точек-кандидатов. Все точки входного множества заносятся в стек, а потом точки, не являющиеся вершинами выпуклой оболочки, со временем удаляются из него. По завершении работы алгоритма в стеке остаются только вершины оболочки в порядке их обхода против часовой стрелки.

Алгоритм

В качестве входных данных процедуры Graham выступает множество точек Q, где |Q|3. В ней вызывается функция Top(S), которая возвращает точку, находящуюся на вершине стека S, не изменяя при этом его содержимое. Кроме того, используется также функция NextToTop(S), которая возвращает точку, расположенную в стеке S, на одну позицию ниже от верхней точки; стек S при этом не изменяется.

Graham(Q)
1) Пусть p0 — точка из множества Q с минимальной координатой y или самая левая из таких точек при наличии совпадений
2) Пусть <p1,p2,,pm> — остальные точки множества Q, отсортированные в порядке возрастания полярного угла,
      измеряемого против часовой стрелки относительно точки p0 
     (если полярные углы нескольких точек совпадают, то по расстоянию до точки p0)
3) Push(p0,S)
4) Push(p1,S)
5) for i = 2 to m do
6)     while угол, образованный точками NextToTop(S),Top(S) и pi, образуют не левый поворот
            (при движении по ломаной, образованной этими точками, мы движемся прямо или вправо)
7)       do Pop(S)
8)    Push(pi,S)
9) return S

Для определения, образуют ли три точки a, b и c левый поворот, можно использовать обобщение векторного произведения на двумерное пространство, а именно условие левого поворота будет выглядеть следующим образом: uxvyuyvx0, где u={bxax,byay},v={cxbx,cyby}

Корректность сканирования по Грэхему

Если процедура Graham обрабатывает множество точек Q, где |Q|3, то по завершении этой процедуры стек S будет содержать (в направлении снизу вверх) только вершины оболочки CH(Q) в порядке обхода против часовой стрелки.

Доказательство

После выполнения строки 2 в нашем распоряжении имеется последовательность точек <p1,p2,,pm>. Определим подмножество точек Qi={p0,p1,,pi} при i = 2,3,…,m. Множество точек Q — Qm образуют те из них, что были удалены из-за того, что их полярный угол относительно точки p0 совпадает с полярным углом некоторой точки из множества Qm. Эти точки не принадлежат выпуклой оболочке CH(Q), так что CH(Qm) = CH(Q). Таким образом, достаточно показать, что по завершении процедуры Graham стек S состоит из вершин оболочки CH(Qm) в порядке обхода против часовой стрелки, если эти точки просматриваются в стеке снизу вверх. Заметим, что точно так же, как точки p0,p1,pm являются вершинами оболочки CH(Q), точки p0,p1,pi являются вершинами оболочки CH(Qi).

В доказательстве используется сформулированный ниже инвариант цикла. В начале каждой итерации цикла for в строках 6-9 стек S состоит(снизу вверх) только из вершин оболочки CH(Qi1) в порядке их обхода против часовой стрелки.

Инициализация. При первом выполнении строки 6 инвариант поддерживается, поскольку в этот момент стек S состоит только из вершин Q2 = Qi1, и это множество трех вершин формирует свою собственную выпуклую оболочку. Кроме того, если просматривать точки снизу вверх, то они будут расположены в порядке обхода против часовой стрелки.

Сохранение. При входе в новую итерацию цикла for вверху стека S находится точка pi1, помещенная туда в конце предыдущей итерации (или перед первой итерацией, когда i = 3). Пусть pj — верхняя точка стека S после выполнения строк 7-8 цикла while, но перед тем, как в строке 9 в стек будет помещена точка pi. Пусть также pk — точка, расположенная в стеке S непосредственно под точкой pj. В тот момент, когда точка pj находится наверху стека S, а точка pi ещё не добавлена, стек содержит те же точки, что и после j-й итерации цикла for. Поэтому, согласно инварианту цикла, в этот момент стек S содержит только CH(Qj) в порядке их обхода против часовой стрелки, если просматривать их снизу вверх. Полярный угол точки pi относительно точки p0 больше, чем полярный угол точки pj, и поскольку угол pkpjpi сворачивает влево(в противном случае точка pj была бы снята со стека), после добавления в стек S точки pi (до этого там были только вершины CH(Qj)) в нем будут содержаться вершины CH(Qj{pi}). При этом они будут расположены в порядке обхода против часовой стрелки, если просматривать их снизу вверх.

Покажем, что множество вершин CH(Qj{pi}) совпадает с множеством точек CH(Qi). Рассмотрим произвольную точку pt, снятую со стека во время выполнения i-й итерации цикла for, и пусть pr — точка, расположенная в стеке S непосредственно под точкой pt перед снятием со стека последней(этой точкой pr может быть точка pj). Угол prptpi не сворачивает влево, и полярный угол точки pt относительно точки p0 больше полярного угла точки pr. Так как точка pt находится внутри треугольника, образованного тремя другими точками множества Qi, она не может быть вершиной CH(Qi). Так как pt не является вершиной CH(Qi), то CH(Qi — {pt}) = CH(Qi). Пусть Pi — множество точек, снятых со стека во время выполнения i-ой итерации цикла for. Верно равенство CH(Qi — Pi) = CH(Qi). Однако Qi — Pi = Qi {pi}, поэтому мы приходим к заключению, что CH(Qj {pi}) = CH(Qi — Pi) = CH(Qi).

Сразу после вытеснения из стека S точки pi в нем содержатся только вершины CH(Qi) в порядке их обхода против часовой стрелки, если просматривать их в стеке снизу вверх. Последующее увеличение на единицу значения i приведет к сохранению инварианта цикла в очередной итерации.

Завершение. По завершении цикла выполняется равенство i = m + 1, поэтому из инварианта цикла следует, что стек S состоит только из вершин CH(Qm), то есть из вершин CH(Q). Эти вершины расположены в порядке обхода против часовой стрелки, если они просматриваются в стеке снизу вверх.

Время работы

Время работы процедуры Graham равно O(NlogN), где N=|Q|. Как несложно показать, циклу while потребуется время O(N). В то время, как сортировка полярных углов займет O(NlogN) времени, откуда и следует общая асимптотика процедуры Graham.

См. также

Литература

Ссылки