У меня есть решение, которое может показаться немного запутанным, но должно быть более эффективным, чем наивный перебор:O(n2)
- пусть будет ось между центрами масс и .A BvAB
- Сортируйте точки в и вдоль этой оси в порядке убывания и возрастания соответственно, получая последовательности , , ..., и , , ..., .B a 0 a 1 a n b 0 b 1 b nABa0a1anb0b1bn
Остальное в псевдокоде, чтобы было понятнее:
d = infinity.
for j from 1 to n
if (b_1 - a_j) along v > d then break endif
for k from 1 to n
if (b_k - a_j) along v > d then
break
else
d = min( d , ||b_k - a_j|| )
endif
enddo
enddo
То есть, предварительно отсортировав точки вдоль , вы можете отфильтровать пары, которые никогда не будут находиться в пределах друг от друга, поскольку вдоль всегда будет,vdbk−ajv≤∥bk−aj∥
В худшем случае это все еще , но если и хорошо разделены, это должно быть намного быстрее, чем это, но не лучше, чем , что требуется для сортировки.O(n2)ABO(nlogn)
Обновить
Это решение ни в коем случае не вытащено из шляпы. Это особый случай того, что я использую при моделировании частиц, чтобы найти все взаимодействующие пары частиц с пространственным биннингом. Моя собственная работа, объясняющая более общую проблему, здесь .
Что касается предложения использовать модифицированный алгоритм строчной развертки, хотя и интуитивно простое, я не уверен, что это в когда рассматриваются непересекающиеся множества. То же самое касается рандомизированного алгоритма Рабина.O(nlogn)
Похоже, не так много литературы, посвященной проблеме ближайших пар в непересекающихся множествах, но я нашел это , которое не претендует на то, что находится под , и это , что не кажется делать какие-либо претензии о чем-либо.O(n2)
Вышеприведенный алгоритм можно рассматривать как вариант развертки плоскости, предложенный в первой статье (Шань, Чжан и Зальцберг), однако вместо использования оси и отсутствия сортировки используется ось между наборами и обходы множеств в порядке убывания / возрастания.x