Повторное вычисление ближайшего соседа для миллионов точек данных слишком медленное

14

У меня есть набор данных, который работает с миллионами точек данных в 3D. Для вычисления, которое я делаю, мне нужно вычислить сосед (поиск диапазона) для каждой точки данных в радиусе, попытаться подогнать функцию, вычислить ошибку для подбора, повторить это для следующего пункта данных и так далее. Мой код работает правильно, но на его выполнение уходит очень много времени, около 1 секунды на точку данных! Вероятно, потому, что для каждой точки нужно искать во всем наборе данных. Есть ли способ, которым я могу сделать процесс быстро. У меня есть идея, что если я смогу каким-то образом установить отношения смежности между первыми соседями, то это может быть менее медленным. Если это помогает, я пытаюсь найти оптимальную ширину окна Parzen в 3D.

Kaustubh Kaluskar
источник

Ответы:

9

Я бы предложил поиск в Google для ограничения иерархий томов (в частности, дерева BSP). Учитывая ваше облако точек, вы можете найти плоскость, которая разделяет его на два равных подпространства. Затем, когда вам нужно найти набор точек, которые находятся в пределах некоторого радиуса R от контрольной точки, вы можете сначала сравнить свою контрольную точку с этой плоскостью, и если ее высота над ней больше, чем R, тогда все подклассы ниже плоскости также должен быть дальше, чем R (так что вам не нужно проверять какие-либо из этих точек). Вы также можете применять эту идею рекурсивно, в конечном итоге, получая n log n типов сложности вместо n-квадрата. (Это разделение BSP / двоичное пространство,

rchilton1980
источник
7

Существует несколько структур данных для хранения данных, которые сохраняют информацию о местоположении и близости; с помощью быстрого определения ближайшего соседа (ей).

В частности, R-деревья (и специализированные формы, такие как R * -деревья ) и X-деревья . Много вариантов, которые оптимизированы для слегка различного использования.

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

О(NжурналN)NО(журналN)производительность поиска, поэтому они хорошо работают, если вы будете выполнять много операций поиска (скажем, по одному на каждую точку, как в DBSCAN); однако некоторые из них имеют очень плохую производительность в худшем случае.

dmckee --- котенок экс-модератора
источник
5

Это очень похоже на одну из самых больших проблем в области молекулярной динамики - вычисление всех парных взаимодействий между несвязанными частицами.

Там мы используем списки ячеек (или списки соседей ), чтобы помочь нам выяснить, что находится поблизости; для этого приложения список ячеек, вероятно, является более простым алгоритмом:

  • Разделите коробку на ряд ячеек.
  • Для каждой частицы определите, какой ячейке она должна быть назначена (O (1) для каждой частицы).
  • Затем для каждой частицы проверьте «собственную» ячейку плюс соседние ячейки; если какой-либо из них занят, дальнейший поиск не требуется.
  • Если все ближайшие соседи пусты, развернитесь до ближайших соседей и т. Д., Пока не будет найдена частица.

Если ваша система имеет более или менее равномерное распределение частиц, это значительно снизит стоимость вашего алгоритма в соответствии с грубостью сетки. Однако необходима некоторая подстройка: слишком грубая сетка, и вы не сэкономите много времени; слишком хорошо, и вы будете тратить много времени на велосипеде по пустым ячейкам сетки!

aeismail
источник
Следует отметить, что длина края ячейки должна быть не меньше радиуса поиска, или, если каждая частица имеет свой собственный радиус поиска, то максимальный радиус.
Педро
Это верно в случае с MD; здесь мы не знаем, что это за радиус априори .
Aeismail
Подобная схема долгое время использовалась при крупномасштабном моделировании гравитации облаков частиц. Я не знаю, является ли это все еще частью уровня техники.
dmckee --- котенок экс-модератора
4

Вы должны обязательно проверить KD деревья и октреи которые являются методами выбора для наборов точек (в то время как BSP предназначены для общих объектов и сетки для более или менее однородных плотностей). Они могут быть очень компактными и быстрыми, минимизируя накладные расходы как в памяти, так и в вычислениях, и просты в реализации.

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

кварцевый
источник
3

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

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

Надеюсь, это поможет!

Dr_Sam
источник