”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 使用分治法查找最近的点对

使用分治法查找最近的点对

发布于2024-07-30
浏览:218

本节介绍使用分治法查找最接近的点对的有效算法。给定一组点,最近对问题是找到彼此最接近的两个点。如下图所示,绘制一条线来连接最近对动画中两个最近的点。

Image description

案例研究:查找最近的对,提出了一种用于查找最近的点对的强力算法。该算法计算所有点对之间的距离并找到距离最小的点。显然,该算法需要 O(n^2) 时间。我们能否设计出更高效的算法?

我们将使用一种称为分而治之的方法来解决这个问题。该方法将问题划分为子问题,求解子问题,然后组合子问题的解以获得整个问题的解。与动态规划方法不同,分而治之方法中的子问题不重叠。子问题就像原问题一样,但规模较小,因此可以应用递归来解决问题。事实上,所有递归问题的解决方案都遵循分而治之的方法。

以下步骤描述了如何使用分而治之的方法解决最近配对问题。

  • 第 1 步:按 x 坐标升序对点进行排序。对于具有相同 x 坐标的点,按 y 坐标排序。这会产生一个排序的点列表 S。
  • 步骤2:使用排序列表中的中点将S分为两个大小相等的子集S1和S2。令中点位于 S1 处。递归地找到 S1 和 S2 中最接近的对。令 d1 和 d2 分别表示两个子集中最近对的距离。
  • 步骤3:找到S1中的点和S2中的点之间最接近的对,并将它们的距离表示为d3。最接近的一对是距离为 min(d1, d2, d3).

选择排序需要 O(n^2) 时间。步骤 1 可以在 O(n log n) 时间内完成。步骤 3 可以在 O(n) 时间内完成。设 d = min(d1, d2)。我们已经知道最近的对距离不能大于 d。为了使S1中的点和S2中的点形成S中最接近的对,左边的点必须在stripL中,右边的点在stripR中,如下图所示( A)。

对于stripL中的点p,只需考虑d X 2d矩形内的右点,如下(b)所示。矩形外的任何右点都不能与 p 形成最接近的对。由于S2中最近对的距离大于或等于d,因此最多可以有六个
矩形内的点。因此,对于stripL中的每个点,最多需要考虑stripR中的六个点。

对于stripL中的每个点p,如何定位stripR中对应的d X 2d矩形区域中的点?如果 stripLstripR 中的点按其 y 坐标的升序排序,则可以有效地完成此操作。令 pointsOrderedOnY 为按 y 坐标升序排序的点列表。 pointsOrderedOnY可以在算法中预先获得。 stripLstripR 可以从步骤 3 中的 pointsOrderedOnY 获得,如下面的代码所示。

Image description

对于pointsOrderedOnY 中的每个点p
if (p 在 S1 中并且 mid.x – p.x 将 p 附加到 stripL;
else if (p 在 S2 中且 p.x - mid.x 将 p 附加到 stripR;

stripLstripR中的点为{p0, p1, ... , pk}和{q0, q1, ... , qt},如图上图(c)。 stripL 中的点与 stripR 中的点之间最接近的对可以使用下面代码中描述的算法找到。

d = min(d1, d2);
 r = 0; // r is the index of a point in stripR
 for (each point p in stripL) {
 // Skip the points in stripR below p.y - d
  while (r 



stripL中的点按 p0, p1, ... , pk 的顺序考虑。对于 stripL 中的点 p,跳过 stripRp.y – d 下方的点(第 5-6 行)。一旦跳过某个点,就不再考虑该点。 while 循环(第 9-17 行)检查 (p, q[r1]) 是否是可能最接近的对。这样的 q[r1] 对最多有 6 个,因为 stripR 中两点之间的距离不能小于 d。因此,在步骤 3 中找到最接近的对的复杂度是 O(n).

请注意,上述步骤中的步骤 1 仅执行一次以对点进行预排序。假设所有点都已预先排序。令 T(n) 表示该算法的时间复杂度。因此,

Image description

因此,可以在 O(n log n) 时间内找到最接近的点对。

版本声明 本文转载于:https://dev.to/paulike/finding-the-closest-pair-of-points-using-divide-and-conquer-2deb?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 为什么不````''{margin:0; }`始终删除CSS中的最高边距?
    为什么不````''{margin:0; }`始终删除CSS中的最高边距?
    在CSS 问题:不正确的代码: 全球范围将所有余量重置为零,如提供的代码所建议的,可能会导致意外的副作用。解决特定的保证金问题是更建议的。 例如,在提供的示例中,将以下代码添加到CSS中,将解决余量问题: body H1 { 保证金顶:-40px; } 此方法更精确,避免了由全局保证金重置引...
    编程 发布于2025-04-07
  • 如何同步迭代并从PHP中的两个等级阵列打印值?
    如何同步迭代并从PHP中的两个等级阵列打印值?
    同步的迭代和打印值来自相同大小的两个数组使用两个数组相等大小的selectbox时,一个包含country代码的数组,另一个包含乡村代码,另一个包含其相应名称的数组,可能会因不当提供了exply for for for the uncore for the forsion for for ytry...
    编程 发布于2025-04-07
  • 对象拟合:IE和Edge中的封面失败,如何修复?
    对象拟合:IE和Edge中的封面失败,如何修复?
    To resolve this issue, we employ a clever CSS solution that solves the problem:position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%)...
    编程 发布于2025-04-07
  • 可以在纯CS中将多个粘性元素彼此堆叠在一起吗?
    可以在纯CS中将多个粘性元素彼此堆叠在一起吗?
    [2这里: https://webthemez.com/demo/sticky-multi-header-scroll/index.html posite:sticky; sticky; .Sticky-1 {[ top:1em; z-index:1; 1; { display:gr...
    编程 发布于2025-04-07
  • 如何限制动态大小的父元素中元素的滚动范围?
    如何限制动态大小的父元素中元素的滚动范围?
    在交互式接口中实现垂直滚动元素的CSS高度限制问题: 考虑一个布局,其中我们具有可滚动的映射div,该图像div与用户的垂直滚动一起移动,同时维持固定的固定sidebar。但是,地图的滚动无限期扩展,超过了视口的高度,阻止用户访问页面页脚。 映射{} 因此。我们不使用jQuery的“ .aim...
    编程 发布于2025-04-07
  • Android如何向PHP服务器发送POST数据?
    Android如何向PHP服务器发送POST数据?
    在android apache httpclient(已弃用) httpclient httpclient = new defaulthttpclient(); httppost httppost = new httppost(“ http://www.yoursite.com/script.p...
    编程 发布于2025-04-07
  • 如何在JavaScript对象中动态设置键?
    如何在JavaScript对象中动态设置键?
    在尝试为JavaScript对象创建动态键时,如何使用此Syntax jsObj['key' i] = 'example' 1;不工作。正确的方法采用方括号: jsobj ['key''i] ='example'1; 在JavaScript中,数组是一...
    编程 发布于2025-04-07
  • 如何将来自三个MySQL表的数据组合到新表中?
    如何将来自三个MySQL表的数据组合到新表中?
    mysql:从三个表和列的新表创建新表 答案:为了实现这一目标,您可以利用一个3-way Join。 选择p。*,d.content作为年龄 来自人为p的人 加入d.person_id = p.id上的d的详细信息 加入T.Id = d.detail_id的分类法 其中t.taxonomy =...
    编程 发布于2025-04-07
  • 如何在php中使用卷发发送原始帖子请求?
    如何在php中使用卷发发送原始帖子请求?
    如何使用php 创建请求来发送原始帖子请求,开始使用curl_init()开始初始化curl session。然后,配置以下选项: curlopt_url:请求 [要发送的原始数据指定内容类型,为原始的帖子请求指定身体的内容类型很重要。在这种情况下,它是文本/平原。要执行此操作,请使用包含以下标头...
    编程 发布于2025-04-07
  • 如何从Python中的字符串中删除表情符号:固定常见错误的初学者指南?
    如何从Python中的字符串中删除表情符号:固定常见错误的初学者指南?
    从python import codecs import codecs import codecs 导入 text = codecs.decode('这狗\ u0001f602'.encode('utf-8'),'utf-8') 印刷(文字)#带有...
    编程 发布于2025-04-07
  • 为什么PYTZ最初显示出意外的时区偏移?
    为什么PYTZ最初显示出意外的时区偏移?
    与pytz 最初从pytz获得特定的偏移。例如,亚洲/hong_kong最初显示一个七个小时37分钟的偏移: 差异源利用本地化将时区分配给日期,使用了适当的时区名称和偏移量。但是,直接使用DateTime构造器分配时区不允许进行正确的调整。 example pytz.timezone(...
    编程 发布于2025-04-07
  • 如何使用Java.net.urlConnection和Multipart/form-data编码使用其他参数上传文件?
    如何使用Java.net.urlConnection和Multipart/form-data编码使用其他参数上传文件?
    使用http request 上传文件上传到http server,同时也提交其他参数,java.net.net.urlconnection and Multipart/form-data Encoding是普遍的。 Here's a breakdown of the process:Mu...
    编程 发布于2025-04-07
  • 您如何在Laravel Blade模板中定义变量?
    您如何在Laravel Blade模板中定义变量?
    在Laravel Blade模板中使用Elegance 在blade模板中如何分配变量对于存储以后使用的数据至关重要。在使用“ {{}}”分配变量的同时,它可能并不总是最优雅的解决方案。幸运的是,Blade通过@php Directive提供了更优雅的方法: $ old_section =“...
    编程 发布于2025-04-07
  • 如何使用Python有效地以相反顺序读取大型文件?
    如何使用Python有效地以相反顺序读取大型文件?
    在python 反向行读取器生成器 == ord('\ n'): 缓冲区=缓冲区[:-1] 剩余_size- = buf_size lines = buffer.split('\ n'....
    编程 发布于2025-04-07
  • 为什么PHP的DateTime :: Modify('+1个月')会产生意外的结果?
    为什么PHP的DateTime :: Modify('+1个月')会产生意外的结果?
    使用php dateTime修改月份:发现预期的行为在使用PHP的DateTime类时,添加或减去几个月可能并不总是会产生预期的结果。正如文档所警告的那样,“当心”这些操作的“不像看起来那样直观。 考虑文档中给出的示例:这是内部发生的事情: 现在在3月3日添加另一个月,因为2月在2001年只有2...
    编程 发布于2025-04-07

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3