Оптимизация алгоритма конверта Лучшее место для размещения круга

Мне нужно решить следующую задачу оптимальным образом.

Входные данные:

  • N точек на плоскости, заданной как (x, y) пара целочисленных координат
  • M точек на той же плоскости, заданной как пара целых чисел (x, y), представляющих центр окружности. Все эти круги имеют (0, 0) на краю.

Мне нужно найти способ выделения ряда окружностей, обладающих тем свойством, что для любой «хорошей» окружности ни одна точка из первых N точек не лежит в выбранной окружности или на краю выбранной окружности.

Количество точек и кругов порядка 100 000. Очевидное решение проверки каждого круга с каждой точкой имеет сложность O(N * M), а при 100 000 кругов и 100 000 точек это занимает около 15 секунд на Core 2 Duo с 64-битным кодом одинарной точности SSE3. Эталонная реализация, с которой я конкурирую, занимает всего около 0,1 секунды с теми же данными. Я знаю, что эталонная реализация - O (Nlog N + Mlog M).

Я подумал об оптимизации своего алгоритма следующим образом. Сделайте 2 копии точечных данных и отсортируйте копии по координате x и соответственно по координате y. Затем используйте только точки, лежащие в квадрате, определяемом [(xc - r, yc - r); (xc + r, yc + r)], где (xc, yc) — центр «текущей» окружности радиусом r. Я могу найти точки в этом интервале с помощью бинарного поиска, потому что теперь я работаю с отсортированными данными. Сложность этого подхода должна быть O(Nlog N + Mlog^2 N), и он действительно быстрее, но все же значительно медленнее, чем эталонный.

Я более или менее знаю, как работает эталонная реализация, но есть некоторые шаги, которые я не понимаю. Я попытаюсь объяснить то, что я знаю до сих пор:

Радиус окружности с координатами (Xc, Yc):

  • Rc = sqrt(Xc * Xc + Yc * Yc) (1)

Это потому, что (0, 0) находится на краю круга.

Чтобы точка P(x, y) находилась вне круга, должно выполняться следующее неравенство:

  • sqrt((Xc - x)^2 + (Yc - y)^2) > Rc (2)

Теперь, если мы подставим Rc из (1) в (2), то возведем в квадрат неравенство, после простых вычислений получим:

  • Yc ‹ 1/2y * (x^2 + y^2) - Xc * x/y (3.1) для y > 0
  • Yc > 1/2y * (x^2 + y^2) - Xc * x/y (3.2) при y ‹ 0

(3.1) и (3.2) должны выполняться для данной окружности C(Xc, Yc) при любых (x, y), выбранных из входных данных.

Для простоты сделаем несколько обозначений:

  • A(x, y) = 1/2y * (x^2 + y^2) (4.1)
  • B(x, y) = -x/y (4.2)
  • E(Xc) = 1/2y * (x^2 + y^2) - Xc * x/y = A(x, y) + Xc * B(x, y) (4.3)

Мы можем видеть, что для данной окружности C(Xc, Yc) мы можем записать (3) как:

  • Yc ‹ MIN(E(Xc)) (5.1) для всех точек с y > 0
  • Yc > MAX(E(Xc)) (5.2) для всех точек с y ‹ 0

Мы можем видеть, что E(Xc) — линейная функция относительно Xc с двумя параметрами — A(x, y) и B(x, y). Это означает, что в основном E(Xc) представляет в евклидовом пространстве семейство прямых с двумя параметрами.

Теперь вот часть, которую я не понимаю. Они говорят, что из-за свойства, указанного в предыдущем абзаце, мы можем вычислить MIN() и MAX() за O(1) амортизированного времени вместо O(N) времени, используя алгоритм Envelope. Я не знаю, как может работать алгоритм Envelope.

Любые подсказки о том, как реализовать алгоритм Envelope?

Заранее спасибо!


Изменить:

Вопрос не в том, что такое оболочка в математическом смысле — это я и так знаю. Вопрос в том, как определить конверт за время, лучшее, чем O(n), по-видимому, это можно сделать за амортизированное время O(1).

У меня есть семейство функций, которое мне нужно для вычисления конверта, и у меня есть массив всех возможных параметров. Как решить задачу максимизации оптимальным образом?

Еще раз спасибо!


person Terminus    schedule 07.12.2008    source источник
comment
Мне просто интересно, почему кто-то заменил тег информатика, который является наиболее важным тегом, поскольку это чисто проблема CS с домашним заданием, поскольку оно не имеет ничего общего с каким-либо домашним заданием, а домашнее задание совсем не описательное и полезное.   -  person Terminus    schedule 08.12.2008
comment
Я думаю, что вы имеете в виду радиус, а не отношение.   -  person Svante    schedule 08.12.2008
comment
В формуле (2) должно быть Yc - y, а не Yc * y.   -  person Svante    schedule 08.12.2008
comment
Я конечно имею в виду радиус, но где? :) И да -- в (2) вы правы. Исправлено! Спасибо.   -  person Terminus    schedule 08.12.2008
comment
Соотношение найдено, исправлено на радиус -- спасибо!.   -  person Terminus    schedule 08.12.2008
comment
самое оптимальное - ерунда: либо что-то оптимально, либо нет. Если что-то оптимально, то по определению не может быть чего-то более оптимального.   -  person Svante    schedule 08.12.2008
comment
Поправил, хотя не согласен. Я знаю, что из грамматики p.o.v вы правы, но я думаю, вы можете сказать, что O (n) более оптимально, чем O (n ^ 2), и менее оптимально, чем O (1).   -  person Terminus    schedule 08.12.2008
comment
Для данной проблемы лучшим решением является оптимальное. Все худшие решения не являются оптимальными. Вы можете приравнять оптимальное к лучшему; лучше было бы лучше - бред. Сравнения на прилагательное оптимальный не определены. Если вы хотите сделать сравнение, вы можете использовать лучше или хуже.   -  person Svante    schedule 08.12.2008
comment
@Harleqin - В нашей области мы часто используем глагол «оптимизировать» для обозначения улучшения производительности [чего-либо] (по отношению к некоторому показателю эффективности). Мы не часто хотим сделать лучшую [реализацию], которая даже не всегда имеет одно единственное определение, поскольку обычно (продолжение...)   -  person P Daddy    schedule 09.12.2008
comment
... задействованные компромиссы (память, процессорное время, реальное время, стоимость и т. д.). Я понимаю ваше возражение с точки зрения английского языка, но я бы сказал, что это еще один случай, когда англоязычное слово становится жаргоном в нашей отрасли с (иногда) немного другим значением.   -  person P Daddy    schedule 09.12.2008
comment
оптимизировать – это глагол, обозначающий действие, которое стремится к оптимальной производительности.   -  person Svante    schedule 16.12.2008


Ответы (6)


Вот запись в Википедии о конвертах. Вот руководство по теореме конверта в оптимизации.

person Yuval F    schedule 07.12.2008
comment
Спасибо. Я знаю о конвертах в математическом смысле, и я знаю, что это должно означать в этом случае, но, хотя я прочитал вторую ссылку, которую вы разместили, я все еще не могу придумать способ определения конверта в O (1) или лучше Затем на). - person Terminus; 08.12.2008

У меня нет математического образования, но я бы подошел к этой проблеме в три этапа:

  • Отбросьте большинство точек в N. Это сложная часть. Каждая пара точек «затеняет» область «позади» ее, если смотреть из начала координат. Эта область ограничена двумя лучами, исходящими из точек наружу, указывающими на начало координат, и пересечением окружности между точками. Расчет этого может быть намного проще в полярных координатах. Начните со случайной пары, затем смотрите на одну новую точку за раз: если она затенена, выбросьте ее; если нет, узнайте, затеняет ли он какую-либо точку уже в вашем наборе, а затем перестройте огибающий набор кривых. Тесты на перестроение части огибающей кривой должны занимать почти постоянное время, поскольку маловероятно, что набор теней превысит определенное небольшое число. Наихудший случай для этого, кажется, O (NlogN). Я не могу представить, что какое-либо решение может быть лучше, чем O(N), потому что вам в любом случае нужно смотреть на каждую точку.

  • Отбросить большинство точек из M. Это довольно просто: если точка из M находится дальше от начала координат, чем половина расстояния до самой дальней точки из огибающего множества, то ее можно отбросить. Это занимает O(M)

  • Отфильтруйте оставшиеся точки в M через фактическую проверку. Сколько времени это займет, зависит от распределения N и M, но я думаю, что это почти O(1), если оба числа большие и распределения похожи.

В целом, это кажется возможным за O(N log(N) + M). Хотя никаких гарантий ;)

person Svante    schedule 08.12.2008

  • Постройте R-Tree из всех точек первого набора.
  • Для каждой точки во втором наборе вычислите ограничивающую рамку ее круга и найдите все точки в R-дереве, которые попадают в эту ограничивающую рамку (O (n log n) по отношению к количеству возвращенных точек).
  • Проверьте расстояние между каждой возвращаемой точкой и рассматриваемой в данный момент точкой; отбросить все, которые лежат в пределах ограничивающей рамки, но вне круга.
person Nick Johnson    schedule 17.12.2008

Я думаю, вы можете сделать это с диаграммой Вороного:

  • Составьте диаграмму Вороного объединения {N точек} {[0,0]}
  • Центры окружностей, не соприкасающиеся с N точками, это в точности те, которые лежат внутри ячейки Вороного точки [0,0], являющейся выпуклым многоугольником
  • Отфильтруйте M точек, один тест должен пройти O (log C) = O (log N) [где C — количество вершин в ячейке [0,0]

Общая сложность должна быть O(N log N+M log N)

person jpalecek    schedule 14.01.2009

Рассмотрим некоторые другие аспекты ваших вычислений.

Например, вы, видимо, сравниваете много расстояний. Каждый принимает вызов SQRT. Почему бы вместо этого не сравнить «квадраты расстояний». SQRT — дорогостоящее вычисление.

person Mark T    schedule 08.12.2008

Никогда не принимайте кв. Оставьте все расстояния в виде их квадратов. При этом их тоже можно сравнить, но времени в 2-3 раза меньше.

person Gangnus    schedule 05.01.2012