Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >查找二维平面上距离最小点对的O(n)算法原理与Python实现

查找二维平面上距离最小点对的O(n)算法原理与Python实现

作者头像
Python小屋屋主
发布于 2024-01-23 04:58:42
发布于 2024-01-23 04:58:42
5300
举报
文章被收录于专栏:Python小屋Python小屋

==============

版权声明:由于公众号后台规则问题,本文暂时无法设置原创标记,但仍属原创内容。

============

问题描述:

给定二维平面上的若干个点,从中查找距离最小的两个。

问题分析:

要解决这个问题,最直接的想法是把给定的点进行两两组合,计算每个组合中两个点的距离,从中找出距离最小的一对。这个算法的计算量非常大,没有任何优化的痕迹,时间复杂度妥妥的O(n^2),即使充分发挥Python语言函数式编程技巧和标准库对象的优势也无法弥补算法本身效率低下的问题。

上面的代码之所以效率低,主要是做了很多不必要的计算。认识到这一点,可以采用一点技巧来减少计算量,例如根据三角形两边长之和大于第三边可知,如果某两个点之间的水平距离或垂直距离已经大于目前已知的最小距离,那么这两个点的距离不可能更小。引入一点减法运算从而避免一些幂运算还是合算的,可以适当提高速度。但这样的改进不属于算法级的优化,虽然有些效果,但效率不会有特别的提升。细心的读者会发现,下面代码中的开方运算并不是必须的,删除可以进一步加快速度把时间再缩短几秒钟,但与我们的目标还有很大距离。

最初的穷举法是仔细检查每个组合是否满足要求,上面的改进是先稍微看一眼每个组合,如果有希望符合要求就再仔细看看,如果第一眼发现不可能符合要求就看完第一眼不再管它了。如果能够减少一些不必要的组合,缩小搜索的范围,把“稍微看一眼”的时间也省下来,应该可以大幅度提高效率。

接下来我们考虑采用分治法,时间复杂度可以达到O(nlogn),核心思路为:1)对所有点按x坐标升序排列,x坐标相同的按y坐标升序排列;2)按x坐标把原始点集左右等分为两个子集,分别寻找两个子集内部距离最小的点对,取二者中最小的一个;3)检查左右两个点集之间的点是否有距离更小的,也就是一个点属于左侧点集另一个点属于右侧点集,但二者之间距离更小;4)对左右两个子集重复上面的操作。

下面的代码在实现算法时又进行了一些优化,例如计算左右点集之间的最小距离时,只考虑了有可能构成更短距离的点,也就是左右两个子集边界附近的点。

虽然代码看上去复杂了很多,但执行速度快了几百倍,点越多效率提高越明显。那么,算法还有改进空间吗?

让我们再回过头来深入分析一下这个问题的枚举法求解过程,如果有一个点B与当前点A的距离最小,那么B点一定在A点的邻域内,如果我们只计算A点与很小邻域内的其他点的距离,而不用计算A点与整个点集中所有点的距离,无疑可以减少大量计算。这样的话问题还有两个关键需要解决,一是邻域半径如何确定,二是如何实现只搜索邻域内的点。对于第一个问题,可以使用目前已知的最小距离作为邻域半径,并且随着计算的推进不断地缩小邻域。对于第二个问题,可以借助于字典来实现。通过这样的改进,甚至可以使得时间复杂度接近于O(n),也会深刻理解一个问题,数据结构是算法的基础,脱离了数据结构的支撑,算法就是空中楼阁。

最后,填写几行代码来测试和比较一下几种方法的效率。

运行结果如下,

注释掉几个函数中检测到距离为0提前结束的代码,重新运行程序,结果如下,

可以看到,只搜索邻域的枚举法具有最好的执行速度,这也符合预期。可能会有读者疑惑,为了确定合适的初始最小距离,代码中先对所有点进行了排序,这是否会引入额外的工作量呢,又是否可以消除呢?需要明确的是,确实会引入一点额外的计算量,但是Python内置函数sorted()已经把排序算法优化到了极致,开销很小。如果不这样做的话,也可以随机选择几个点并计算最小距离作为初始值,这样的话会导致算法不稳定,有时快有时慢,如果随机选择的点距离比较远的话,整个算法的收敛速度会很慢。即使是随机选择的点合适的时候,效率的提升也不明显,几乎可以忽略。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-01-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python小屋 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
《python算法教程》Day10 - 平面最近点对问题平面最小点对问题介绍代码演示
今天是《python算法教程》的第10篇读书笔记。笔记的主要内容是使用python实现求最小点对的时间复杂度为O(nlogn)的算法。 平面最小点对问题介绍 在几何学中,有一个基本问题:在一个平面的n
billyang916
2018/05/02
2.9K0
ICP算法改进--基于曲率特征
算法步骤:利用二次曲面逼近方法求每点的方向矢量以及曲率;根据曲率确定特征点集;根据方向矢量调整对应关系,从而减少ICP算法的搜索量,提高效率。
点云PCL博主
2019/07/30
3.1K0
ICP算法改进--基于曲率特征
【数据挖掘】聚类算法总结
一、层次聚类 1、层次聚类的原理及分类 1)层次法(Hierarchicalmethods)先计算样本之间的距离。每次将距离最近的点合并到同一个类。然后,再计算类与类之间的距离,将距离最近的类合并为一个大类。不停的合并,直到合成了一个类。其中类与类的距离的计算方法有:最短距离法,最长距离法,中间距离法,类平均法等。比如最短距离法,将类与类的距离定义为类与类之间样本的最短距离。 层次聚类算法根据层次分解的顺序分为:自下底向上和自上向下,即凝聚的层次聚类算法和分裂的层次聚类算法(agglomerative和di
陆勤_数据人网
2018/02/27
2.9K0
【数据挖掘】聚类算法总结
k近邻(KNN)之kd树算法原理
本文介绍一种用于高维空间中的快速最近邻和近似最近邻查找技术——Kd-Tree(Kd树)。Kd-Tree,即K-dimensional tree,是一种高维索引树形数据结构,常用于在大规模的高维数据空间进行最近邻查找(Nearest Neighbor)和近似最近邻查找(Approximate Nearest Neighbor),例如图像检索和识别中的高维图像特征向量的K近邻查找与匹配。本文首先介绍Kd-Tree的基本原理,然后对基于BBF的近似查找方法进行介绍,最后给出一些参考文献和开源实现代码。
Python数据科学
2018/08/06
4.5K0
k近邻(KNN)之kd树算法原理
图论求解平面TSP问题算法复现
旅行商问题(Traveling Salesman Problem,TSP)作为组合优化领域的经典难题,在物流配送、电路布线、旅游规划等众多实际场景中具有广泛应用。其核心在于寻找旅行商遍历所有城市且不重复、最终返回起点的最短路径,然而随着城市数量的增加,问题复杂度呈指数级增长,传统算法在求解大规模 TSP 问题时面临巨大挑战。
Srlua
2025/01/02
1791
图论求解平面TSP问题算法复现
深入浅出聚类算法
原创声明:本文为 SIGAI 原创文章,仅供个人学习使用,未经允许,不能用于商业目的。
SIGAI学习与实践平台
2018/09/04
1.1K0
USING INDUCTION TO DESIGN 使用归纳法设计算法【全文翻译】
这篇文章在进行组合算法设计和教学过程中展示了一种基于数学归纳法的方法,尽管这种方法并不能涵盖设计算法时的所有可能方法,但它包含了大部分已知的技术方法。同时这种方法也提供了一个极好的并且也是直观的结构,从而在解释算法设计的时候显得更有深度。这种方法的核心是通过对数学定理证明过程中和设计组合算法过程中的两种智力过程进行类比。尽管我们承认这两种过程是为不同的目的服务的并且取得的是不同类型的结果,但是这两者要比看上去的更加相似。这种说法可以通过一系列的算法例子得到验证,在这些算法中都可以采用这种方法进行设计和解释。我们相信通过学习这种方法,学生能够对算法产生更多的热情,也能更深入更好的理解算法。
EltonZheng
2021/01/26
5220
USING INDUCTION TO DESIGN 使用归纳法设计算法【全文翻译】
基于正交投影的点云局部特征描述详解
本次介绍一个发表于Pattern Recognition的经典三维点云描述子TOLDI,首先进行算法阐述,然后再给出数据集的介绍、局部参考坐标系与描述子的评估方法。
3D视觉工坊
2020/12/11
1.2K0
基于正交投影的点云局部特征描述详解
原创 | 平面内有N个点,如何快速求出距离最近的点对?
这个问题经常在各种面试当中出现,难度不低,很少有人能答上来。说实话,我也被问过,因为毫无准备,所以也没有答上来。是的,这道题有点神奇,没有准备的人往往答不上来。
TechFlow-承志
2020/10/27
3.9K0
原创 | 平面内有N个点,如何快速求出距离最近的点对?
各种聚类算法的介绍和比较「建议收藏」
聚类就是按照某个特定标准(如距离准则)把一个数据集分割成不同的类或簇,使得同一个簇内的数据对象的相似性尽可能大,同时不在同一个簇中的数据对象的差异性也尽可能地大。即聚类后同一类的数据尽可能聚集到一起,不同数据尽量分离。
全栈程序员站长
2022/07/31
6.9K0
各种聚类算法的介绍和比较「建议收藏」
计算几何 平面最近点对 nlogn分治算法 求平面中距离最近的两点
int SOLVE(int left,int right)//求解点集中区间[left,right]中的最近点对
RainMark
2019/09/10
2.7K0
计算几何 平面最近点对 nlogn分治算法 求平面中距离最近的两点
基于三维点云的卷积运算综述
3D传感器(如激光雷达和深度相机)的普及引起了人们对3D视觉的广泛关注,这些传感器采集的3D数据可以提供丰富的几何结构和尺度细节,这也在许多领域得到了实际应用,包括自动驾驶技术[1]、机器人控制技术[2]等。
一点人工一点智能
2024/01/09
8101
基于三维点云的卷积运算综述
回溯算法和动态规划,到底谁是谁爹?文末送书
我们前文经常说回溯算法和递归算法有点类似,有的问题如果实在想不出状态转移方程,尝试用回溯算法暴力解决也是一个聪明的策略,总比写不出来解法强。
labuladong
2021/09/23
9080
Harris角点提取后怎么匹配?
对于角点匹配算法的研究本文主要采用Harris算法提取图像中的角点,通过相似测度得到粗匹配点集,然后简单分析了两种提纯匹配点的简单聚类法和视差梯度约束法。 1. Harris算法角点检测 人眼对角点的识别通常是在一个局部的小区域或小窗口完成的。如果在各个方向上移动这个特征的小窗口,窗口内区域的灰度发生了较大的变化,那么就认为在窗口内遇到了角点。如果这个特定的窗口在图像各个方向上移动时,窗口内图像的灰度没有发生变化,那么窗口内就不存在角点;如果窗口在某一个方向移动时,窗口内图像的灰度发生了较大的变化,而在另一
智能算法
2018/04/03
2.6K0
Harris角点提取后怎么匹配?
机器学习常用聚类算法大盘点,包括:原理、使用细节、注意事项
无监督学习是没有标记信息的学习方式,能够挖掘数据之间的内在规律,聚类算法的目的就是找到这些数据之间的内在性质和规律。
double
2019/10/22
1.9K0
机器学习常用聚类算法大盘点,包括:原理、使用细节、注意事项
随机增量算法 - 最小圆覆盖
随机增量算法是计算几何的一个重要算法,它对理论知识要求不高,算法时间复杂度低,应用范围广大。
ACM算法日常
2020/06/29
1.9K0
聚类K-means算法
概述 机器学习里面的聚类是无监督的学习问题,它的目标是为了感知样本间的相似度进行类别归纳。它可以用于潜在类别的预测以及数据压缩上去。潜在类别预测,比如说可以基于通过某些常听的音乐而将用户进行不同的分类。数据压缩则是指将样本进行归类后,就可以用比较少的的One-hot向量来代替原来的特别长的向量。
算法之名
2021/09/29
5060
聚类K-means算法
图像分割技术介绍
图像分割(image segmentation)技术是计算机视觉领域的一个重要的研究方向,是图像语义理解的重要一环。图像分割是指将图像分成若干具有相似性质的区域的过程,从数学角度来看,图像分割是将图像划分成互不相交的区域的过程。近些年来随着深度学习技术的逐步深入,图像分割技术有了突飞猛进的发展,该技术相关的场景物体分割、人体前背景分割、人脸人体Parsing、三维重建等技术已经在无人驾驶、增强现实、安防监控等行业都得到广泛的应用。
SIGAI学习与实践平台
2018/12/12
2.1K0
图像分割技术介绍
轻量级实时三维激光雷达SLAM,面向大规模城市环境自动驾驶
对于自动驾驶汽车来说,在未知环境中的实时定位和建图非常重要。本文提出了一种快速、轻量级的3D激光雷达SLAM,用于大规模城市环境中自动驾驶车辆的定位。文中提出了一种新的基于深度信息的编码方法,可以对具有不同分辨率的无序点云进行编码,避免了点云在二维平面上投影时丢失维度信息。通过根据编码的深度信息动态选择邻域点来修改主成分分析(PCA),以更少的时间消耗来拟合局部平面。阈值和特征点的数量根据距离间隔自适应,从而提取出稀疏的特征点并均匀分布在三维空间中。提取的关键特征点提高了里程计的准确性,并加快了点云的对齐。在KITTI和MVSECD上验证了该算法的有效性和鲁棒性。里程计估计的快速运行时间为21ms。与KITTI的几种典型的最先进方法相比,所提出的方法将平移误差减少了至少19%,旋转误差减少了7.1%。
一点人工一点智能
2023/02/15
3.7K0
轻量级实时三维激光雷达SLAM,面向大规模城市环境自动驾驶
维诺图分析与实现
维诺图(Voronoi Diagram)又叫泰森多边形或 Dirichlet 图,由两邻点连线的垂直平分线组成的连续多边形构成。
恋喵大鲤鱼
2024/05/24
4100
维诺图分析与实现
推荐阅读
相关推荐
《python算法教程》Day10 - 平面最近点对问题平面最小点对问题介绍代码演示
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档