Jump to content

сканирование Грэма

Демонстрация сканирования Грэма для поиска выпуклой двумерной оболочки.

Сканирование Грэма — это метод поиска выпуклой оболочки конечного набора точек на плоскости с временной сложностью O ( n log n ). Он назван в честь Рональда Грэма , опубликовавшего оригинальный алгоритм в 1972 году. [1] Алгоритм находит все вершины выпуклой оболочки, упорядоченные вдоль ее границы. Он использует стек для эффективного обнаружения и устранения вогнутостей на границе.

Алгоритм [ править ]

Как видите, PAB и ABC вращаются против часовой стрелки, а BCD — нет. Алгоритм обнаруживает эту ситуацию и отбрасывает ранее выбранные сегменты до тех пор, пока поворот не будет сделан против часовой стрелки (в данном случае ABD).

Первым шагом в этом алгоритме является поиск точки с наименьшей координатой Y. Если наименьшая координата Y существует более чем в одной точке набора, следует выбрать точку с наименьшей координатой X из кандидатов. Назовем эту П. точку Этот шаг занимает O ( n ), где n — количество рассматриваемых точек.

Затем набор точек необходимо отсортировать в порядке возрастания угла, который они и точка P составляют с осью x. общего назначения Для этого подойдет любой алгоритм сортировки , например пирамидальная сортировка (то есть O( n log n )).

Сортировка по углу не требует вычисления угла. Можно использовать любую функцию угла, монотонную на интервале . Косинус легко вычисляется с помощью скалярного произведения или можно использовать наклон линии. Если на карту поставлена ​​числовая точность, функция сравнения, используемая алгоритмом сортировки, может использовать знак векторного произведения для определения относительных углов.

Если несколько точек имеют одинаковый угол, либо разорвите связи, увеличив расстояние ( расстояния можно использовать расстояние Манхэттена или Чебышева вместо евклидова для упрощения вычислений, поскольку точки лежат на одном луче), либо удалите все точки, кроме самой дальней.

Алгоритм последовательно рассматривает каждую точку отсортированного массива. Для каждой точки сначала определяется, является ли движение из двух точек, непосредственно предшествующих этой точке, поворотом налево или поворотом направо. При повороте направо предпоследняя точка не является частью выпуклой оболочки, а находится «внутри» нее. Затем то же самое определение делается для набора последней точки и двух точек, которые непосредственно предшествуют точке, которая, как выяснилось, находилась внутри корпуса, и повторяется до тех пор, пока не встретится набор «поворот налево», после чего алгоритм переходит дальше. до следующей точки в наборе точек отсортированного массива за вычетом всех точек, оказавшихся внутри оболочки; нет необходимости рассматривать эти моменты еще раз. (Если на каком-либо этапе три точки лежат на одной прямой, можно либо отказаться от этого, либо сообщить об этом, поскольку в некоторых приложениях требуется найти все точки на границе выпуклой оболочки.)

Опять же, определение того, представляют ли три точки «поворот налево» или «поворот направо», не требует вычисления фактического угла между двумя сегментами линии и фактически может быть достигнуто только с помощью простой арифметики. За три очка , и , вычислите z координату векторного произведения двух векторов и , что задается выражением . Если результат равен 0, точки лежат на одной прямой; если он положительный, три точки представляют собой «поворот влево» или ориентацию против часовой стрелки, в противном случае «поворот вправо» или ориентацию по часовой стрелке (для пронумерованных точек против часовой стрелки).

Этот процесс в конечном итоге вернется к той точке, в которой он начался, после чего алгоритм завершается, и стек теперь содержит точки на выпуклой оболочке в порядке против часовой стрелки.

Временная сложность [ править ]

Сортировка точек имеет временную сложность O( n log n ). Хотя может показаться, что временная сложность цикла равна O( n 2 ), поскольку для каждой точки он возвращается, чтобы проверить, совершила ли какая-либо из предыдущих точек «поворот направо», на самом деле это O( n ), поскольку в некотором смысле каждая точка рассматривается не более двух раз. Каждая точка может появиться только один раз как точка. в «левом повороте» (потому что алгоритм переходит к следующей точке после этого), и как точка в «правом повороте» (потому что точка удаляется). Таким образом, общая временная сложность равна O( n log n ), поскольку время сортировки доминирует над временем фактического вычисления выпуклой оболочки.

Псевдокод [ править ]

В приведенном ниже псевдокоде используется функция ccw: ccw > 0, если три точки поворачиваются против часовой стрелки, ccw < 0, если по часовой стрелке, и ccw = 0, если коллинеарно. (В реальных приложениях, если координаты представляют собой произвольные действительные числа, функция требует точного сравнения чисел с плавающей запятой, и нужно остерегаться числовых особенностей для «почти» коллинеарных точек.)

Затем сохраните результат в stack.

let points be the list of points
let stack = empty_stack()

find the lowest y-coordinate and leftmost point, called P0
sort points by polar angle with P0, if several points have the same polar angle then only keep the farthest

for point in points:
    # pop the last point from the stack if we turn clockwise to reach this point
    while count stack > 1 and ccw(next_to_top(stack), top(stack), point) <= 0:
        pop stack
    push point to stack
end

Теперь стек содержит выпуклую оболочку, точки которой ориентированы против часовой стрелки, а P0 — первая точка.

Здесь, next_to_top() — это функция для возврата элемента на одну запись ниже вершины стека, без изменения стека, и аналогично: top() для возврата самого верхнего элемента.

Этот псевдокод адаптирован из Введения в алгоритмы .

Примечания [ править ]

Та же основная идея работает и в том случае, если входные данные сортируются по координате X, а не по углу, и оболочка вычисляется в два этапа, создавая верхнюю и нижнюю части оболочки соответственно. Эту модификацию разработал А.М. Андрей. [2] Он имеет те же основные свойства, что и сканирование Грэма. [3]

Первоначальное описание Грэма включало сортировку вокруг внутренней точки выпуклой оболочки , а не одной из ее вершин. [1] При том же выборе опорной точки для алгоритма сортировки соединение всех остальных точек в их отсортированном порядке вокруг этой точки вместо выполнения оставшихся шагов сканирования Грэма приводит к образованию звездообразного многоугольника , полигонализации входных данных. [4]

Метод стека, используемый при сканировании Грэма, очень похож на метод для задачи всех ближайших меньших значений , и параллельные алгоритмы для всех ближайших меньших значений также могут использоваться (например, сканирование Грэма) для эффективного вычисления выпуклых оболочек отсортированных последовательностей точек. [5]

устойчивость Численная

Численная устойчивость — это проблема, с которой приходится иметь дело в алгоритмах, использующих компьютерную арифметику с плавающей запятой конечной точности . В статье 2004 года проанализирована простая пошаговая стратегия, которую можно использовать, в частности, для реализации сканирования Грэма. [6] Заявленная цель статьи заключалась не в конкретном анализе алгоритма, а в том, чтобы предоставить хрестоматийный пример того, что и как может потерпеть неудачу из-за вычислений с плавающей запятой в вычислительной геометрии . [6] Позже Д. Цзян и Н. Ф. Стюарт. [7] подробно остановился на этом вопросе и с помощью обратного анализа ошибок сделал два основных вывода. Во-первых, выпуклая оболочка — это хорошо обусловленная задача, и поэтому можно ожидать появления алгоритмов, дающих ответ с разумной погрешностью. Во-вторых, они демонстрируют, что модификация сканирования Грэма, которую они называют Грэмом-Фортуном (включающая идеи Стивена Форчуна для числовой стабильности [8] ) преодолевает проблемы конечной точности и неточных данных «насколько это возможно».

См. также [ править ]

Ссылки [ править ]

  1. ^ Перейти обратно: а б Грэм, Р.Л. (1972). «Эффективный алгоритм определения выпуклой оболочки конечного плоского множества» (PDF) . Письма об обработке информации . 1 (4): 132–133. дои : 10.1016/0020-0190(72)90045-2 .
  2. ^ Эндрю, AM (1979). «Еще один эффективный алгоритм для выпуклых оболочек в двух измерениях». Письма об обработке информации . 9 (5): 216–219. дои : 10.1016/0020-0190(79)90072-3 .
  3. ^ Де Берг, Марк; Чеонг, Отфрид; Ван Кревелд, Марк; Овермарс, Марк (2008). Алгоритмы и приложения вычислительной геометрии . Берлин: Шпрингер . стр. 2–14 . дои : 10.1007/978-3-540-77974-2 . ISBN  978-3-540-77973-5 .
  4. ^ Аркин, Эстер М.; Фекете, Шандор П.; Уртадо, Ферран; Митчелл, Джозеф С.Б.; Нет, Марк; Сакристан, Вера; Сетия, Саураб (2003). «О рефлексивности множеств точек». В Аронов Борис; Басу, Саугата; Пах, Янош; Шарир, Миша (ред.). Дискретная и вычислительная геометрия: Фестиваль Гудмана-Поллака . Алгоритмы и комбинаторика. Том. 25. Берлин: Шпрингер. стр. 139–156. дои : 10.1007/978-3-642-55566-4_6 . МР   2038472 .
  5. ^ Беркман, Омер; Шибер, Барух ; Вишкин, Узи (1993). «Оптимальные двойные логарифмические параллельные алгоритмы, основанные на поиске всех ближайших меньших значений». Журнал алгоритмов . 14 (3): 344–370. CiteSeerX   10.1.1.55.5669 . дои : 10.1006/jagm.1993.1018 . .
  6. ^ Перейти обратно: а б Кеттнер, Лутц; Мельхорн, Курт; Пион, Сильвен; Ширра, Стефан; Да, Чи (2008). «Классные примеры проблем устойчивости в геометрических вычислениях» (PDF) . Вычислительная геометрия . 40 (1): 61–78. дои : 10.1016/j.comgeo.2007.06.003 . (Более ранняя версия была представлена ​​в 2004 году на ESA'2004)
  7. ^ Д. Цзян и Н. Ф. Стюарт, Обратный анализ ошибок в вычислительной геометрии. Архивировано 9 августа 2017 г. в Wayback Machine , Вычислительная наука и ее приложения - ICCSA, 2006, том 3980 из серии « Конспекты лекций по информатике» , стр. 50-59.
  8. ^ Форчун, С. Стабильное поддержание триангуляций множества точек в двух измерениях. Слушания 30-го ежегодного симпозиума IEEE по основам информатики Том. 30, 494–499, 1989.

Дальнейшее чтение [ править ]

Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: cb8acd77f254bb5eb489d931b64ec557__1713438120
URL1:https://arc.ask3.ru/arc/aa/cb/57/cb8acd77f254bb5eb489d931b64ec557.html
Заголовок, (Title) документа по адресу, URL1:
Graham scan - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)