У мене є рішення, яке може здатися трохи заплутаним, але повинно бути більш ефективним, ніж пошук наївного грубої сили:O (н2)
- нехай буде вісь між центрами мас і .vАБ
- Сортуйте точки і уздовж цієї осі у порядку зменшення та зростання відповідно, у результаті виходять послідовності , , ..., та , , ..., .АБа0а1анб0б1бн
Решта - у псевдо-коді, щоб зробити це зрозумілішим:
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