zoukankan      html  css  js  c++  java
  • KD Tree

    最近在项目中用到了,特地搬运过来。

    Kd-树 其实是K-dimension tree的缩写,是对数据点在k维空间中划分的一种数据结构。其实,Kd-树是一种平衡二叉树。

    举一示例:

    假设有六个二维数据点 = {(2,3),(5,4),(9,6),(4,7),(8,1),(7,2)},数据点位于二维空间中。为了能有效的找到最近邻,Kd-树采用分而治之的思想,即将整个空间划分为几个小部分。六个二维数据点生成的Kd-树的图为:

    File:Kdtree 2d.svgFile:Tree 0001.svg

                              图1                                                                                           图2

    而在三维空间中,则是这个样子的

    对于拥有n个已知点的kD-Tree,其复杂度如下:

    1. 构建:O(log2n)
    2. 插入:O(log n)
    3. 删除:O(log n)
    4. 查询:O(n1-1/k+m) m---每次要搜索的最近点个数

     Kd-树的构建

    Kd-树是一个二叉树,每个节点表示的是一个空间范围。下表表示的是Kd-树中每个节点中主要包含的数据结构。Range域表示的是节点包含的空间范围。Node-data域就是数据集中的某一个n维数据点。分割超面是通过数据点Node-Data并垂直于轴split的平面,分割超面将整个空间分割成两个子空间。令split域的值为i,如果空间Range中某个数据点的第i维数据小于Node-Data[i],那么,它就属于该节点空间的左子空间,否则就属于右子空间。Left,Right域分别表示由左子空间和右子空间空的数据点构成的Kd-树。

    域名

    数据类型

    描述

    Node-Data

    数据矢量

    数据集中某个数据点,是n维矢量

    Range

    空间矢量

    该节点所代表的空间范围

    Split

    整数

    垂直于分割超面的方向轴序号

    Left

    Kd-tree

    由位于该节点分割超面左子空间内所有数据点构成的Kd-树

    Right

    Kd-tree

    由位于该节点分割超面左子空间内所有数据点构成的Kd-树

    Parent

    Kd-tree

    父节点

    构建Kd-树的伪码为:

    算法:构建Kd-tree

    输入:数据点集Data_Set,和其所在的空间。

    输出:Kd,类型为Kd-tree

    1 if data-set is null ,return 空的Kd-tree

    2 调用节点生成程序

     (1)确定split域:对于所有描述子数据(特征矢量),统计他们在每个维度上的数据方差,挑选出方差中最大值,对应的维就是split域的值。数据方差大说明沿该坐标轴方向上数据点分散的比较开。这个方向上,进行数据分割可以获得最好的分辨率。

    (2)确定Node-Data域,数据点集Data-Set按照第split维的值排序,位于正中间的那个数据点 被选为Node-Data,Data-Set` =Data-SetNode-data

    3 dataleft = {d 属于Data-Set` & d[:split]<=Node-data[:split]}

       Left-Range ={Range && dataleft}

      dataright = {d 属于Data-Set` & d[:split]>Node-data[:split]}

      Right-Range ={Range && dataright}

    4:left = 由(dataleft,LeftRange)建立的Kd-tree

       设置:left的parent域(父节点)为Kd

      :right = 由(dataright,RightRange)建立的Kd-tree

      设置:right的parent域为kd。

    如上例中,

    (1)确定:split 域=x,6个数据点在x,y 维度上的数据方差为39,28.63.在x轴方向上的方差大,所以split域值为x。

    (2)确定:Node-Data=(7,2),根据x维上的值将数据排序,6个数据的中值为7,所以node-data域为数据点(7,2)。这样该节点的分割超面就是通过(7,2)并垂直于:split=x轴的直线x=7.

    (3)左子空间和右子空间,分割超面x=7将整个空间分为两部分。x<=7 为左子空间,包含节点(2,3),(5,4),(4,7),另一部分为右子空间。包含节点(9,6),(8,1)

    这个构建过程是一个递归过程。重复上述过程,直至只包含一个节点。

  • 相关阅读:
    hlgoj 1766 Cubing
    Reverse Linked List
    String to Integer
    Bitwise AND of Numbers Range
    Best Time to Buy and Sell Stock III
    First Missing Positive
    Permutation Sequence
    Next Permutation
    Gray Code
    Number of Islands
  • 原文地址:https://www.cnblogs.com/kevingeek/p/3891479.html
Copyright © 2011-2022 走看看