Реализация kd-дерева PCL очень медленная

Я использую реализацию поиска ближайшего соседа (NN) kd-tree на C++ на основе библиотеки Point Cloud Library (PCL). Набор данных содержит около 2,2 млн точек. Я ищу точки NN для каждой другой точки. Радиус поиска установлен на 2.0. Чтобы полностью это вычислить, требуется около 12 часов! Я использую 64-битную машину Windows с 4 ГБ оперативной памяти. Это очень распространено для поиска kd-дерева? Интересно, есть ли какая-нибудь другая библиотека С++ для данных трехмерного облака точек, которая работает быстрее. Я слышал о библиотеке ANN C++ и CGAL, но не уверен, насколько они быстры.


person ayan.c    schedule 22.08.2014    source источник
comment
Я дам +1, так как проблема сложная. Тем не менее, подумайте о том, чтобы проверить себя в следующий раз и спросите о временных результатах.   -  person gsamaras    schedule 24.08.2014
comment
Вы упомянули, что ваш радиус поиска установлен на 2.0. Как распределяются ваши данные (например, какой диапазон они охватывают в направлениях XYZ)? Если в радиус поиска попадает много точек, поиск может стать очень медленным.   -  person anderas    schedule 25.08.2014
comment
Используя радиус поиска 2,0, приблизительное количество точек составляет около 7-80. Но данные распределены неравномерно. Число NN варьируется от 10 до 150. Я тоже думаю, что проблема не в размерности, а в распределении данных.   -  person ayan.c    schedule 25.08.2014
comment
Ты собираешься что-то сказать по поводу ответа?   -  person gsamaras    schedule 12.06.2015


Ответы (1)


Вкратце:

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

Вы должны убедиться, что библиотека NN быстрее грубой силы, что, вероятно, имеет место для ваших данных.

Как упомянул Андерас в комментарии, радиус поиска также играет значительную роль. Если в радиус поиска попадает много точек, поиск может стать очень медленным.

Полный ответ:

3 измерения это не много. Проблема возникает из-за количества очков, которые у вас есть.

ANN означает приблизительный поиск ближайшего соседа. Очень часто приходится идти на компромисс между точностью и скоростью, когда речь идет о NNS (поиске ближайших соседей).

Это означает, что вы выполняете поиск быстрее, но можете найти не точную NN, а близкую (например, не ближайшую точку, а вторую ближайшую и так далее). Большая скорость означает меньшую точность и наоборот.

CGAL также имеет параметр epsilon, обозначающий точность (ε = 0 означает полную точность). CGAL предназначен для перехода в 3 измерения, так что вы можете попробовать.

Я мог бы просто проверить себя и опубликовать ответы. Однако это не было бы на 100% безопасным, поскольку имеющиеся у вас очки могут иметь какое-то отношение. Это очень важно для производительности библиотеки, если она собирается использовать отношения, которые точки (могут) иметь друг к другу.

Еще один фактор, который следует учитывать, — простота установки.

CGAL трудно установить. Когда я это сделал, я выполнил эти шаги. ИНС легко установить. Я бы также посоветовал вам взглянуть на BOOST Geometry, который может вам пригодиться.

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

....

Хорошо, я признаю это, теперь мне самому любопытно, и я собираюсь провести несколько тестов!

....

ЭНН

(Я не публикую код, чтобы ответ не стал слишком большим. В документации есть примеры, и вы, конечно, можете спросить, если хотите!). Вывод:

// для бутылки Клейна

samaras@samaras-A15:~/Inria/nn_libs/ANN/ann_1.1.2/code$ g++ main.cpp -O3 -I ../include/ -L../lib -lANN -std=c++0x -o myExe
samaras@samaras-A15:~/Inria/nn_libs/ANN/ann_1.1.2/code$ ./myExe
N = 1000000
D = 3
ε = 0 // full accuracy
Misses: 0
creation of the tree took 1.06638 seconds.
Brute force for min: 0.009985598 seconds.
NN for 0.0           0.000078551 seconds.
Speedup of ANN for NN = 8.721533780

Для ε = 0.1 я получил:

Misses: 1000
creation of the tree took 0.727613 seconds.
Brute force for min: 0.006351318 seconds.
NN for 0.0           0.000004260 seconds.
Speedup of ANN for NN = 8.678169573

// для сферы

ε = 0
Misses: 0
creation of the tree took 1.28098 seconds.
Brute force for min: 0.006382912 seconds.
NN for 0.0           0.000022341 seconds.
Speedup of ANN for NN = 4.897436311

ε = 0.1
Misses: 1000
creation of the tree took 1.25572 seconds.
Brute force for min: 0.006482465 seconds.
NN for 0.0           0.000004379 seconds.
Speedup of ANN for NN = 5.144413371

Обратите внимание на разницу в ускорении! Это связано с характером наборов данных, как объяснялось выше (связь между точками).

ЦГАЛ:

// бутылка Клейна

samaras@samaras-A15:~/code/NN$ ./myExe
ε = 0
SplitingRule = Sliding_midpoint, N = 1000000, D = 3
creation of the tree took 0.02478 seconds.
Tree statistics:
Number of items stored: 1000000
Number of nodes: 471492
 Tree depth: 34
0x80591e4
Brute force for min: 0.007979495 seconds.
NN for 0.0           0.008085704 seconds.
Speedup of cgal for NN = 0.983849423

ε = 0.1
SplitingRule = Sliding_midpoint, N = 1000000, D = 3
creation of the tree took 0.02628 seconds.
Tree statistics:
Number of items stored: 1000000
Number of nodes: 471492
 Tree depth: 34
0x80591e4
Brute force for min: 0.007852951 seconds.
NN for 0.0           0.007856228 seconds.
Speedup of cgal for NN = 0.996250305

// Сфера

samaras@samaras-A15:~/code/NN$ ./myExe
ε = 0
SplitingRule = Sliding_midpoint, N = 1000000, D = 3
creation of the tree took 0.025502 seconds.
Tree statistics:
Number of items stored: 1000000
Number of nodes: 465002
 Tree depth: 32
0x80591e4
Brute force for min: 0.007946504 seconds.
NN for 0.0           0.007981456 seconds.
Speedup of cgal for NN = 0.992449817


samaras@samaras-A15:~/code/NN$ ./myExe
ε = 0.1
SplitingRule = Sliding_midpoint, N = 1000000, D = 3
creation of the tree took 0.025106 seconds.
Tree statistics:
Number of items stored: 1000000
Number of nodes: 465002
 Tree depth: 32
0x80591e4
Brute force for min: 0.008115519 seconds.
NN for 0.0           0.008117261 seconds.
Speedup of cgal for NN = 0.996702679

Для моих тестов ANN понятнее, чем CGAL, возможно, и для ваших тоже!


Примечание:

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

person gsamaras    schedule 23.08.2014
comment
PCL использует FLANN внутри компании. Вы также провели тест с FLANN? Я хорошо знаком с оболочкой FLANN для PCL, и по моему опыту она обычно не медленнее, чем ANN (или даже быстрее) в случае низкоразмерных данных. - person anderas; 25.08.2014
comment
Нет, я не запускал FLANN @anderas, потому что OP не упоминает об этом и в основном потому, что FLANN предназначен для гораздо более высоких измерений, в то время как набор данных OP лежит в трех измерениях. - person gsamaras; 25.08.2014
comment
Я не понимаю ваш результат, они действительно показали, что дерево CGAL работает медленнее, чем просто перебор? Это невозможно, что-то должно быть не так. - person Aleksander Fular; 24.09.2015
comment
@AleksanderFular, когда размер высок, известно, что CGAL плохо работает с ближайшими соседями. - person gsamaras; 24.09.2015
comment
@gsamaras Я не знал об этом, разве ваши тесты не проводились на D = 3? вот что я понял из твоего ответа - person Aleksander Fular; 24.09.2015
comment
@AleksanderFular извините, вы правы! Вероятно, это происходит из-за характера ввода. - person gsamaras; 24.09.2015