【机器学习】 多维kd-tree的python实现

news2024/11/15 13:00:33

一、说明

        本篇主要介绍一个用python实现kd-tree的代码,以及围绕代码实现的kd-tree原理。期望能够为读者打开另一个视角,看待kd-tree的好处。

二、什么是K维树?

        K-D 树(也称为 K 维树)是一种二叉搜索树,其中每个节点中的数据是空间中的 K 维点。简而言之,它是一种空间划分(详见下文)数据结构,用于在K维空间中组织点。 K-D树中的一个非叶节点将空间分成两部分,称为半空间。该空间左侧的点由该节点的左子树表示,空间右侧的点由右子树表示。我们很快就会解释如何划分空间和形成树的概念。为了简单起见,让我们通过一个例子来理解二维树。 root 将有一个 x 对齐的平面,root 的子级都有 y 对齐的平面,root 的孙级都有 x 对齐的平面,root 的曾孙级都有 y 对齐的平面,依此类推。

        概括:让我们将平面编号为 0、1、2、...(K – 1)。从上面的示例中,很明显深度 D 处的点(节点)将有一个对齐的平面,其中 A 的计算公式为:A = D mod K

        如何判断一个点是在左子树还是在右子树?如果根节点在平面 A 中对齐,则左子树将包含在该平面中坐标小于根节点坐标的所有点。类似地,右子树将包含其在该平面中的坐标大于等于根节点坐标的所有点。

三、如何创建Kd-tree

        创建二维树:考虑二维平面中的以下点:(3, 6), (17, 15), (13, 15), (6, 12), (9, 1), (2 , 7), (10, 19)

  1. Insert(3, 6):因为树是空的,所以把它作为根节点。
  2. Insert(17, 15):与根节点比较。由于根节点是 X 对齐的,因此将比较 X 坐标值以确定它是在右子树中还是在左子树中。该点将 Y 对齐。
  3. Insert (13, 15):该点的X值大于根节点中点的X值。所以,这将位于 (3, 6) 的右子树中。再次比较此点的 Y 值与点 (17, 15) 的 Y 值(为什么?)。因为,它们是相等的,所以该点将位于 (17, 15) 的右子树中。该点将 X 对齐。
  4. Insert (6, 12):该点的X值大于根节点中点的X值。所以,这将位于 (3, 6) 的右子树中。再次比较此点的 Y 值与点 (17, 15) 的 Y 值(为什么?)。因为,12 < 15,这个点将位于 (17, 15) 的左子树中。该点将 X 对齐。
  5. Insert (9, 1):同样,该点将位于(6, 12)的右侧。
  6. Insert (2, 7):同样,这个点会在(3, 6)的左边。
  7. Insert (10, 19):同样,该点将位于 (13, 15) 的左侧。

        空间是如何划分的?所有 7 个点都将绘制在 X-Y 平面中,如下所示:

  1. 点 (3, 6) 会将空间分成两部分:画线 X = 3。

     

  2. 点 (2, 7) 将线 X = 3 左侧的空间水平分成两部分。在 X = 3 的左侧绘制 Y = 7 线。

  3. 点 (17, 15) 会将直线 X = 3 右侧的空间水平分成两部分。在 X = 3 的右侧绘制 Y = 15 线。

  • 点 (6, 12) 将线 Y = 15 下方和线 X = 3 右侧的空间分成两部分。在 X = 3 线的右侧和 Y = 15 线的下方绘制线 X = 6。

  • 点 (13, 15) 会将 Y = 15 线下方和 X = 6 线右侧的空间分成两部分。在 X = 6 线的右侧和 Y = 15 线的下方绘制线 X = 13。

  • 点 (9, 1) 将线 X = 3、X = 6 和 Y = 15 之间的空间分成两部分。在 X = 3 和 X = 13 之间绘制 Y = 1 线。

  • 点 (10, 19) 会将 X = 3 行右侧和 Y = 15 行上方的空间分成两部分。在 X = 3 行的右侧和 Y = 15 行的上方绘制 Y = 19 行。

四、对应的python代码

# A Python program to demonstrate operations of KD tree

import sys

# Number of dimensions

k = 2

# A structure to represent node of kd tree

class Node:

    def __init__(self, point):

        self.point = point

        self.left = None

        self.right = None

# A method to create a node of K D tree

def newNode(point):

    return Node(point)

# Inserts a new node and returns root of modified tree

# The parameter depth is used to decide axis of comparison

def insertRec(root, point, depth):

    # Tree is empty?

    if not root:

        return newNode(point)

    # Calculate current dimension (cd) of comparison

    cd = depth % k

    # Compare the new point with root on current dimension 'cd'

    # and decide the left or right subtree

    if point[cd] < root.point[cd]:

        root.left = insertRec(root.left, point, depth + 1)

    else:

        root.right = insertRec(root.right, point, depth + 1)

    return root

# Function to insert a new point with given point in

# KD Tree and return new root. It mainly uses above recursive

# function "insertRec()"

def insert(root, point):

    return insertRec(root, point, 0)

# A utility method to determine if two Points are same

# in K Dimensional space

def arePointsSame(point1, point2):

    # Compare individual coordinate values

    for i in range(k):

        if point1[i] != point2[i]:

            return False

    return True

# Searches a Point represented by "point[]" in the K D tree.

# The parameter depth is used to determine current axis.

def searchRec(root, point, depth):

    # Base cases

    if not root:

        return False

    if arePointsSame(root.point, point):

        return True

    # Current dimension is computed using current depth and total

    # dimensions (k)

    cd = depth % k

    # Compare point with root with respect to cd (Current dimension)

    if point[cd] < root.point[cd]:

        return searchRec(root.left, point, depth + 1)

    return searchRec(root.right, point, depth + 1)

# Searches a Point in the K D tree. It mainly uses

# searchRec()

def search(root, point):

    # Pass current depth as 0

    return searchRec(root, point, 0)

# Driver program to test above functions

if __name__ == '__main__':

    root = None

    points = [[3, 6], [17, 15], [13, 15], [6, 12], [9, 1], [2, 7], [10, 19]]

    n = len(points)

    for i in range(n):

        root = insert(root, points[i])

    point1 = [10, 19]

    if search(root, point1):

        print("Found")

    else:

        print("Not Found")

    point2 = [12, 19]

    if search(root, point2):

        print("Found")

    else:

        print("Not Found")

         

# This code is contributed by Prajwal Kandekar

Output:

Found
Not Found

五、后记

K-d树作为数据结构有几个优点:

  • 高效搜索:K-d 树在 k 维空间中有效地搜索点,例如最近邻搜索或范围搜索。
  • 降维:K-d 树可用于降低问题的维数,从而缩短搜索时间并降低数据结构的内存需求。
  • 多功能性:K-d 树可用于广泛的应用,例如数据挖掘、计算机图形学和科学计算。
  • 平衡:K-d 树是自平衡的,这确保树即使在插入或删除数据时也能保持高效。
  • 增量构建:K-d 树可以增量构建,这意味着可以在结构中添加或删除数据,而无需重建整棵树。
  • 易于实现:K-d 树相对容易实现,可以用多种编程语言实现。
  • 本文由 Aashish Barnwal 编译。如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请发表评论。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/452957.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

甘蔗种植成本居高不下 培育良种和提高机械化覆盖率或成行业破局关键

一、甘蔗种植行业概述及分类 甘蔗是一种重要的经济农作物&#xff0c;是世界上最重要的糖料作物及较有发展潜力的可再生能源作物&#xff0c;现广泛种植于热带及亚热带地区&#xff0c;最大的甘蔗生产国是巴西、印度和中国。 根据观研报告网发布的《中国甘蔗种植市场发展态势分…

matlab 点云滤波(中值、均值、高斯滤波)代码

点云中值、均值、高斯滤波 介绍一下滤波函数 smoothdata: 对含噪数据进行平滑处理 B smoothdata(___,method) 为上述任一语法指定平滑处理方法。例如&#xff0c;B smoothdata(A,sgolay) 使用 Savitzky-golay 滤波器对 A 中的数据进行平滑处理。Method-平滑处理方法 "…

java实现修改excel中数据格式

目录 背景&#xff1a;过程&#xff1a;方案&#xff1a;个人想法&#xff1a;总结&#xff1a;1、清楚边界&#xff0c;全局观2、工欲善其事&#xff0c;必先利其器3、别总想着改源码&#xff0c;别总觉得自己做不出来&#xff0c;要给自己积极的心理暗示。有用。 背景&#x…

基于深度强化学习训练《街头霸王·二:冠军特别版》通关关底 BOSS -智能 AI 代理项目上手

文章目录 SFighterAI项目简介实现软件环境项目文件结构 运行指南环境配置验证及调整gym环境&#xff1a; gym-retro 游戏文件夹错误提示及解决Could not initialize NNPACK!错误提示&#xff1a;libGL error: MESA-LOADER: failed to open swrast 运行测试训练模型查看曲线 Tip…

《Redis设计与开发》读书笔记

《Redis设计与实现》读书笔记 简单动态字符串 SDS的定义 结构&#xff1a; buf数组&#xff1a;用于保存字符串 len属性&#xff1a;记录SDS中保存字符串的长度 free属性&#xff1a;记录buf中未使用字节数量 遵循C字符串以空字符串结尾的惯例&#xff0c;保存空字符串的…

默认成员函数之构造函数,构造函数的特点,创建,调用与对象创建的一语双关,默认构造函数等

内置类型与自定义类型 C当中的类型的话分为两类&#xff1a;一种就是内置类型/基本类型&#xff0c;就是c语言自带的那些类型基本类型&#xff0c;如int, char, double, 指针&#xff08;任何类型的指针&#xff0c;因为指针就是地址嘛&#xff09;等等&#xff1b;还有就是自…

某安全对抗行走APP逆向分析

1.定位url 抓包: https://api5.xxxx.com/xxx-rest-service/message/fun_getnearby 看一下参数: opentime:时间戳 reqdata:base64编码 sign 未知,需要解密 # -*- coding: utf-8 -*- # @Author : Codeooo # @Time : 2022-10-14import frida, sysm199a = "&qu…

learn_C_deep_5 (语句和表达式的概念、if语句的多种语法结构、C语言有没有布尔类型、“零值”的比较)

目录 语句和表达式的概念 if语句的多种语法结构 注释的便捷方法&#xff08;环境vs&#xff09; if语句执行的过程 逻辑与&& 逻辑或|| 运算关系的顺序 ​编辑 C语言有没有布尔类型 C99标准 sizeof(bool)的值为多少&#xff1f; _Bool原码 BOOL、TRUE、…

IT_开发提测标准规范

背景 公司 IT 规模小&#xff0c;开发提测质量差&#xff0c;流程不规范&#xff0c;导致测试任务重&#xff0c;于是推行 &#xff1a;IT_开发提测标准规范&#xff0c;正文如下&#xff1b;拟定开发提测标准规范后&#xff0c;测试与项目经理内部评审后&#xff0c;发至IT群…

低相位噪声链路调试分析

上图为原始状态,与项目结项评审指标差不多,确实存在几个噪声比较差的点。 频率分布大约在几Hz,20K,50K左右。 由于测试时由子卡进行输出,采用直接进行直接输出,以看出,明显的尖峰已经没有了,只剩下20K左右的尖峰,但是总体来说,效果很差,可能时单端输出的问题。试…

【SVN已解决】svn下载成功图标不显示解决方法

介绍 这里是小编成长之路的历程&#xff0c;也是小编的学习之路。希望和各位大佬们一起成长&#xff01; 以下为小编最喜欢的两句话&#xff1a; 要有最朴素的生活和最遥远的梦想&#xff0c;即使明天天寒地冻&#xff0c;山高水远&#xff0c;路远马亡。 一个人为什么要努力&a…

【小技巧】word文档编辑技巧(一)

文章目录 一、显示显示导航显示所有字符 二、格式格式-三级目录格式-文本格式-图格式-表格式-公式格式-参考文献 三、小技巧交叉引用连续交叉引用表/图目录等自动更新分节符设置页眉/页码word转pdf带导航 一、显示 显示导航 开启导航&#xff1a;视图->显示框->导航窗格…

《春琴抄》庭有枇杷树,今已亭亭如盖矣~

《春琴抄》庭有枇杷树&#xff0c;今已亭亭如盖矣~ 谷崎润一郎&#xff08;1886年7月24日&#xff5e;1965年7月30日&#xff09;&#xff0c;日本近代小说家&#xff0c;唯美派文学主要代表人物之一&#xff0c;《源氏物语》现代文的译者。 代表作有《刺青》《春琴抄》《细雪》…

客户体验的重要性和企业发展的紧密联系

近年来&#xff0c;随着企业数字化转型的加速&#xff0c;客户服务的意义越来越被人们所重视。客户服务的质量不仅直接影响到客户满意度和忠诚度&#xff0c;而且会间接影响到企业的品牌口碑和市场竞争力。然而&#xff0c;目前市面上的很多企业帮助中心搭建平台&#xff0c;可…

【油猴脚本】ChatGPT 智能 Prompts 提示词助手

chatGPT 插件脚本 中文 Prompt 训练对话框 ChatGPT 智能 Prompts 可以为你带来更好的使用体验助你训练好用的ChatGPT&#xff1a;添加快捷指令&#xff08;prompts&#xff09;新增&#xff1a;论文专家角色、支持自动发送、固定智能助手…还有更多需求可以到仓库Issues里发起…

Qt Quick - ScrollView

Qt Quick - ScrollView 使用总结 一、概述二、使用四、分级五、滚动条控制六、触摸vs.鼠标交互七、美化 一、概述 ScrollView 为用户定义的内容提供滚动功能。类似QScrollArea 的功能。 二、使用 第一个例子展示了ScrollView的最简单用法。 ScrollView {width: 200height: …

本周大新闻|MR头显或成WWDC23重头戏;PICO 4 Pro本周开售

本周XR大新闻&#xff0c;AR方面&#xff0c;彭博社Mark Gurman确认XR头显将成为WWDC重头戏&#xff0c;同时将兼容iPad应用&#xff1b;Inprentus将发布用于AR光波导方案的闪耀光栅工艺&#xff1b;富采展示0.12英寸蓝光Micro LED&#xff1b;锐思华创公布多层光波导PGU&#…

大数据技术之Kafka集成

一、集成Flume 1.1 Flume生产者 &#xff08;1&#xff09;启动Kafka集群 zkServer.sh startnohup kafka-server-start.sh /opt/soft/kafka212/config/server.properties & &#xff08;2&#xff09;启动Kafka消费者 kafka-console-consumer.sh --bootstrap-server 192…

Django框架之定义模型和表迁移

django3.0 定义表模型并通过定义好的模型实现源代码创建数据表。 概述 模型是一个用于表示数据的Python类&#xff0c;包含基本的数据字段和行为。 通常一个模型就代表一张数据库表。 模型继承自django.db.models.Model&#xff0c;模型的每一个属性代表一个数据的字段。 定…

SLAM面试笔记(2) - ORB-SLAM2

目录 1 四叉树实现特征点均匀化分布 2 Bow词袋模型 2.1 什么是词袋&#xff1f; 2.2 词袋在ORB-SLAM2中的作用 2.3 离线训练字典树流程 3 ORB-SLAM的跟踪方法 3.1 恒速模型跟踪 3.2 重定位跟踪 3.3 参考关键帧跟踪 持续更新中... 1 四叉树实现特征点均匀化分布 参考…