Алгоритм Чена — алгоритм побудови опуклої оболонки скінченної множини точок на площині. Виконується за час , де — кількість точок опуклої оболонки. Є комбінацією алгоритму, що обчислює опуклу оболонку за час (наприклад, алгоритм Грехема) з алгоритмом загортання за Джарвісом, який виконується за час .
Алгоритм широко використовується, так як є найшвидшим алгоритмом для обчислення опуклої оболонки, так і тому, що є суттєво простішим ніж алгоритм Кіркпатрика-Зейделя, який працює з такою ж швидкістю. Також узагальнюється на випадок обчислення опуклої оболонки в тривимірному просторі.
Алгоритм названий на честь Тімоті М. Чена[en].
Ідея алгоритму Чена полягає у початковому поділі всіх точок на групи по штук в кожній. Відповідно, кількість груп дорівнює . Для кожної з груп будується опукла оболонка скануванням за Грехемом, або якимось іншим, що працює зі швидкістю , таким чином, час витрачений для всіх груп точок складе .
Далі, починаючи з найнижчої точки (як що таких декілька, то обираємо з них крайню ліву), для отриманих в результаті розбиття оболонок будується спільна опукла оболонка за алгоритмом Джарвіса. При цьому наступна точка опуклої оболонки точка знаходиться за час , так як для того, щоб знайти точку з максимальним тангенсом по відношенню до точки, що розглядається, в -кутнику достатньо затратити . Логарифмічний час на пошук, витрачається тому, що точки в -кутнику вже впорядковані за полярним кутом під час виконання алгоритму сканування за Грехемом. У підсумку, на обхід потрібно часу.
Тобто алгоритм Чена працює за , при цьому, якщо отримати , то за .
Hull(P, m) 1)взяти . Розділити на диз'юнктивних підмножин потужності не більше ; 2)for i = 1 to r do: (a) обчислити опуклу оболонку Graham(), зберегти вершини в відсортованому за полярним кутом масиві; 3)як взяти нижню найлівішу точку з ; 4)for k = 1 to m do (a) for i = 1 to r do знайти та запам'ятати точку з з максимальним кутом ; (b) взяти як точку з с максимальним кутом ; (c) if return ; 5) return маленьке, спробуйте ще;
Зрозуміло, що обхід за Джарвісом, а отже і весь алгоритм, буде коректно працювати, тільки якщо , але як заздалегідь дізнатися, скільки точок буде в опуклій оболонці? Треба запускати алгоритм декілька разів, підбираючи та, якщо , то алгоритм буде повертати помилку. Якщо робити підбір бінарним пошуком за , то у підсумку вийде час , що достатньо довго.
Процес можна прискорити, якщо почати з маленького значення m і далі значно його збільшувати, доки не вийде . З іншого боку, якщо m буде збільшуватись занадто швидко, то є ризик що m буде набагато більше h і буде виконана зайва робота, яка збільшить час роботи алгоритму. Ітерація на кроці з номером буде . При цьому -а ітерація займе . Процес пошуку завершиться, коли , тобто ( — бінарний логарифм).
У підсумку .
ChanHull(P) for t = 1 to n do: (a) взяти ; (b) L = Hull(P, m); (c) if L != « маленьке, спробуйте ще» return L;
Стаття Чена містить декілька пропозицій, які можуть підвищити ефективність практичного використання алгоритму, наприклад: