Алгоритм трехмерной кластеризации - PullRequest
7 голосов
/ 14 августа 2010

Постановка задачи: У меня следующая проблема:

В трехмерном пространстве более миллиарда точек.Цель состоит в том, чтобы найти верхние N точек, которые имеют наибольшее число соседей в пределах заданного расстояния R. Другое условие состоит в том, что расстояние между любыми двумя точками этих верхних N точек должно быть больше R. Распределение этих точек не является равномерным.Очень часто определенные области пространства содержат много точек.

Цель: Найти алгоритм, который хорошо масштабируется для многих процессоров и требует небольшого объема памяти.

Мысли: Нормального пространственного разложения недостаточно для такого рода проблем из-за неравномерного распределения.неправильная пространственная декомпозиция, которая равномерно делит количество точек, может помочь нам решить проблему.Я буду очень признателен, если кто-то может пролить свет на то, как решить эту проблему.

Ответы [ 5 ]

4 голосов
/ 04 сентября 2012

Используйте Октри . Для 3D-данных с ограниченной областью значений, которая очень хорошо масштабируется до огромных массивов данных.

Многие из вышеупомянутых методов, такие как локально-чувствительное хэширование , являются приблизительными версиями, рассчитанными на гораздо более высокую размерность, когда вы больше не можете разумно разделять.

Разделение на каждом уровне на 8 ячеек (2 ^ d для d = 3) работает очень хорошо. А поскольку вы можете остановиться, когда в ячейке слишком мало точек, и построить более глубокое дерево, в котором есть множество точек, которые должны вполне соответствовать вашим требованиям.

Подробнее см. В Википедии:

https://en.wikipedia.org/wiki/Octree

Кроме того, вы можете попытаться построить R-дерево. Но R-дерево пытается сбалансировать, затрудняя поиск наиболее плотных областей. Для вашей конкретной задачи этот недостаток Octree действительно полезен! R-дерево прилагает большие усилия для того, чтобы глубина дерева была одинаковой везде, чтобы каждая точка была найдена примерно в одно и то же время. Тем не менее, вы заинтересованы только в плотных областях, которые будут найдены на самых длинных трассах в Октрее, даже не глядя на фактические точки еще!

2 голосов
/ 15 августа 2010

У меня нет определенного ответа для вас, но у меня есть предложение о подходе, который может привести к решению.

Я думаю, что стоит изучить хеширование с учетом локальных особенностей .Я думаю, что разделение точек равномерно и затем применение этого вида LSH к каждому набору должно быть легко распараллеливаемым.Если вы спроектируете свой алгоритм хеширования так, чтобы размер сегмента определялся в терминах R, представляется вероятным, что для данного набора точек, разделенных на сегменты, точки, удовлетворяющие вашим критериям, вероятно, будут присутствовать в наиболее полных сегментах.

Выполнив это локально, возможно, вы сможете применить некоторую стратегию в стиле уменьшения карты, чтобы пошагово комбинировать пространственные сегменты из разных параллельных прогонов алгоритма LSH, используя тот факт, что вы можете начатьчтобы исключить части вашего проблемного пространства путем дисконтирования целых сегментов.Очевидно, вы должны быть осторожны с краевыми случаями, которые охватывают разные сегменты, но я подозреваю, что на каждом этапе объединения вы можете применять разные размеры / смещения сегментов, чтобы убрать этот эффект (например, выполнить слияние пространственно эквивалентных сегментов).как соседние ведра).Я полагаю, что этот метод можно использовать для поддержания небольших требований к памяти (т. Е. Вам не нужно хранить гораздо больше, чем сами точки в любой момент, и вы всегда работаете с небольшими (ish) подмножествами).

Если вы ищете какую-то эвристику, то я думаю, что этот результат немедленно приведет к чему-то, напоминающему «хорошее» решение, то есть даст вам небольшое количество вероятных точек, которые вы можете проверить, удовлетворяя вашим критериям.Если вы ищете точный ответ, то вам придется применить некоторые другие методы, чтобы урезать пространство поиска, когда вы начинаете объединять параллельные сегменты.

Еще одна мысль, которая у меня была, заключалась в том, что это может относиться к нахождению метрики k -центр .Это определенно не та же самая проблема, но, возможно, некоторые из методов, используемых в решении, которые применимы в этом случае.Проблема в том, что это предполагает, что у вас есть метрическое пространство , в котором возможно вычисление метрики расстояния - однако в вашем случае наличие миллиарда точек делает нежелательным и трудным выполнение любого вида глобального обхода(например, сортировка расстояний между точками).Как я уже сказал, только мысль и, возможно, источник дальнейшего вдохновения.

1 голос
/ 04 сентября 2013

Я бы также предложил использовать октри.Фреймворк OctoMap отлично справляется с огромными трехмерными облаками точек.Он не хранит все точки напрямую, но обновляет плотность занятости каждого узла (он же 3D-блок).После того, как дерево построено, вы можете использовать простой итератор, чтобы найти узел с самой высокой плотностью.Если вы хотите смоделировать плотность точек или распределение внутри узлов, OctoMap очень легко принять.

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

1 голос
/ 06 сентября 2010

Вот некоторые возможные части решения.На каждом этапе есть различные варианты, которые будут зависеть от Ncluster, от того, как быстро изменяются данные, и от того, что вы хотите сделать со средствами.

3 шага: квантование, блок, K-средние.

1) квантование: уменьшите входные координаты XYZ до 8 бит, беря 2 ^ 8 процентилей X, Y, Z отдельно.Это ускорит весь поток без большой потери деталей.Вы можете отсортировать все точки 1G или просто случайную 1M, чтобы получить 8-битный x0 8 бит x быстрый развернутый бинарный поиск - см. Bentley, Pearls p.95.

Добавлено: Деревья Kd разбить любое облако точек на блоки разных размеров, каждая с точками размера листа - гораздо лучше, чем разбивать XYZ, как указано выше.Но на самом деле вам придется свернуть свой собственный код дерева Kd, чтобы разделить только первые поля, скажем, 16M, и сохранить только счетчик, а не баллы.

2): подсчитайте количество баллов в каждом 3d-боксе, [xj .. xj + 1, yj .. yj + 1, zj .. zj + 1].Средняя коробка будет иметь 2 ^ (30-3 * 8) очков;распределение будет зависеть от того, насколько скучны данные.Если некоторые блоки слишком велики или получают слишком много очков, вы можете a) разделить их на 8, b) отследить центр точек в каждом блоке, в остальном просто взять середины блока.

3) K-означает кластеризацию на 2 ^ (3 * 8) боксовых центров.(Google параллельно "k означает" -> 121 тыс. Обращений.) Это сильно зависит от K aka Ncluster, а также от вашего радиуса R. Грубый подход заключается в том, чтобы вырастить heap из скажем 27 * Ncluster box снаибольшее количество баллов, затем возьмите самые большие из них с учетом вашего ограничения радиуса.(Мне нравится начинать с Минимального связующего дерева , затем удалить самые длинные ссылки K-1, чтобы получить K кластеров.) См. Также Квантование цвета .

I 'сделайте Nbit, здесь 8, параметром с самого начала.

Что такое ваш Ncluster?

Добавлено: если ваши точки движутся во времени, см. collision-treatment-of-огромное количество кругов на SO.

0 голосов
/ 29 июля 2011

Просто идея.Создайте график с заданными точками и ребрами между точками, когда расстояние

Создание такого рода графика аналогично пространственной декомпозиции.На ваши вопросы можно ответить с помощью локального поиска на графике.Во-первых, это вершины с максимальной степенью, во-вторых, это нахождение максимального несвязанного множества вершин с максимальной степенью.

Я думаю, что создание графа и поиск могут выполняться параллельноЭтот подход может иметь большие требования к памяти.Разделение домена и работа с графиками для небольших объемов может уменьшить потребность в памяти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...