Надто повільний повторний підрахунок найближчого сусіда для мільйонів точок даних


14

У мене є набір даних, що складається з мільйонів точок даних у 3D. Для обчислення, який я роблю, мені потрібно обчислити сусід (пошук діапазону) до кожної точки даних у радіусі, спробувати помістити функцію, обчислити помилку для придатності, повторити це для наступної точки даних тощо. Мій код працює належним чином, але це потребує дуже довго часу, приблизно 1 секунда за точку даних! Це, мабуть, тому, що для кожної точки він повинен шукати цілий набір даних. Чи є спосіб я зробити процес швидким. У мене є думка, що якщо я можу якось встановити якісь стосунки сусідства між першими сусідами, то це може бути менш повільним. Якщо це допомагає, я намагаюся знайти оптимальну ширину вікон Парзен в 3D.

Відповіді:


9

Я б запропонував googling для обмеження ієрархій обсягів (зокрема, дерево BSP). З огляду на вашу хмару точок, ви можете знайти площину, яка розбиває її на два рівні підклади. Тоді, коли вам потрібно знайти набір точок, які знаходяться в деякому радіусі R тестової точки, ви можете спочатку порівняти свою тестову точку з цією площиною, і якщо її висота вище, ніж R, то весь підкладок нижче площини також має бути далі, ніж R (також вам не потрібно перевіряти жодну з цих точок). Ви також можете застосовувати цю ідею рекурсивно, в кінцевому підсумку породжуючи складності n log n типу замість n-квадрата. (Це розділення BSP / бінарного простору,


7

Існує декілька структур даних для зберігання даних, що зберігають інформацію про положення та близькість; там, дозволяючи швидко визначити найближчого сусіда.

Зокрема, R-дерева (та спеціалізовані форми, такі як R * -берези ) та X-дерева . Багато варіантів, оптимізованих для дещо іншого використання.

Вибір R *-дерева, а не наївного найближчого сусіда, був важливою частиною мого отримання фактора 10000 прискорення з певного коду. (Добре, можливо , кілька сотень , що було R * -tree, більшість інших тому , що наївний погляд вгору був сильно закодований таким чином, що він розбив кеш. :: зітхати :: )

О(NжурналN)NО(журналN)


5

Це дуже схоже на одну з найбільших проблем у галузі молекулярної динаміки - обчислення всіх парних взаємодій між не пов'язаними частинками.

Там ми використовуємо списки комірок (або списки сусідів ), щоб допомогти нам зрозуміти, що знаходиться поруч; для цього додатка список комірок, мабуть, простіший алгоритм використання:

  • Розділіть ящик на ряд комірок.
  • Для кожної частинки визначте, якій клітині її слід призначити (O (1) на частинку).
  • Потім для кожної частинки перевірте "власну" клітинку плюс сусідні клітини; якщо будь-яка з них зайнята, подальший пошук не потрібен.
  • Якщо всі найближчі сусіди порожні, то перейдіть до наступних найближчих сусідів тощо, поки не знайдеться частинка.

Якщо у вашій системі є більш-менш рівномірний розподіл частинок, це значно знизить вартість вашого алгоритму, відповідно до грубості сітки. Однак необхідна тонка настройка: занадто груба сітка і ви не заощадите багато часу; занадто добре, і ви витратите багато часу на велосипеді по порожніх сітках!


Слід зазначити, що довжина краю комірки повинна бути принаймні радіусом пошуку, або якщо кожна частинка має власний радіус пошуку, то максимальний радіус.
Педро

Це правда у випадку МД; тут ми не знаємо, що це радіус апріорі .
aeismail

Аналогічна схема тривалий час використовувалася в симуляції гравітації хмарних часток. Я не знаю, чи це все ще є частиною найсучаснішого.
dmckee --- кошеня колишнього модератора

4

Ви обов'язково повинні перевірити дерева KD та октриси, які є методами вибору для точкових наборів (тоді як BSP - для загальних об'єктів, а сітки для більш-менш однакової щільності). Вони можуть бути дуже компактними і швидкими, мінімізуючи накладні витрати як в пам'яті, так і в обчисленні, і їх легко здійснити.

Коли ваші точки більш-менш рівномірно розподілені (навіть з порожніми ділянками, але не повинно бути особливості щільності або інших високих концентрацій), перевірте сферичні упаковки, якщо ви хочете спробувати неієрархічний підрозділ простору, подібний до сітки.


3

Ви, напевно, повинні розглянути можливість побудови триангуляції Делоне (ну, його аналог 3D). У 2D це спеціальна тріангуляція точок даних, яка завжди містить найближчого сусіда. Те ж саме в 3D, але з тетраедрами.

Ви можете будувати раз і назавжди триангуляцію, а потім шукати найближчого сусіда безпосередньо в тріангуляції. Я думаю, що є кілька хороших алгоритмів побудови триангуляції: у 2D побудова триангуляції внжурнал(н) і пізніші пошуки найближчого сусіда лінійні за кількістю точок даних.

Сподіваюся, це допомагає!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.