@markheng
2017-01-17T08:10:19.000000Z
字数 2280
阅读 2727
数据结构
k-d树是查找相邻点很重要的一种数据结构。
索引结构中相似性查询有两种基本的方式:一种是范围查询(range searches),另一种是K近邻查询(K-neighbor searches)。
范围查询就是给定查询点和查询距离的阈值,从数据集中找出所有与查询点距离小于阈值的数据;
K近邻查询是给定查询点及正整数K,从数据集中找到距离查询点最近的K个数据,当K=1时,就是最近邻查询(nearest neighbor searches)。
特征匹配算子可以风风能为两类,一类是线性扫描法(穷举),一类是建立数据索引,然后进行快速匹配。
k-d树是索引树的一种。划分的空间没有混叠(clipping)的,另一种划分空间是有混叠(overlapping)的。
k-d树的算法分为两类,一类是有关k-d树的构建算法,一类是在k-d树上进行邻近查找的算法。
k-d是k-dimension的缩写,是对数据点在k维空间中划分的一种数据结构。k-d树实际上是一种二叉树。
它结点内容包括:
| 数据名 | 类型 | 解释 |
|---|---|---|
| dom_elt | k维的向量 | k维空间中的一个点,k-d树在某个维度以这个点为界进行划分 |
| split | 正数 | 表示进行划分的维数的序号 |
| left | kd-tree | 左子树 |
| right | kd-tree | 右子树 |
注意split是当前结点进行划分的维数的序号,序号只是为了在算法中表示方便,其实就是维度的标识。
算法描述
split选取
选取split时,为了得到较好的划分效果(较高的分辨率),通常做法是,计算每个维度的方差
dom_elt选取
将所有元素按照split维的数值大小进行排序,取最中间的那个元素作为dom_elt。
建立子树
假设ele为k维空间中的任意,对dom_elt一侧的数据(
伪代码
算法:构建k-d树(build_kd_tree)
输入:k维点集ele_set
输出:k-d树 kd_t
- 如果ele_set 为空,则返回空
- 调用选择分裂点的子程序,得到分裂点dom_elt和分裂的维度split
- ele_set_left =
{e|e∈ele_set,e[split]≤dom_elt[split]}
ele_set_right ={e|e∈ele_set,e[split]>dom_elt[split]} - build_kd_tree(ele_set_left)
build_kd_tree(ele_set_right)
分裂点指的是结点中的dom_elt值,标识了当前分裂的界线。
算法:k-d树查找target点的最近邻点(find_kd_tree)输入:k-d树kd_tree, 目标点 target输出:目标的最近邻点nearest, 最近距离dist1. 如果kd_tree为空,则设dist为无穷大,返回2. 搜索k-d树直到叶子结点,记录搜索过的路径pSearch 指向 kd_tree的根节点while(pSearch指向的结点p不是叶子结点){将p加入到search_path中if(target[p.split] <= p.dom_elt[p.split]){pSearch指向当前结点的左子树}else{pSearch指向当前结点的右子树}}取出search_path中最后一个赋值给nearestdist = Distance(nearest, target)3. 回溯搜索路径while(search_path 不为空){pBack = search_path最后一个元素if(pBack 为叶子结点){if(Distance(nearset, target) >Distance(pBack->dom_elt, target) ){nearset = pBack->dom_eltdist = Distance(pBack->dom_elt, target)}}else{s = pBack->splitif(abs(pBack->dom_elt[s] - target[s]) < dist){if( Distance(nearest, target) >Distance(pBack->dom_elt, target) ){nearest = pBack->dom_elt;dist = Distance(pBack->dom_elt, target);}if(target[s] <= pBack->dom_elt[s])pSearch = pBack->right;elsepSearch = pBack->left;if(pSearch != NULL)pSearch加入到search_path中}}}}
参考:
http://underthehood.blog.51cto.com/2531780/687160
k-d tree wikipedia
http://www.cnblogs.com/eyeszjwang/articles/2429382.html