k -d дерево
k -d дерево | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Тип | Многомерное БСТ | |||||||||||||||||||||||
Изобретенный | 1975 | |||||||||||||||||||||||
Изобретён | Джон Луис Бентли | |||||||||||||||||||||||
|
В информатике k - d дерево (сокращение от k-мерного дерева ) — это с разделением пространства структура данных для организации точек в k -мерном пространстве . K-мерным называется то, что касается ровно k ортогональных осей или пространства любого числа измерений . [1] Деревья k -d являются полезной структурой данных для нескольких приложений, таких как:
- Поиски с использованием многомерного ключа поиска (например, поиск по диапазону и поиск ближайшего соседа ) и
- Создание облаков точек .
k -d-деревья — это частный случай деревьев разбиения двоичного пространства .
Описание
[ редактировать ]Дерево k -d — это двоичное дерево , в котором каждый узел представляет собой k -мерную точку. [2] Каждый нелистовой узел можно рассматривать как неявно генерирующий разделяющую гиперплоскость , которая делит пространство на две части, известные как полупространства . Точки слева от этой гиперплоскости представлены левым поддеревом этого узла, а точки справа от гиперплоскости представлены правым поддеревом. Направление гиперплоскости выбирается следующим образом: каждый узел дерева связан с одним из k измерений, причем гиперплоскость перпендикулярна оси этого измерения. Так, например, если для конкретного разделения выбрана ось «x», все точки поддерева с меньшим значением «x», чем узел, появятся в левом поддереве, а все точки с большим значением «x» будут отображаться в левом поддереве. находиться в правом поддереве. В таком случае гиперплоскость будет задана значением x точки, а ее нормаль будет единичной осью x. [3]
Операции над k -d деревьями
[ редактировать ]Строительство
[ редактировать ]Поскольку существует много возможных способов выбора плоскостей расщепления, ориентированных по осям, существует много разных способов построения k -d деревьев. Канонический метод построения k -d дерева имеет следующие ограничения: [4]
- При движении вниз по дереву происходит циклическое переключение осей, используемых для выбора плоскостей разделения. (Например, в трехмерном дереве корень будет иметь плоскость, выровненную по оси X , оба дочерних элемента корня будут иметь плоскости, выровненные по оси Y , все внуки корня будут иметь плоскости , выровненные по оси Z , все правнуки корня будут иметь плоскости, выровненные по оси Z. имеют плоскости, ориентированные по оси x , все праправнуки корня будут иметь плоскости, выровненные по оси y , и так далее.)
- Точки вставляются путем выбора медианы точек, помещаемых в поддерево , относительно их координат на оси, используемой для создания плоскости разделения. вводим в алгоритм весь набор из n точек.) (Обратите внимание на предположение, что мы заранее
Этот метод приводит к сбалансированному k -d дереву, в котором каждый листовой узел находится примерно на одинаковом расстоянии от корня. Однако сбалансированные деревья не обязательно оптимальны для всех приложений.
не требуется Обратите внимание, что выбирать срединную точку . В случае, когда медианные точки не выбраны, нет никакой гарантии, что дерево будет сбалансированным. Чтобы избежать кодирования сложного поиска медианы алгоритм [5] [6] или с помощью Для сортировки, такой как пирамидальная сортировка или сортировка слиянием, для сортировки всех n точек, популярной практикой является сортировка фиксированного числа случайно выбранных точек и использование медианы этих точек в качестве плоскости разделения. На практике этот метод часто приводит к хорошо сбалансированным деревьям.
Учитывая список из n точек, следующий алгоритм использует сортировку с поиском медианы для построения сбалансированного дерева k -d, содержащего эти точки.
function kdtree (list of points pointList, int depth){ // Select axis based on depth so that axis cycles through all valid values var int axis := depth mod k; // Sort point list and choose median as pivot element select median by axis from pointList; // Create node and construct subtree node.location := median; node.leftChild := kdtree(points in pointList before median, depth+1); node.rightChild := kdtree(points in pointList after median, depth+1); return node;}
Обычно точки «после» медианы включают только те, которые строго больше медианы в текущем измерении. Для точек, лежащих на медиане текущего измерения, можно определить функцию, которая сравнивает их во всех измерениях. В некоторых случаях допустимо, чтобы точки, равные медиане, лежали по одну сторону от медианы, например, путем разделения точек на подмножество «меньше чем» и подмножество «больше или равно».
Этот алгоритм создает инвариант , согласно которому для любого узла все узлы левого поддерева находятся на одной стороне плоскости разбиения , а все узлы правого поддерева — на другой стороне. Точки, лежащие на плоскости расщепления, могут появиться с любой стороны. Плоскость разделения узла проходит через точку, связанную с этим узлом (называемую в коде node.location ).
Альтернативные алгоритмы построения сбалансированного k дерева -d предварительно сортируют данные перед построением дерева. Затем они поддерживают порядок предварительной сортировки во время построения дерева и, следовательно, исключают дорогостоящий этап поиска медианы на каждом уровне подразделения. Два таких алгоритма строят сбалансированное k -d дерево для сортировки треугольников, чтобы улучшить время выполнения трассировки лучей для трёхмерной компьютерной графики . Эти алгоритмы предварительно сортируют n треугольников перед построением дерева k -d , а затем строят дерево за время в лучшем случае. [7] [8] Алгоритм, который строит сбалансированное k -d дерево для сортировки точек, имеет сложность в наихудшем случае . [9] [10] Этот алгоритм предварительно сортирует n точек в каждом из k измерений, используя сортируйте, например пирамидальную сортировку или сортировку слиянием, перед построением дерева. Затем он сохраняет порядок этих k предварительных сортировок во время построения дерева и тем самым позволяет избежать поиска медианы на каждом уровне подразделения.
Добавление элементов
[ редактировать ]Этот раздел нуждается в расширении . Вы можете помочь, добавив к нему . ( ноябрь 2008 г. ) |
-d добавляется новая точка В дерево k так же, как добавляется элемент в любое другое дерево поиска . Сначала пройдите по дереву, начиная с корня и перемещаясь либо к левому, либо к правому дочернему элементу в зависимости от того, находится ли вставляемая точка на «левой» или «правой» стороне плоскости разделения. Как только вы доберетесь до узла, под которым должен располагаться дочерний элемент, добавьте новую точку в качестве левого или правого дочернего элемента листового узла, опять же в зависимости от того, на какой стороне плоскости разделения узла находится новый узел.
Добавление точек таким образом может привести к разбалансировке дерева, что приведет к снижению производительности дерева. Скорость снижения производительности дерева зависит от пространственного распределения добавляемых точек дерева и количества добавляемых точек в зависимости от размера дерева. Если дерево становится слишком несбалансированным, возможно, потребуется его повторная балансировка, чтобы восстановить производительность запросов, основанных на балансировке дерева, таких как поиск ближайшего соседа.
Удаление элементов
[ редактировать ]Этот раздел нуждается в расширении . Вы можете помочь, добавив к нему . ( февраль 2011 г. ) |
Чтобы удалить точку из существующего дерева k -d, не нарушая инвариант, самый простой способ — сформировать набор всех узлов и листьев из дочерних элементов целевого узла и воссоздать эту часть дерева. [11]
Другой подход — найти замену удаленной точке. [12] Сначала найдите узел который содержит точку, которую нужно удалить. Для базового случая, когда R — листовой узел, замена не требуется. Для общего случая найдите точку замены, скажем , из поддерева с корнем в . Замените точку, сохраненную в с . Затем рекурсивно удалите .
Для поиска точки замены, если дискриминирует (сказать) и имеет правильный дочерний элемент, найдите точку с минимумом значение из поддерева, корнем которого является правый дочерний элемент. В противном случае найдите точку с максимальным значение из поддерева, корнем которого является левый дочерний элемент.
Балансировка
[ редактировать ]Балансировка дерева k -d требует осторожности, поскольку деревья k -d сортируются в нескольких измерениях, поэтому технику вращения дерева нельзя использовать для их балансировки, поскольку это может нарушить инвариант.
Существует несколько вариантов сбалансированных k -d деревьев. К ним относятся разделенное k -d-дерево, псевдо- k -d-дерево, KDB-дерево , hB-дерево и Bkd-дерево . Многие из этих вариантов являются адаптивными деревьями kd .
Поиск ближайшего соседа
[ редактировать ]Алгоритм поиска ближайшего соседа (NN) направлен на поиск точки в дереве, ближайшей к заданной входной точке. Этот поиск можно выполнить эффективно, используя свойства дерева для быстрого исключения больших частей пространства поиска.
Поиск ближайшего соседа в дереве k -d происходит следующим образом:
- Начиная с корневого узла, алгоритм рекурсивно перемещается вниз по дереву, так же, как если бы была вставлена точка поиска (т. е. он идет влево или вправо в зависимости от того, меньше или больше точка текущего узла в дереве). разделенное измерение).
- Как только алгоритм достигает конечного узла, он проверяет узловую точку, и если расстояние лучше, чем «текущее лучшее», эта узловая точка сохраняется как «текущее лучшее».
- Алгоритм раскручивает рекурсию дерева, выполняя на каждом узле следующие шаги:
- Если текущий узел находится ближе, чем текущий лучший, то он становится текущим лучшим.
- Алгоритм проверяет, могут ли быть какие-либо точки на другой стороне плоскости разделения, которые находятся ближе к точке поиска, чем текущая лучшая точка. Теоретически это делается путем пересечения гиперплоскости разделения с гиперсферой вокруг точки поиска, радиус которой равен текущему ближайшему расстоянию. Поскольку все гиперплоскости выровнены по осям, это реализовано как простое сравнение, чтобы увидеть, меньше ли расстояние между координатой разделения точки поиска и текущим узлом, чем расстояние (общие координаты) от точки поиска до текущего наилучшего значения.
- Если гиперсфера пересекает плоскость, на другой стороне плоскости могут быть более близкие точки, поэтому алгоритм должен двигаться вниз по другой ветви дерева от текущего узла в поисках более близких точек, следуя тому же рекурсивному процессу, что и весь поиск. .
- Если гиперсфера не пересекает плоскость разбиения, алгоритм продолжает движение вверх по дереву, и вся ветвь на другой стороне этого узла удаляется.
- Когда алгоритм завершит этот процесс для корневого узла, поиск будет завершен.
Обычно алгоритм использует квадраты расстояний для сравнения, чтобы избежать вычисления квадратных корней. Кроме того, он может сэкономить вычисления, сохраняя квадрат текущего наилучшего расстояния в переменной для сравнения.
Алгоритм можно расширить несколькими способами путем простых модификаций. Он может предоставить k ближайших соседей для точки, сохраняя k текущих лучших значений вместо одного. Ветка удаляется только тогда, когда k найдено очков, и у ветки не может быть очков ближе, чем к любому из k текущих лучших результатов.
Его также можно преобразовать в алгоритм аппроксимации для более быстрой работы. Например, приблизительный поиск ближайшего соседа может быть достигнут путем простой установки верхней границы числа точек для проверки в дереве или прерывания процесса поиска на основе часов реального времени (что может быть более подходящим в аппаратных реализациях). Ближайшего соседа для точек, которые уже есть в дереве, можно получить, не обновляя уточнение для узлов, которые дают нулевое расстояние. В результате этого есть обратная сторона: отбрасываются точки, которые не являются уникальными, но расположены рядом с исходной точкой поиска.
Приблизительный ближайший сосед полезен в приложениях реального времени, таких как робототехника, из-за значительного увеличения скорости, получаемого за счет отсутствия исчерпывающего поиска лучшей точки. Одна из его реализаций — поиск по принципу «сначала лучший бин» .
Поиск диапазона
[ редактировать ]Поиск по диапазону ищет диапазоны параметров. Например, если в дереве хранятся значения, соответствующие доходу и возрасту, то поиск по диапазону может быть чем-то вроде поиска всех членов дерева с возрастом от 20 до 50 лет и доходом от 50 000 до 80 000. Поскольку деревья kd делят диапазон домена пополам на каждом уровне дерева, они полезны для выполнения поиска по диапазону.
Анализ двоичных деревьев поиска показал, что наихудшее время поиска диапазона в k -мерном k -d дереве, содержащем n узлов, определяется следующим уравнением. [13]
Снижение производительности при работе с многомерными данными
[ редактировать ]Поиск ближайшей точки – это операция в среднем, в случае случайно распределенных точек, хотя анализ в целом сложен. [14]
В многомерных пространствах из-за проклятия размерности алгоритму приходится посещать гораздо больше ветвей, чем в низкомерных пространствах. В частности, когда количество точек лишь немного превышает количество измерений, алгоритм лишь немного лучше, чем линейный поиск по всем точкам. Как правило, если размерность равна k , количество точек в данных n должно быть равно . В противном случае, когда деревья k -d используются с многомерными данными, большинство точек в дереве будут оценены, и эффективность будет не лучше, чем исчерпывающий поиск. [15] и, если требуется достаточно хороший быстрый ответ, вместо этого следует использовать приближенные методы ближайших соседей.
Снижение производительности, когда точка запроса находится далеко от точек в дереве k -d.
[ редактировать ]Кроме того, даже в низкоразмерном пространстве, если среднее попарное расстояние между k ближайшими соседями точки запроса значительно меньше, чем среднее расстояние между точкой запроса и каждым из k ближайших соседей, производительность поиска ближайшего соседа снижается в сторону линейная, поскольку расстояния от точки запроса до каждого ближайшего соседа имеют одинаковую величину. (В худшем случае рассмотрим облако точек, распределенных на поверхности сферы с центром в начале координат. Каждая точка равноудалена от начала координат, поэтому при поиске ближайшего соседа от начала координат пришлось бы перебирать все точки в начале координат. поверхность сферы для идентификации ближайшего соседа – который в данном случае даже не уникален.)
Чтобы смягчить потенциально значительное ухудшение производительности поиска по дереву k -d в худшем случае, в алгоритм поиска по дереву может быть предоставлен параметр максимального расстояния , а рекурсивный поиск может быть сокращен всякий раз, когда ближайшая точка в данной ветви дерева не может быть ближе, чем это максимальное расстояние. Это может привести к тому, что поиск ближайшего соседа не сможет вернуть ближайшего соседа, что означает, что ни одна точка не находится в пределах этого максимального расстояния от точки запроса.
Сложность
[ редактировать ]- Построение статического дерева k -d из n точек имеет следующую сложность в худшем случае:
- О ( нлог 2 n ) если сортировка O ( n log n ), такая как пирамидальная сортировка или сортировка слиянием, используется для нахождения медианы на каждом уровне рождающегося дерева;
- O ( n log n ), если O ( n ) медианы алгоритм [5] [6] используется для выбора медианы на каждом уровне рождающегося дерева;
- O ( kn log n ), если n точек предварительно сортируются в каждом из k измерений с использованием сортировки O ( n log n ) , такой как пирамидальная сортировка или сортировка слиянием, перед построением k дерева -d . [10]
- Вставка новой точки в сбалансированное k -d дерево занимает время O (log n ) .
- Удаление точки из сбалансированного k -d дерева занимает время O (log n ) .
- Запрос диапазона, параллельного осям, в сбалансированном дереве k -d занимает O ( n 1−1/к + m ) время, где m — количество сообщаемых точек, а k — размерность k -d дерева.
- Поиск одного ближайшего соседа в сбалансированном k -d дереве со случайно распределенными точками занимает O (log n ) . в среднем время
Вариации
[ редактировать ]Объемные объекты
[ редактировать ]Вместо точек дерево k -d также может содержать прямоугольники или гиперпрямоугольники . [16] [17] Таким образом, поиск диапазона становится проблемой возврата всех прямоугольников, пересекающих прямоугольник поиска. Дерево строится обычным способом со всеми прямоугольниками на листьях. При поиске ортогонального диапазона . при сравнении с медианой используется противоположная координата Например, если текущий уровень разделен по x high , мы проверяем координату x low прямоугольника поиска. Если медиана меньше нижней координаты x прямоугольника поиска, то ни один прямоугольник в левой ветви не может когда-либо пересекаться с прямоугольником поиска и поэтому может быть обрезан. В противном случае придется пересечь обе ветви. См. также дерево интервалов , которое является одномерным особым случаем.
Точки только в листьях
[ редактировать ]Также возможно определить дерево k -d с точками, хранящимися исключительно в листьях. [4] Эта форма дерева k -d допускает различные механизмы разделения, отличные от стандартного медианного разделения. Правило разделения по средней точке [18] выбирает середину самой длинной оси искомого пространства, независимо от распределения точек. Это гарантирует, что соотношение сторон будет не более 2:1, но глубина зависит от распределения точек. Вариант, называемый скользящей средней точкой, разделяется посередине только в том случае, если по обе стороны от разделения есть точки. В противном случае он разбивается в точке, ближайшей к середине. Манивонгватана и Маунт показывают, что это обеспечивает «достаточно хорошую» производительность на обычных наборах данных.
Используя скользящую среднюю точку, на приблизительный запрос ближайшего соседа в можно получить ответ .Приблизительный подсчет диапазона можно получить в с этим методом.
См. также
[ редактировать ]Близкие варианты:
- неявное k дерево -d , дерево k -d, определяемое неявной функцией расщепления, а не явно сохраненным набором расщеплений.
- min/max k -d Tree , k -d дерево, которое связывает минимальное и максимальное значение с каждым из своих узлов.
- Расслабленное k -d дерево , k -d дерево такое, что дискриминанты в каждом узле произвольны.
Связанные варианты:
- Quadtree — структура разделения пространства, которая одновременно разбивается на два измерения, так что каждый узел имеет 4 дочерних элемента.
- Octree — структура разделения пространства, которая одновременно разбивается на три измерения, так что каждый узел имеет 8 дочерних элементов.
- Дерево шаров — многомерное разбиение пространства, полезное для поиска ближайших соседей.
- R-дерево и иерархия ограничивающих интервалов , структура для разделения объектов, а не точек, с перекрывающимися областями
- Дерево точек обзора , вариант дерева k -d, в котором для разделения данных используются гиперсферы вместо гиперплоскостей.
Проблемы, которые можно решить с помощью k -d деревьев:
- Рекурсивное разделение — метод построения статистических деревьев решений, похожих на k -d. деревья
- Проблема меры Клее — задача вычисления площади объединения прямоугольников, решаемая с помощью k -d деревьев.
- Задача гильотины — задача поиска k -d дерева, ячейки которого достаточно велики, чтобы содержать заданный набор прямоугольников.
Реализации с открытым исходным кодом
[ редактировать ]- ALGLIB имеет C# и C++ реализации алгоритмов ближайшего соседа на основе k -d дерева и приближенных алгоритмов ближайшего соседа.
- CGAL, библиотека вычислительных алгоритмов, содержит реализации алгоритмов ближайшего соседа на основе k -d дерева, приблизительного ближайшего соседа, а также алгоритмов поиска диапазона.
- SciPy , библиотека Python для научных вычислений, содержит реализации алгоритмов поиска ближайшего соседа на основе дерева k -d.
- scikit-learn , библиотека Python для машинного обучения, содержит реализации k -d деревьев для поддержки поиска ближайших соседей и соседей по радиусу.
Ссылки
[ редактировать ]- ^ «k-мерный» . xlinux.nist.gov . Проверено 17 сентября 2023 г.
- ^ Христов, Христо (29 марта 2023 г.). «Введение в деревья КД» . Баелдунг .
- ^ Бентли, Дж.Л. (1975). «Многомерные двоичные деревья поиска, используемые для ассоциативного поиска» . Коммуникации АКМ . 18 (9): 509–517. дои : 10.1145/361002.361007 . S2CID 13091446 .
- ^ Перейти обратно: а б Берг, Марк де; Чеонг, Отфрид; Кревелд, Марк ван; Овермарс, Марк (2008). «Поиск ортогонального диапазона». Вычислительная геометрия . стр. 95–120. дои : 10.1007/978-3-540-77974-2_5 . ISBN 978-3-540-77973-5 .
- ^ Перейти обратно: а б Блюм, М .; Флойд, RW ; Пратт, Вирджиния ; Ривест, РЛ ; Тарьян, Р.Э. (август 1973 г.). «Сроки выбора» (PDF) . Журнал компьютерных и системных наук . 7 (4): 448–461. дои : 10.1016/S0022-0000(73)80033-9 .
- ^ Перейти обратно: а б Кормен, Томас Х .; Лейзерсон, Чарльз Э .; Ривест, Рональд Л. Введение в алгоритмы . MIT Press и McGraw-Hill. Глава 10
- ^ Вальд I, Гавран V (сентябрь 2006 г.). «О построении быстрых kd-деревьев для трассировки лучей и о том, как сделать это за O (N log N)» (PDF) . Симпозиум IEEE 2006 г. по интерактивной трассировке лучей . стр. 61–69. дои : 10.1109/RT.2006.280216 . ISBN 1-4244-0693-5 . S2CID 1603250 .
- ^ Хавран В., Биттнер Дж. (2002). «Об улучшении деревьев КД для лучевой стрельбы» (PDF) . В: Труды WSCG : 209–216.
- ^ Прокопюк, Т; Агарвал, М; Арге, Л; Виттнер, Дж (2003). «Bkd-дерево: динамическое масштабируемое kd-дерево». В Хадзилакосе, Т; Манолопулос, Ю; Роддик, Дж; Теодоридис, Ю. (ред.). Конспекты лекций по информатике . Том. 2750. Берлин: Springer-Verlag. стр. 46–65.
- ^ Перейти обратно: а б Браун Р. (2015). «Построение сбалансированного k -d дерева за время O( kn log n ) » . Журнал методов компьютерной графики . 4 (1): 50–68.
- ^ Христов, Христо (29 марта 2023 г.). «Введение в деревья КД» . Баелдунг .
- ^ Чандран, Шарат. Введение в kd-деревья . Факультет компьютерных наук Университета Мэриленда.
- ^ Ли, DT; Вонг, СК (1977). «Анализ наихудшего случая для поиска областей и частичных областей в многомерных двоичных деревьях поиска и сбалансированных квадродеревьях». Акта Информатика . 9 . дои : 10.1007/BF00263763 . S2CID 36580055 .
- ^ Фридман, Дж. Х .; Бентли, Джей Лей ; Финкель, Р.А. (1977). «Алгоритм поиска лучших совпадений в логарифмическом ожидаемом времени». Транзакции ACM в математическом программном обеспечении . 3 (3): 209. дои : 10.1145/355744.355745 . ОСТИ 1443274 . S2CID 10811510 .
- ^ Джейкоб Э. Гудман , Джозеф О'Рурк и Петр Индик , изд. (2004). «Глава 39: Ближайшие соседи в многомерных пространствах». Справочник по дискретной и вычислительной геометрии (2-е изд.). ЦРК Пресс.
- ^ Розенберг, Дж. Б. (1985). «Сравнение географических структур данных: исследование структур данных, поддерживающих запросы к регионам». Транзакции IEEE по автоматизированному проектированию интегральных схем и систем . 4 : 53–67. дои : 10.1109/TCAD.1985.1270098 . S2CID 31223074 .
- ^ Хаутхейс, П. (1987). «Box Sort, метод многомерной двоичной сортировки прямоугольных блоков, используемый для быстрого поиска диапазона». Визуальный компьютер . 3 (4): 236–249. дои : 10.1007/BF01952830 . S2CID 3197488 .
- ^ С. Манивонгватана и Д.М. Маунт . Быть худым — это нормально, если твои друзья толстые . 4-й ежегодный семинар CGC по вычислительной геометрии, 1999 г.