У меня есть база данных с 500 000 точек в 100-мерном пространстве, и я хочу найти ближайшие 2 точки. Как это сделать?
Обновление: пространство евклидово, извините. И спасибо за все ответы. Кстати, это не домашнее задание.
У меня есть база данных с 500 000 точек в 100-мерном пространстве, и я хочу найти ближайшие 2 точки. Как это сделать?
Обновление: пространство евклидово, извините. И спасибо за все ответы. Кстати, это не домашнее задание.
Вы можете попробовать библиотеку ANN, но она дает надежные результаты только до 20 измерений. .
В Введение в алгоритмы есть глава, посвященная поиску двух ближайших точек в двумерном пространстве в O( n*logn) время. Вы можете ознакомиться с ним в книгах Google. На самом деле, я предлагаю это всем, потому что то, как они применяют технику «разделяй и властвуй» к этой проблеме, очень простое, элегантное и впечатляющее.
Хотя его нельзя распространить непосредственно на вашу проблему (поскольку константа 7
будет заменена на 2^101 - 1
), для большинства наборов данных это должно подойти. Итак, если у вас достаточно случайный ввод, это даст вам O(n*logn*m)
сложность, где n
— количество точек, а m
— количество измерений.
редактировать
Это все при условии, что у вас есть евклидово пространство. То есть длина вектора v
равна sqrt(v0^2 + v1^2 + v2^2 + ...)
. Однако, если вы можете выбрать метрику, могут быть и другие варианты оптимизации алгоритма.
Используйте kd-дерево. Вы смотрите на проблему ближайшего соседа, и существуют высокооптимизированные структуры данных для решения именно этого класса проблем.
http://en.wikipedia.org/wiki/Kd-tree
P.S. Веселая проблема!
Запустите PCA для ваших данных, чтобы преобразовать векторы из 100 измерений в, скажем, 20 измерений. Затем создайте дерево K-ближайших соседей (KD-Tree) и получите двух ближайших соседей на основе евклидова расстояния.
Вообще если нет. размеров очень велики, тогда вам нужно либо использовать подход грубой силы (параллельный + распределенный/уменьшение карты), либо подход, основанный на кластеризации.
Используйте структуру данных, известную как KD-TREE. Вам нужно будет выделить много памяти, но вы можете обнаружить одну или две оптимизации на основе ваших данных.
http://en.wikipedia.org/wiki/Kd-дерево.
Мой друг работал над своей кандидатской диссертацией много лет назад, когда столкнулся с похожей проблемой. Его работа была порядка 1 миллиона точек в 10 измерениях. Мы создали библиотеку kd-tree, чтобы решить эту проблему. Возможно, мы сможем раскопать код, если вы захотите связаться с нами в автономном режиме.
Вот его опубликованная статья: http://www.elec.qmul.ac.uk/people/josh/documents/ReissSelbieSandler-WIAMIS2003.pdf