【分治】最接近点对Python实现

文章目录

    • @[toc]
      • 问题描述
      • 一维最接近点对算法
        • `Python`实现
      • 二维最接近点对算法
        • 分治算法
        • 时间复杂性
        • `Python`实现

问题描述

  • 给定平面上 n n n个点,找其中的一对点,使得在 n n n个点组成的所有点对中,该点对的距离最小

一维最接近点对算法

Python实现
import sysdef closest_pair(points):points.sort()  # 按照横坐标排序min_dist = sys.maxsize  # 初始化最小距离为一个很大的数closest = None  # 初始化最接近点对为 Nonefor i in range(len(points) - 1):dist = abs(points[i] - points[i + 1])  # 计算相邻点对的距离if dist < min_dist:min_dist = distclosest = (points[i], points[i + 1])return closestpoints = [2, 4, 1, 5, 8, 9, 3]res = closest_pair(points)print(f'最接近的点对: {res}')

二维最接近点对算法

分治算法
  • 选取一垂直线 l : x = m l : x = m l:x=m m m m S S S中各点 x x x坐标的中位数,将 S S S分割为 S 1 = { p ∈ S ∣ x ( p ) ≤ m } S_{1} = \set{p \in S \mid x(p) \leq m} S1={pSx(p)m} S 2 = { p ∈ S ∣ x ( p ) > m } S_{2} = \set{p \in S \mid x(p) > m} S2={pSx(p)>m}
  • 递归地在 S 1 S_{1} S1 S 2 S_{2} S2上解最接近点对问题,分别得到 S 1 S_{1} S1 S 2 S_{2} S2中的最小距离 d 1 d_{1} d1 d 2 d_{2} d2
  • d = min ⁡ { d 1 , d 2 } d = \min\set{d_{1} , d_{2}} d=min{d1,d2},若 S S S的最接近点对 ( p , q ) (p , q) (p,q)之间的距离小于 d d d,则 p p p q q q必分属于 S 1 S_{1} S1 S 2 S_{2} S2,设 p ∈ S 1 p \in S_{1} pS1 q ∈ S 2 q \in S_{2} qS2,则 p p p q q q距直线 l l l的距离均小于 d d d
  • P 1 P_{1} P1 P 2 P_{2} P2分别表示直线 l l l的左侧和右侧宽为 d d d的两个垂直长条区域,则 p ∈ P 1 p \in P_{1} pP1 q ∈ P 2 q \in P_{2} qP2,此时 P 1 P_{1} P1中所有点与 P 2 P_{2} P2中所有点构成的点对均为最接近点对的候选者,在最坏情况下有 n 2 / 4 n^{2} / 4 n2/4对这样的候选者,但是对于 P 1 P_{1} P1中任一点 p p p P 2 P_{2} P2中最多只有 6 6 6个点与它构成最接近点对的候选者
    • 实际上对于 P 1 P_{1} P1中任一点 p p p,若与 P 2 P_{2} P2中的点构成最接近点对的候选者,则必有 d i s t a n c e ( p , q ) < d distance(p , q) < d distance(p,q)<d,满足这个条件的 P 2 P_{2} P2中的点一定落在一个 d × 2 d d \times 2d d×2d的矩形 R R R
    • 可将矩形 R R R的长为 2 d 2d 2d的边 3 3 3等分,将长为 d d d的边 2 2 2等分,由此导出 6 6 6 ( d / 2 ) × ( 2 d / 3 ) (d / 2) \times (2d / 3) (d/2)×(2d/3)的矩形,矩形 R R R中最多只有 6 6 6 S S S中的点

1

  • 合并步骤中,最多只需检查 6 × n / 2 = 3 n 6 \times n / 2 = 3n 6×n/2=3n个候选者,为了确切地知道要检查哪 6 6 6个点,将 p p p P 2 P_{2} P2中的点投影到垂直线 l l l上,能与 p p p点一起构成最接近点对候选者的 q q q p p p l l l上投影点的距离小于 d d d,且这种投影点最多只有 6 6 6个,若将 P 1 P_{1} P1 P 2 P_{2} P2中所有 S S S中点按其 y y y坐标排好序,则对 P 1 P_{1} P1中所有点,对排好序的点列做一次扫描,就可以找出所有最接近点对的候选者
时间复杂性

T ( n ) = { O ( 1 ) , n < 4 2 T ( n / 2 ) + O ( n ) , n ≥ 4 T(n) = \begin{cases} O(1) , & n < 4 \\ 2 T(n / 2) + O(n) , & n \geq 4 \end{cases} T(n)={O(1),2T(n/2)+O(n),n<4n4

T ( n ) = O ( n log ⁡ n ) T(n) = O(n \log{n}) T(n)=O(nlogn)

Python实现
import math# 计算两点之间的欧几里德距离
def dist(p1, p2):return math.sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2)# 分治法求解最接近点对问题
def closest_pair(points):# 如果点集中的点个数小于等于 3 个, 直接计算并返回最小距离对if len(points) <= 3:min_dist = float('inf')min_pair = Nonefor i in range(len(points)):for j in range(i + 1, len(points)):d = dist(points[i], points[j])if d < min_dist:min_dist = dmin_pair = (points[i], points[j])return min_pair# 将点集按照 x 坐标排序sorted_points = sorted(points, key=lambda p: p[0])# 将点集分成左右两部分mid = len(sorted_points) // 2left_points = sorted_points[:mid]right_points = sorted_points[mid:]# 递归求解左右两部分的最接近点对left_min_pair = closest_pair(left_points)right_min_pair = closest_pair(right_points)# 取左右两部分最接近点对的最小距离if left_min_pair is None:min_dist = dist(right_min_pair[0], right_min_pair[1])min_pair = right_min_pairelif right_min_pair is None:min_dist = dist(left_min_pair[0], left_min_pair[1])min_pair = left_min_pairelse:left_dist = dist(left_min_pair[0], left_min_pair[1])right_dist = dist(right_min_pair[0], right_min_pair[1])if left_dist <= right_dist:min_dist = left_distmin_pair = left_min_pairelse:min_dist = right_distmin_pair = right_min_pair# 在横跨左右两部分的点中寻找更近的点对mid_x = sorted_points[mid][0]strip = []# 将点集按照 y 坐标排序sorted_points = sorted(points, key=lambda p: p[1])for point in sorted_points:if abs(point[0] - mid_x) < min_dist:strip.append(point)for i in range(len(strip)):for j in range(i + 1, min(i + 7, len(strip))):d = dist(strip[i], strip[j])if d < min_dist:min_dist = dmin_pair = (strip[i], strip[j])return min_dist, min_pairpoints = [(2, 3), (12, 30), (40, 50), (5, 1), (12, 10), (3, 4)]min_dist, min_pair = closest_pair(points)print(f'最接近的点对为: {min_pair}, 点对距离为 {min_dist}')

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

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

相关文章

LED透镜粘接UV胶是一种特殊的UV固化胶,用于固定和粘合LED透镜。

LED透镜粘接UV胶是一种特殊的UV固化胶&#xff0c;用于固定和粘合LED透镜。 它具有以下特点&#xff1a; 1. 高透明度&#xff1a;LED透镜粘接UV胶具有高透明度&#xff0c;可以确保光线的透过性&#xff0c;不影响LED的亮度和效果。 2. 快速固化&#xff1a;经过UV紫外线照射…

CPU、MCU、MPU、DSP、FPGA各是什么?有什么区别?

1、CPU 中央处理器&#xff0c;简称 CPU&#xff08;Central Processing Unit&#xff09;&#xff0c;中央处理器主要包括两个部分&#xff0c;即控制器、运算器&#xff0c;其中还包括高速缓冲存储器及实现它们之间联系的数据、控制的总线。 电子计算机三大核心部件就是CPU…

力扣257. 二叉树的所有路径(递归回溯与迭代)

题目&#xff1a; 给你一个二叉树的根节点 root &#xff0c;按 任意顺序 &#xff0c;返回所有从根节点到叶子节点的路径。 叶子节点 是指没有子节点的节点。 示例 1&#xff1a; 输入&#xff1a;root [1,2,3,null,5] 输出&#xff1a;["1->2->5","…

[陇剑杯 2021]简单日志分析

[陇剑杯 2021]简单日志分析 题目做法及思路解析&#xff08;个人分享&#xff09; 问一&#xff1a;某应用程序被攻击&#xff0c;请分析日志后作答&#xff1a; 黑客攻击的参数是______。&#xff08;如有字母请全部使用小写&#xff09;。 题目思路&#xff1a; 分析…

软件设计师——计算机网络(二)

&#x1f4d1;前言 本文主要是【计算机网络】——软件设计师——计算机网络的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是听风与他&#x1f947; ☁️博客首页&#xff1a;CSDN主页听风与他 &#x1…

生成式AI赋能千行百业加速创新,2023亚马逊云科技re:Invent行业盘点

2023亚马逊云科技re:Invent全球大会已于上周圆满闭幕&#xff0c;在本次大会中&#xff0c;亚马逊云科技又为大家带来了很多功能/项目迭代更新&#xff0c;也重磅发布了很多全新的功能。今天从行业视角来盘点回顾哪些重磅发布适用于垂直行业客户&#xff0c;以及面向汽车、制造…

ChatGLM3-6B和langchain阿里云部署

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、ChatGLM3-6B部署搭建环境部署GLM3 二、Chatglm2-6blangchain部署三、Tips四、总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; …

ffmpeg之ffprobe.c源码分析一---大流程及核心代码分析

文章目录 前言为什么学习ffprobe源码源码调试main()函数重要流程函数分析open_input_file函数分析avformat_match_stream_specifier函数分析read_packets函数分析本篇文章带你打通ffprobe源码的脉络。 关注公众号免费看: 前言 注:本文章全凭个人经验以及平时学习所记录,由…

【MySQL进阶】索引使用

一、索引使用 1.验证索引效率 tb_sku 这张表中准备了 1000w 的记录。 我用夸克网盘分享了「1000w的模拟数据」链接&#xff1a;https://pan.quark.cn/s/15cf665202b2 这张表中id为主键&#xff0c;有主键索引&#xff0c;而其他字段是没有建立索引的。 我们先来查询其中的…

JS基础之原型原型链

JS基础之原型&原型链 原型&原型链构造函数创建对象prototypeprotoconstructor实例与原型原型的原型原型链其他constructorproto继承 原型&原型链 构造函数创建对象 我们先使用构造函数创建一个对象&#xff1a; function Person(){ } var person new Person();…

多窗口文件管理工具Q-Dir安装以及使用教程

软件介绍 Q-Dir 是一款功能强大的Windows资源管理器&#xff0c;可以非常方便的管理你的各种文件。Q-Dir有4 个窗口&#xff0c;特别适用于频繁在各个目录间跳跃复制粘贴的情况&#xff0c;每个窗口都可以方便的切换目录&#xff0c;以不同颜色区分不同类型的文件&#xff0c;…

(企业项目)微服务项目解决跨域问题:

前后端分离项目中前端出现了跨域的问题 在网关模块配置文件中添加 配置 application.properties # 允许请求来源&#xff08;老版本叫allowedOrigin&#xff09; spring.cloud.gateway.globalcors.cors-configurations.[/**].allowedOriginPatterns* # 允许携带的头信息 spri…

idea__SpringBoot微服务06——静态资源(新依赖),首页和图标定制

静态资源 一、静态资源二、首页和图标定制————————创作不易&#xff0c;如觉不错&#xff0c;随手点赞&#xff0c;关注&#xff0c;收藏(*&#xffe3;︶&#xffe3;)&#xff0c;谢谢~~ 新依赖&#xff1a;jquery的 <dependency><groupId>org.webjars&…

matplotlib 默认属性和绘图风格

matplotlib 默认属性 一、绘图风格1. 绘制叠加折线图2. Solarize_Light23. _classic_test_patch4. _mpl-gallery5. _mpl-gallery-nogrid6. bmh7. classic8. fivethirtyeight9. ggplot10. grayscale11. seaborn12. seaborn-bright13. seaborn-colorblind14. seaborn-dark15. sea…

Chart 7 内存优化

文章目录 前言7.1 Adreno GPU OpenCL内存7.1.1 内存声明周期7.1.2 Loacl Memory7.1.3 Constant memory(常量内存)7.1.4 Private Memory7.1.5 Global Memory7.1.5.1 Buffer Object7.1.5.2 Image Object7.1.5.3 Image object vs. buffer object7.1.5.4 Use of both Image and buf…

C语言数据结构-双向链表

文章目录 1 双向链表的结构2 双向链表的实现2.1 定义双向链表的数据结构2.2 打印链表2.3 初始化链表2.4 销毁链表2.5 尾插,头插2.6 尾删,头删2.7 根据头次出现数据找下标2.8 定点前插入2.9 删除pos位置2.10 定点后插入 3 完整代码3.1 List.h3.2 Lish.c3.3 test.c 1 双向链表的结…

键盘打字盲打练习系列之矫正坐姿——4

一.欢迎来到我的酒馆 盲打&#xff0c;矫正坐姿&#xff01; 目录 一.欢迎来到我的酒馆二.继续练习二.矫正坐姿1.键鼠快速选购指南2.椅子快速选购指南 三.改善坐姿建议 二.继续练习 前面的章节&#xff0c;我们重点向大家介绍了主键盘区指法和键盘键位。经过一个系列的教程学习…

Mybatis环境搭建

1、开发环境 IDE&#xff1a;IntelliJ IDEA 2022.2.1 (Ultimate Edition) 构建工具&#xff1a;maven 3.6.1 MySQL版本&#xff1a;MySQL 5.7 MyBatis版本&#xff1a;MyBatis 3.5.14 2、工程创建 创建一个Maven工程giser-java-mybatis-demo 基础依赖如下&#xff1a; &…

用友U8 Cloud 多处反序列化RCE漏洞复现

0x01 产品简介 用友U8 Cloud是用友推出的新一代云ERP,主要聚焦成长型、创新型企业,提供企业级云ERP整体解决方案。 0x02 漏洞概述 用友U8 Cloud存在多处(TableInputOperServlet、LoginServlet 、FileTransportServlet、CacheInvokeServlet、ActionHandlerServlet、Servle…

【rabbitMQ】springboot整合rabbitMQ模拟简单收发消息

目录 1.创建项目和模块 2.添加rabbitMQ依赖 3.启动rabbitMQ服务 4.引入rabbitMQ服务端信息 5.通过单元测试模拟业务发送消息 6. 接收消息 1.创建项目和模块 2.添加rabbitMQ依赖 <!-- rabbitmq依赖--> <dependency> <groupId>org.sp…