K-D树

学一学K-D树吧。
基本上是搬砖

K-D树

K-D树常用来作空间划分及近邻搜索,是二叉空间划分树的一个特例。通常,对于维度为 k k k,数据点数为 N N N的数据集,K-D树适用于 n < 2 k n < 2^k n<2k的情形。

原理

K-D树是每个节点均为 k k k维数值点的二叉搜索树,每个节点代表一个超平面,该超平面垂直于当前划分维度的坐标轴,并在该维度上将空间划分为两部分,一部分在其左子树,另一部分在其右子树。即若当前节点的划分维度为 d d d,其左子树上所有点在 d d d维的坐标值均小于当前值,右子树上所有点在 d d d维的坐标值均大于等于当前值,本定义对其任意子节点均成立。

构造

一棵平衡的K-D树,其所有叶子节点到根节点的距离近似相等。但一个平衡的K-D树对最近邻搜索、空间搜索等应用场景并非是最优的。常规的K-D树的构建过程为:循环依序取数据点的各维度来作为切分维度,取数据点在该维度的中值作为切分超平面,将中值左侧的数据点挂在其左子树,将中值右侧的数据点挂在其右子树。递归处理其子树,直至所有数据点挂载完毕。

切分维度选择优化

构建开始前,对比数据点在各维度的分布情况,数据点在某一维度坐标值的方差越大分布越分散,方差越小分布越集中。从方差大的维度开始切分可以取得很好的切分效果及平衡性。

中值选择优化

第一种,算法开始前,对原始数据点在所有维度进行一次排序,存储下来,然后在后续的中值选择中,无须每次都对其子集进行排序,提升了性能。
第二种,从原始数据点中随机选择固定数目的点,然后对其进行排序,每次从这些样本点中取中值(或中位数),来作为分割超平面。该方式在实践中被证明可以取得很好性能及很好的平衡性。

寻找d维最小坐标值点

A
若当前节点的切分维度是 d d d,因其右子树节点均大于等于当前节点在 d d d维的坐标值,所以可以忽略其右子树,仅在其左子树进行搜索。若无左子树,当前节点即是最小坐标值节点。

B
若当前节点的切分维度不是 d d d,需在其左子树与右子树分别进行递归搜索。

新增节点

从根节点出发,若待插入节点在当前节点切分维度的坐标值小于当前节点在该维度的坐标值时,在其左子树插入;若大于等于当前节点在该维度的坐标值时,在其右子树插入。递归遍历,直至叶子节点。多次新增节点可能引起树的不平衡。不平衡性超过某一阈值时,需进行再平衡。

删除节点

最简单的方法是将待删节点的所有子节点组成一个新的集合,然后对其进行重新构建。将构建好的子树挂载到被删节点即可。此方法性能不佳,下面考虑优化后的算法。
假设待删节点 T T T的切分维度为 x x x,下面根据待删节点的几类不同情形进行考虑。
A 无子树:
    本 \ \ \ 本    身为叶子节点,直接删除。
B 有右子树:
    在 \ \ \ 在     T . r i g h t T.right T.right寻找 x x x切分维度最小的节点 p p p,然后替换被删节点 T T T;递归处理删除节点 p p p
C 无右子树有左子树:
    在 \ \ \ 在     T . l e f t T.left T.left寻找 x x x切分维度最小的节点 p p p,即 p = f i n d m i n ( T . l e f t , c u t t i n g − d i m = x ) p=findmin(T.left, cutting-dim=x) p=findmin(T.left,cuttingdim=x),然后用节点 p p p替换被删节点 T T T;将原 T . l e f t T.left T.left作为 p . r i g h t p.right p.right;递归处理删除节点 p p p。(之所以未采用 f i n d m a x ( T . l e f t , c u t t i n g − d i m = x ) findmax(T.left, cutting-dim=x) findmax(T.left,cuttingdim=x)节点来替换被删节点,是由于原被删节点的左子树节点存在 x x x维度最大值相等的情形,这样就破坏了左子树在 x x x分割维度的坐标需小于其根节点的定义)

最近邻搜索

给定点 p p p,查询数据集中与其距离最近点的过程即为最近邻搜索。

复杂度分析

新增、删除和搜索,平均都为 l o g ( n ) log(n) log(n),最坏都为 ( O ( n ) ) (O(n)) (O(n))

而OI中,K-D树一般都是解决二维问题。

搬了这么久砖,练练题吧。

K远点对

欧氏距离 欧几里得度量(euclidean metric)(也称欧氏距离)是一个通常采用的距离定义,指在m维空间中两个点之间的真实距离,或者向量的自然长度(即该点到原点的距离)。在二维和三维空间中的欧氏距离就是两点之间的实际距离。

Code:
在这里插入代码片
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值