kd-tree

Kd-Tree算法原理和开源实现代码

痞子三分冷 提交于 2020-12-19 15:45:45
一、Kd-tree Kd-Tree,即K-dimensional tree,是一棵二叉树,树中存储的是一些K维数据。在一个K维数据集合上构建一棵Kd-Tree代表了对该K维数据集合构成的K维空间的一个划分,即树中的每个结点就对应了一个K维的超矩形区域(Hyperrectangle)。 在介绍Kd-tree的相关算法前,我们先回顾一下二叉查找树(Binary Search Tree)的相关概念和算法。 二叉查找树(Binary Search Tree,BST),是具有如下性质的二叉树(来自wiki): 1)若它的左子树不为空,则左子树上所有结点的值均小于它的根结点的值; 2)若它的右子树不为空,则右子树上所有结点的值均大于它的根结点的值; 3)它的左、右子树也分别为二叉排序树; 例如,图1中是一棵二叉查找树,其满足BST的性质。 图1 二叉查找树(来源:Wiki) 给定一个1维数据集合,怎样构建一棵BST树呢?根据BST的性质就可以创建,即将数据点一个一个插入到BST树中,插入后的树仍然是BST树,即根结点的左子树中所有结点的值均小于根结点的值,而根结点的右子树中所有结点的值均大于根结点的值。 将一个1维数据集用一棵BST树存储后,当我们想要查询某个数据是否位于该数据集合中时,只需要将查询数据与结点值进行比较然后选择对应的子树继续往下查找即可,查找的平均时间复杂度为:O(logN)

机器学习——详解KD-Tree原理

混江龙づ霸主 提交于 2020-04-08 10:53:25
本文始发于个人公众号: TechFlow ,原创不易,求个关注 今天是机器学习的 第15篇文章 ,之前的文章当中讲了Kmeans的相关优化,还讲了大名鼎鼎的EM算法。有些小伙伴表示喜欢看这些硬核的,于是今天上点硬菜,我们来看一个机器学习领域经常用到的数据结构—— KD-Tree 。 从线段树到KD树 在讲KD树之前,我们先来了解一下 线段树 的概念。线段树在机器学习领域当中不太常见,作为高性能维护的数据结构,经常出现在各种算法比赛当中。线段树的本质是一棵维护一段区间的平衡二叉树。 比如下图就是一个经典的线段树: 从下图当中我们不难看出来,这棵线段树维护的是一个 区间内的最大值 。比如树根是8,维护的是整个区间的最大值,每一个中间节点的值都是以它为树根的子树中所有元素的最大值。 通过线段树,我们可以在 的时间内计算出某一个 连续区间的最大值 。比如我们来看下图: 当我们要求被框起来的区间中的最大值,我们只需要 找到能够覆盖这个区间的中间节点 就行。我们可以发现被红框框起来的两个节点的子树刚好覆盖这个区间,于是整个区间的最大值,就是这两个元素的最大值。这样,我们就把一个需要 查找的问题降低成了 ,不但如此,我们也可以 做到 复杂度内的更新 ,也就是说我们不但可以快速查询,还可以更新线段当中的元素。 当然线段树的应用非常广泛,也有 许多种变体 ,这里我们不过多深入

kd-Tree 【专题@AbandonZHANG】

半腔热情 提交于 2020-04-02 03:34:58
刚开始学习,介绍先搁着~等理解透彻了再来写~~~ 我是学习的mzry1992(UESTC_Izayoi ~)------ http://www.mzry1992.com/blog/miao/kd%E6%A0%91.html 先去看mzry1992大牛博客里的讲解吧。。。 再附两篇论文:(看英文看得好爽。。。~@.@) 《An intoductory tutorial on kd-trees》  ★(里面就介绍了kd-tree和nearest neighbour algorithm(最近邻算法)、Q nearest neighbour(Q近邻) ) 《Range Searching Using Kd-Tree.》 kd-tree入门题:    HDOJ 2966 In case of failure (最近邻,模板~)   查找平面点最近点的距离(此题中是距离的平方) /* HDOJ 2966 KD-Tree模板 */ #include #include #include #include #include #include #include #include #include #include #include #define MID(x, y) ( (x + y)>>1 ) using namespace std; typedef long long LL; //KD

【learning】kd-tree

眉间皱痕 提交于 2020-02-07 05:56:39
吐槽   ​ kd-tree这个东西很早就听说过了但是qwq一直没有去了解   ​ (原因的话。。啊哈哈听说是什么跟二维平面之类的东西有关的所以就怂掉了qwq没错就是怂qwq)   ​ 但其实好像。。真的很暴力啊qwq知道思路之后随便乱搞系列qwq   ​ 时间复杂度什么的应该是玄学恩qwq(网上看到有dalao说期望复杂度是O(n^(d-1)/d),不会证就是这样qwq)   ​ 正题   ​ 首先kd-tree是一棵类似二叉查找树的东西   ​ 拿二维的kd-tree为例,每个数据有两个关键值 \(x\) 和 \(y\)   ​ 那么kd-tree的总的思路就是,每层根据一个关键值(记为 \(val\) 好了)来排序,这两个关键值轮着来(其实就是。。第一层按照 \(x\) 排序,第二层 \(y\) ,然后第三层又是 \(x\) ,以此类推)   ​ kd-tree满足的性质是, \(x\) 左子树中所有节点的 \(val\) 小于 \(x\) 的 \(val\) ,右子树中所有节点的 \(val\) 大于 \(x\) 的 \(val\)   ​   ​ 比如说我们现在要构建 \(n\) 组数据的kd-tree,那么方法很简单   ​ 首先stl有一个十分吼的东西叫做nth_element(),具体用法是将 \([l,r]\) 这个区间内的第 \(k\) 个数放到这段区间中的第

[BZOJ4520][Cqoi2016]K远点对 kd-tree 优先队列

二次信任 提交于 2020-02-06 01:44:24
4520: [Cqoi2016]K远点对 Time Limit: 30 Sec Memory Limit: 512 MB Submit: 1285 Solved: 708 [ Submit ][ Status ][ Discuss ] Description 已知平面内 N 个点的坐标,求欧氏距离下的第 K 远点对。 Input 输入文件第一行为用空格隔开的两个整数 N, K。接下来 N 行,每行两个整数 X,Y,表示一个点 的坐标。1 < = N < = 100000, 1 < = K < = 100, K < = N*(N−1)/2 , 0 < = X, Y < 2^31。 Output 输出文件第一行为一个整数,表示第 K 远点对的距离的平方(一定是个整数)。 Sample Input 10 5 0 0 0 1 1 0 1 1 2 0 2 1 1 2 0 2 3 0 3 1 Sample Output 9 HINT Source kd-tree可以查询每个点到其他点的距离。 我们求出每两个点间的距离,随后求出第2*k大值即可。 用优先队列维护前2*k大值,在kd-tree上查询并修改即可。 1 #include<iostream> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cstdio> 5 #include

kd-tree 小结

▼魔方 西西 提交于 2019-12-21 08:48:23
核心思想 是一种分割 \(k\) 维数据空间的数据结构 一维情况下就是平衡树,以 \(key\) 为标准判断插入左儿子还是右儿子 \(kdtree\) 就是平衡树在多维空间的扩展 因为有多维,我们按不同维度交错作为关键字进行插入与查询 如:第一层按照第一维排序,第二层按照第二维排序,第 \(k\) 层按照第 \(k\) 维排序 每一层取该维的中位数,把空间中的点分割开来,分别作为当前点的左右儿子,直到该层只有一个点停止 实现与运用 在 \(OI\) 中,运用最多的是二维的情况,一般当作优秀的暴力来用 如查询离某个点最远/近的点,插入一个点........ 首先可以定义一个类,方便每一层排序和分割使用,定义一个重载运算符 \([x]\) 就可以方便的以第 \(x\) 维排序了 struct data{ int a[K],mn[K],mx[K],l,r; inline int& operator [](int x){return a[x];} }t[N]; inline bool operator <(data p,data q){return p[D]<q[D];} \(build\) 操作 inline int build(int l,int r,int k){ D=k; int mid=(l+r)>>1,o=mid; nth_element(t+l,t+mid,t+r+1);

KD-tree讲解

匿名 (未验证) 提交于 2019-12-03 00:02:01
KD-tree 讲解 by simb351    在OI中的应用更是少之又少。 虽然这东西很水,随便嘴一嘴就能口胡出来。 所以写一篇讲解。 前置芝士: 1. 基础BST姿势 2. 替罪羊树 3. 优良的空间感 比如能脑补出k维空间QWQ KD-tree的应用:    KD-tree主要解决对K维数据的管理,比如多维偏序。但是本弱发现目前OI中KD-tree主流考法为 维护 二维平面中区间的信息。比如ION 9102 弹跳 但是好像能被菜鸡simba口胡的暴力算几卡过。 KD-tree的原理:   考虑从一般BST中类比过来---对于其中一个节点其左边节点的值恒小于它本身,右边反之。实际上是 把所有节点的值从中间分开。如果说BST是对一个一维线段的分割,那么KD-tree就是对K维空间分割。最 终在小的空间内统计答案。说人话就是对K维按顺序均匀分割查哪部分就去哪个块中查找。因为是按序分 割,所以找到答案空间的时间是nlogn至nsqrtn 我信你个鬼,不带O2天天被卡。 为了划分空间,KD-tree在第i层维护第i%k维的信息,即这一维中比它小的在左子树,大的在右子树。对 于查询就像BST一样就好了。同BST,考虑KD-tree如何保持自身平衡。由于用方差过于优雅,此处选择替 罪羊树一样的思路---拍扁重建。 这样KD-tree就愉快的讲完了,撒花。 KD-tree代码实现:

kd-tree

匿名 (未验证) 提交于 2019-12-02 23:36:01
kd-tree 简单理解为一种数据结构(所以点云数据处理中最为核心的问题就是建立离散点间的拓扑关系,实现基于邻域关系的快速查找。) k-d树 (k-dimensional树的简称),是一种分割k维数据空间的数据结构。主要应用于多维空间关键数据的搜索(如:范围搜索和最近邻搜索)。K-D树是二进制空间分割树的特殊的情况。用来组织表示K维空间中点的几何,是一种带有其他约束的二分查找树,为了达到目的,通常只在三个维度中进行处理因此所有的kd_tree都将是三维的kd_tree,kd_tree的每一维在指定维度上分开所有的字节点,在树 的根部所有子节点是以第一个指定的维度上被分开。 k-d树算法可以分为两大部分,一部分是有关k-d树本身这种数据结构建立的算法,另一部分是在建立的k-d树上如何进行最邻近查找的算法。 #include <pcl/point_cloud.h> #include <pcl/kdtree/kdtree_flann.h> #include <iostream> #include <vector> #include <ctime> int main (int argc, char**argv) { srand (time (NULL)); pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl:

KD-tree讲解

試著忘記壹切 提交于 2019-11-29 09:30:38
KD-tree 讲解 by simb351    应神犇junble19768的要求,来水一发KD-tree讲解。学习过程中发现关于KD-tree的资源实在是少, 在OI中的应用更是少之又少。 虽然这东西很水,随便嘴一嘴就能口胡出来。 所以写一篇讲解。 前置芝士: 1. 基础BST姿势 2. 替罪羊树 3. 优良的空间感 比如能脑补出k维空间QWQ KD-tree的应用:    KD-tree主要解决对K维数据的管理,比如多维偏序。但是本弱发现目前OI中KD-tree主流考法为 维护 二维平面中区间的信息。比如ION 9102 弹跳 但是好像能被菜鸡simba口胡的暴力算几卡过。 KD-tree的原理:   考虑从一般BST中类比过来---对于其中一个节点其左边节点的值恒小于它本身,右边反之。实际上是 把所有节点的值从中间分开。如果说BST是对一个一维线段的分割,那么KD-tree就是对K维空间分割。最 终在小的空间内统计答案。说人话就是对K维按顺序均匀分割查哪部分就去哪个块中查找。因为是按序分 割,所以找到答案空间的时间是nlogn至nsqrtn 我信你个鬼,不带O2天天被卡。 为了划分空间,KD-tree在第i层维护第i%k维的信息,即这一维中比它小的在左子树,大的在右子树。对 于查询就像BST一样就好了。同BST,考虑KD-tree如何保持自身平衡。由于用方差过于优雅

[KD-tree] Luogu P2093 JZPFAR

旧巷老猫 提交于 2019-11-26 09:57:08
题目描述 平面上有n个点。现在有m次询问,每次给定一个点(px, py)和一个整数k,输出n个点中离(px, py)的距离第k大的点的标号。如果有两个(或多个)点距离(px, py)相同,那么认为标号较小的点距离较大。 题解 利用KD-Tree算法,求二维平面内到一定点的第k远点 正常建树,由于题目要求输出第k远点的编号,我们需记录一下每个节点的id,用优先队列动态维护小根堆,保持k个最优点,最后输出堆顶元素的编号即可 代码 1 #include <queue> 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 #include <algorithm> 6 #define sqr(x) (x)*(x) 7 #define N 100010 8 #define ll long long 9 using namespace std; 10 ll n,m,X,Y,tot,D,root; 11 struct node 12 { 13 ll dis,id; 14 bool operator < (const node &a)const { return dis>a.dis||(dis==a.dis&&id<a.id); } 15 }; 16 struct Node 17 { 18 ll x[2],id; 19