Учитывая набор точек, как мне найти две точки, которые находятся дальше всего друг от друга?

Возможный дубликат:
Двумерный набор наибольшего линейного измерения баллов

Я мог бы вычислить расстояние между каждой точкой и взять самое большое, но это не звучит как очень эффективный способ сделать это при большом (> 1000) количестве точек.

Примечание. Это для iPhone, поэтому у меня не так много вычислительной мощности.


person willc2    schedule 24.10.2009    source источник


Ответы (4)


Вы просите вычислить диаметр набора. Стандартный метод состоит в том, чтобы сначала вычислить выпуклую оболочку, что сводит задачу к нахождению диаметра выпуклого многоугольника. Даже в том случае, если вы не устраняете какие-либо точки, эта дополнительная информация - именно то, что необходимо для эффективного решения проблемы. Однако определение диаметра выпуклого многоугольника не совсем тривиально; несколько опубликованных статей с алгоритмами решения этой задачи оказались некорректными.

Вот довольно читаемое обсуждение правильного O (n) алгоритма для задачи (где n - количество точек в выпуклой оболочке).

Также обратите внимание, что iphone не это ограничено; Тщательно написанная реализация даже совершенно наивного алгоритма может обработать 1000 точек менее чем за десятую долю секунды. Конечно, использование правильного алгоритма позволит вам работать намного быстрее =)

person Stephen Canon    schedule 24.10.2009
comment
Это O (n) только после нахождения выпуклой оболочки - если вам просто дан набор точек, может быть O (n log n), чтобы сначала найти выпуклую оболочку. - person ShreevatsaR; 21.07.2011
comment
@ShreevatsaR: Конечно. В моем ответе прямо указано, где n - количество точек в выпуклой оболочке, что довольно ясно дает понять, что вам нужно сначала найти выпуклую оболочку. - person Stephen Canon; 21.07.2011
comment
Да, возможно, это так. Ясность в глазах читателя. :-) (Алгоритм для задачи в вопросе, очевидно, не O (n), где n - количество точек в выпуклой оболочке; это вторая часть, как вы говорите.) В любом случае, я подумал, что стоит упомянуть , просто для полноты: люди могут прийти к этим ответам спустя годы через поисковые системы, могут невнимательно читать, могут запутаться и т. д. - person ShreevatsaR; 22.07.2011
comment
Ссылка в формате pdf мертва, быстрый поиск в гугле меня не подвел, у кого-нибудь есть копия? - person Thomas; 11.10.2012
comment
@Thomas: алгоритм называется вращающимися штангенциркулями, и Шривацар дает хорошее неформальное описание его в своем ответе на другой вопрос (stackoverflow.com/ a / 322409/142434) - person Stephen Canon; 11.10.2012

Почему бы просто не вычислить выпуклую оболочку точек? В зависимости от используемого алгоритма, который вы используете, он требует O(n) или O(n log n) времени и устраняет все внутренние точки. из соображений. Затем проверяйте только эти крайние точки, чтобы найти две самые дальние.

person Chris Bunch    schedule 24.10.2009
comment
Это не облегчает жизнь. Если количество точек в выпуклой оболочке равно O (n), то сложность останется прежней. - person P Shved; 24.10.2009
comment
Совершенно верно. Но есть надежда, что если будет ›1000 точек, то многие из них окажутся внутри выпуклой оболочки. - person Chris Bunch; 24.10.2009
comment
Отличный ответ. Я собирался сказать это. Начните с эвристики Акла-Туссена, чтобы выкинуть как можно больше точек, прежде чем найти выпуклую оболочку. - person Nosredna; 24.10.2009
comment
Вы уменьшили меру сложности с O (n ^ 2). В худшем случае все точки находятся на выпуклой оболочке, но во многих случаях вы значительно сократите реальную работу. - person PanCrit; 24.10.2009
comment
@Pavel (и @Chris) ожидаемое количество точек на выпуклой оболочке O(log n), поэтому ожидаемое время работы для проверки этих точек O(log^2 n). - person Jesse Beder; 25.10.2009
comment
@Jesse (и @Pavel, и @Chris): если на выпуклой оболочке есть k точек, вы можете найти самую дальнюю пару всего за время O (k) (с помощью вращающихся штангенциркулей); ему не нужно k ^ 2. См. Ответы на другой вопрос, в котором задается то же самое: stackoverflow.com/questions/321989/ - person ShreevatsaR; 25.10.2009

Начните с точки с наименьшей x-координатой. (Назовите это Точкой X) Постройте набор «граничных точек», начиная с точки x, и вертикальной линии, проходящей через точку. Не должно быть других точек слева от PointX) найдите следующую точку на границе, медленно вращая линию по часовой стрелке (Или против часовой стрелки), пока линия не коснется другой точки (см. ниже). Добавьте эту точку в набор и повторите с этой следующей точкой, чтобы получить следующую, пока вы в конечном итоге не вернетесь к исходной точке x. У вас npw есть набор точек, образующих границу полного набора. Сравните расстояние между каждой парой в этом сокращенном наборе, чтобы найти пару, которая находится дальше всего друг от друга.

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

person Charles Bretana    schedule 24.10.2009
comment
Тот же комментарий, что и Крису. Ничего проще не сделаешь, если на внешней границе очков не намного меньше. - person P Shved; 24.10.2009
comment
Это звучит как дорогостоящий способ вычисления сложной оболочки, за которым следует остальная часть ответа Криса Банча. - person PanCrit; 24.10.2009
comment
Я не знал, что есть технический термин для этого ... (выпуклый корпус), но это граница из резиновой ленты. Я проверю другие алгоритмы для его вычисления ... Что касается количества точек, для любого случайного набора точек количество точек на границе должно быть на O (n) меньше, чем общее количество точек. (Граница - это одномерная линия, ограничивающая 2-мерную область.) - person Charles Bretana; 24.10.2009

См. эти страницы (та, на которую есть ссылки и страницы, на которые можно попасть, щелкнув ссылку «далее») при вычислении диаметра выпуклой оболочки набора точек.

Мое краткое резюме:

  1. вычислить набор точек в выпуклой оболочке (= O (n log n), единственный раз, когда вы получите O (n), - это если вы сначала отсортируете список, который в любом случае займет O (n log n))
  2. заказ вдоль границы (вы получите это бесплатно, если используете сканирование Грэма для №1)
  3. используйте один из алгоритмов диаметра O (n) для поиска противоположных точек с наибольшим диаметром. Мне нравится алгоритм Shamos, поскольку он является одним из алгоритмы вращающихся штангенциркулей.
person Jason S    schedule 25.10.2009