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

алгоритм пошуку опуклої оболонки множини точок на площині

Алгоритм Грехема (англ. Graham scan) — метод знаходження опуклої оболонки для скінченної множини точок на площині за час O(n log n). Названий на честь Рональда Грехема, який опублікував первісний варіант алгоритму в 1972 році[1]. Алгоритм знаходить всі вершини опуклої оболонки впорядковані вздовж її межі.

Приклад знаходження опуклої оболонки алгоритмом Грехема.

Алгоритм

Як можна побачити, A — B і B — C слідують в напрямку протилежному годинниковому, а C — D ні. Алгоритм визначає таку ситуацію та відміняє попередньо обраний сегмент доти, доки напрямок знов не буде проти годинникового (B — D в цьому випадку.)

Перший крок в алгоритмі — знайти точку з найменшою у-координатою. Якщо таких декілька, то обираємо серед них точку з найменшою х-координатою. Назвемо її P. Цей крок має складність O(n), де n — кількість точок. Додамо цю точку в стек.

Далі, точки мають бути відсортовані в порядку зростання кута, який вони разом з P утворюють з віссю х. Будь-який алгоритм сортування підходить. Для пришвидшення обчислень, не обов'язково визначати кут, що ці точки утворюють з віссю х; замість цього достатньо обчислити котангенс цього кута: це монотонно спадна функція на проміжку і може бути обчислена простими арифметичними операціями.

Алгоритм виконується вважаючи, що точки відсортовано згідно з попереднім кроком. Для кожної точки він визначає чи було пересування від двох попередніх точок до цієї точки поворотом ліворуч чи поворотом праворуч. Якщо це був поворот праворуч, тоді передостання точка (від якої повертали) не є частиною опуклої оболонки і має бути видалена зі стека. Цей процес триває доти доки останні три точки утворюють поворот праворуч. Як тільки поворот ліворуч був отриманий, алгоритм рухається до наступної точки у відсортованному масиві. (Якщо в якийсь момент виявляється, що три точки колінеарні, користувач може сам вирішувати, що робити в такому випадку, адже іноді потрібно отримати всі точки, що належать до опуклої оболонки.)

Визначення, коли три точки утворюють поворот ліворуч, а коли поворот праворуч не вимагає обчислення кута між двома відрізками, і може бути визначено за допомогою простих арифметичних операцій. Для трьох точок , і , просто обчисліть напрямок векторного добутку двох векторів визначених точками , і , , яке характеризується знаком виразу . Якщо результат 0, точки колінеарні; якщо позитивний, точки утворюють поворот ліворуч, інакше поворот праворуч.

Насамкінець алгоритм досягне точки з якої ми починали, тепер він завершився і стек містить точки опуклої оболонки в напрямку зворотному до годинникового.

Час роботи

Загальний час роботи дорівнює O(n log n).

Псевдокод

# Три точки йдуть проти годинникової стрілки якщо ccw > 0, за стрілкою якщо# ccw < 0, і колінеарні якщо ccw = 0 через те, що ccw визначена як# така, що повертає signed area трикутника сформованного p1, p2 та p3.function ccw(p1, p2, p3):    return (p2.x - p1.x)*(p3.y - p1.y) - (p2.y - p1.y)*(p3.x - p1.x)

Результат буде збережений в points.

let N           = number of pointslet points[N+1] = the array of pointsswap points[1] with the point with the lowest y-coordinatesort points by polar angle with points[1]# points[0] буде позначкою зупинки алгоритму.let points[0] = points[N]# M буде вказувати кількість точок в опуклій оболонці.let M = 2for i = 3 to N:    # Шукаємо наступну правильну точку на опуклій оболонці.    while ccw(points[M-1], points[M], points[i]) <= 0:       M -= 1    # Пересуваємо points[i] в правильне місце та оновлюємо M.    M += 1    swap points[M] with points[i]

Див. також

Література

  • Томас Кормен; Чарльз Лейзерсон, Рональд Рівест, Кліфорд Стайн (2009) [1990]. Розділ 33.3: Знаходження опуклої оболонки. Вступ до алгоритмів (вид. 3rd). MIT Press і McGraw-Hill. ISBN 0-262-03384-4.

Примітки

🔥 Top keywords: Головна сторінкаЧемпіонат Європи з футболу 2024Спеціальна:ПошукВікіпедія:Культурна спадщина та видатні постаті (2024)Збірна України з футболуБріджертониЧемпіонат Європи з футболу 2020YouTubeУкраїнаЧемпіонат Європи з футболуЗбірна Румунії з футболуРебров Сергій СтаніславовичГлобальний саміт мируРадіо «Свобода»ДефолтРумуніяЛунін Андрій ОлексійовичНаціональна суспільна телерадіокомпанія УкраїниДень батькаДовбик Артем ОлександровичШевченко Андрій МиколайовичЯрмоленко Андрій МиколайовичЧемпіонат Європи з футболу 2024 (кваліфікаційний раунд)Мудрик Михайло Петрович138-ма зенітна ракетна бригада (Україна)FacebookЄрмак Андрій БорисовичСексВійськові звання України22-га окрема механізована бригада (Україна)Зінченко Олександр ВолодимировичТериторіальний центр комплектування та соціальної підтримкиДумками навиворіт 2Чемпіонат Європи з футболу 2016Список операторів систем розподілу України2024 у телебаченніMegogoСписок українських жіночих іменКиїв