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

news2024/12/26 22:50:50

文章目录

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

因上努力

个人主页:丷从心·

系列专栏:分治算法

学习指南:Python学习指南

果上随缘


问题描述

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

一维最接近点对算法

Python实现
import sys


def closest_pair(points):
    points.sort()  # 按照横坐标排序
    min_dist = sys.maxsize  # 初始化最小距离为一个很大的数
    closest = None  # 初始化最接近点对为 None

    for i in range(len(points) - 1):
        dist = abs(points[i] - points[i + 1])  # 计算相邻点对的距离

        if dist < min_dist:
            min_dist = dist
            closest = (points[i], points[i + 1])

    return closest


points = [2, 4, 1, 5, 8, 9, 3]

res = closest_pair(points)

print(f'最接近的点对为: {res}')
最接近的点对为: (1, 2)

二维最接近点对算法

分治算法
  • 选取一垂直线 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 = None

        for 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 = d
                    min_pair = (points[i], points[j])

        return min_pair

    # 将点集按照 x 坐标排序
    sorted_points = sorted(points, key=lambda p: p[0])

    # 将点集分成左右两部分
    mid = len(sorted_points) // 2

    left_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_pair
    elif right_min_pair is None:
        min_dist = dist(left_min_pair[0], left_min_pair[1])
        min_pair = left_min_pair
    else:
        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_dist
            min_pair = left_min_pair
        else:
            min_dist = right_dist
            min_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 = d
                min_pair = (strip[i], strip[j])

    return min_dist, min_pair


points = [(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}')
最接近的点对为: ((2, 3), (3, 4)), 点对距离为 1.4142135623730951

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

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

相关文章

Python 深度学习(二)

原文&#xff1a;zh.annas-archive.org/md5/98cfb0b9095f1cf64732abfaa40d7b3a 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 第五章&#xff1a;图像识别 视觉可以说是人类最重要的感官之一。我们依赖视觉来识别食物&#xff0c;逃离危险&#xff0c;认出朋友和家人…

【C++题解】1044. 找出最经济型的包装箱型号

问题&#xff1a;1044. 找出最经济型的包装箱型号 类型&#xff1a;多分支结构 题目描述&#xff1a; 已知有 A&#xff0c;B&#xff0c;C&#xff0c;D&#xff0c;E 五种包装箱&#xff0c;为了不浪费材料&#xff0c;小于 10 公斤的用 A 型&#xff0c;大于等于 10 公斤小…

浅论汽车研发项目数字化管理之道

随着汽车行业竞争不断加剧&#xff0c;汽车厂商能否快速、高质地推出贴合市场需求的新车型已经成为车企竞争的重要手段&#xff0c;而汽车研发具备流程复杂、专业领域多、协作难度大、质量要求高等特点&#xff0c;企业如果缺少科学健全的项目管理体系&#xff0c;将会在汽车研…

应用监控(Prometheus + Grafana)

可用于应用监控的系统有很多&#xff0c;有的需要埋点(切面)、有的需要配置Agent(字节码增强)。现在使用另外一个监控系统 —— Grafana。 Grafana 监控面板 这套监控主要用到了 SpringBoot Actuator Prometheus Grafana 三个模块组合的起来使用的监控。非常轻量好扩展使用。…

光伏管理系统:降本增效解决方案。

现在是光伏发展的重要节点&#xff0c;如何在众多同行中脱颖而出并且有效的达到降低成本、提高效率也是很多企业都在考虑的问题&#xff0c;鹧鸪云的团队研发出了光伏管理系统&#xff0c;通过更高效、更智能、更全面的管理方式来帮助企业实现降本增效的转型&#xff0c;小编带…

记录AE学习查漏补缺(持续补充中。。。)

记录AE学习查漏补缺 常用win下截图WinShifts导入AI/PS工程文件将图层上移一个位置或者下移一个位置展示/关闭图层标线/标度放大面板适应屏幕大小 CtrlAltF 关键帧熟记关键参数移动锚点位置加选一个关键参数快速回到上下一帧隐藏/显示图层关键帧拉长缩短关键帧按着鼠标左键不松手…

【面试经典 150 | 回溯】单词搜索

文章目录 写在前面Tag题目来源解题思路方法一&#xff1a;回溯 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并附带一些对于本题涉及到的数据结构等内容进行回顾…

Golang | Leetcode Golang题解之第59题螺旋矩阵II

题目&#xff1a; 题解&#xff1a; func generateMatrix(n int) [][]int {matrix : make([][]int, n)for i : range matrix {matrix[i] make([]int, n)}num : 1left, right, top, bottom : 0, n-1, 0, n-1for left < right && top < bottom {for column : lef…

Flask表单详解

Flask表单详解 概述跨站请求伪造保护表单类把表单渲染成HTML在视图函数中处理表单重定向和用户会话Flash消息 概述 尽管 Flask 的请求对象提供的信息足够用于处理 Web 表单&#xff0c;但有些任务很单调&#xff0c;而且要重复操作。比如&#xff0c;生成表单的 HTML 代码和验…

【stomp 实战】spring websocket用户消息发送源码分析

这一节&#xff0c;我们学习用户消息是如何发送的。 消息的分类 spring websocket将消息分为两种&#xff0c;一种是给指定的用户发送&#xff08;用户消息&#xff09;&#xff0c;一种是广播消息&#xff0c;即给所有用户发送消息。那怎么区分这两种消息呢?那就是用前缀了…

maven聚合,继承等方式

需要install安装到本地仓库&#xff0c;或者私服&#xff0c;方可使用自己封装项目 编译&#xff0c;测试&#xff0c;打包&#xff0c;安装&#xff0c;发布 parent: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://mav…

Python 机器学习 基础 之 学习 基础环境搭建

Python 机器学习 基础 之 学习 基础环境搭建 目录 Python 机器学习 基础 之 学习 基础环境搭建 一、简单介绍 二、什么是机器学习 三、python 环境的搭建 1、Python 安装包下载 2、这里以 下载 Python 3.10.9 为例 3、安装 Python 3.10.9 4、检验 python 是否安装成功&…

二分图--判定以及最大匹配

水了个圈钱杯省一&#xff0c;不过估计国赛也拿不了奖&#xff0c;但还是小小挣扎一下。 什么是二分图&#xff1a;G(V,E)是一个无向图&#xff0c;若顶点V可以分为两个互不相交的子集A,B&#xff0c;并图中的每一条边&#xff08;i,j)所关联的ij属于不同的顶点集&#xff0c;…

2024年Docker常用操作快速查询手册

目录 一、Linux系统上 Docker安装流程&#xff08;以ubuntu为例&#xff09; 一、卸载所有冲突的软件包 二、设置Docker的apt存储库&#xff08;这里使用的是阿里云软件源&#xff09; 三、直接安装最新版本的Docker 三、安装指定版本的Docker 四、验证Docker是否安装成功…

Nginx实现端口转发与负载均衡配置

前言&#xff1a;当我们的软件体系结构较为庞大的时候&#xff0c;访问量往往是巨大的&#xff0c;所以我们这里可以使用nginx的均衡负载 一、配置nginx实现端口转发 本地tomcat服务端口为8082 本地nginx端口为8080 目的&#xff1a;将nginx的8080转发到tomcat的8082端口上…

每日一题:插入区间

给你一个 无重叠的 &#xff0c;按照区间起始端点排序的区间列表 intervals&#xff0c;其中 intervals[i] [starti, endi] 表示第 i 个区间的开始和结束&#xff0c;并且 intervals 按照 starti 升序排列。同样给定一个区间 newInterval [start, end] 表示另一个区间的开始和…

【嵌入式笔试题】网络编程笔试题

非常经典的笔试题。 2.网络编程(29道) 2.1列举一下OSI协议的各种分层。说说你最熟悉的一层协议的功能。 ( 1 )七层划分为:应用层、表示层、会话层、传输层、网络层、数据链路层、物理 层。 ( 2 )五层划分为:应用层、传输层、网络层、数据链路层、物理层。 ( 3 )…

vue 脚手架 创建vue3项目

创建项目 命令&#xff1a;vue create vue-element-plus 选择配置模式&#xff1a;手动选择模式 (上下键回车) 选择配置&#xff08;上下键空格回车&#xff09; 选择代码规范、规则检查和格式化方式: 选择语法检查方式 lint on save (保存就检查) 代码文件中有代码不符合 l…

国家开放大学2024年春《Matlab语言及其应用》实验一熟悉Matlab 操作环境参考答案

实验报告 姓名&#xff1a; 学号&#xff1a; 实验一名称&#xff1a;熟悉 Matlab 操作环境 实验目标&#xff1a;通过简单变量和矩阵的录入、计算和查看相关信息&#xff0c;了解 Matlab 操作界面 及各子窗口使用方法。熟悉一系列便于使用的 Matlab 函数和文件的工具。 实…

java-springmvc 01 补充 javaweb 三大组件Servlet,Filter、Listener(源码都是tomcat8.5项目中的)

01.JavaWeb三大组件指的是&#xff1a;Servlet、Filter、Listener,三者提供不同的功能 这三个在springmvc 运用很多 Servlet 01.Servlet接口&#xff1a; public interface Servlet {/*** 初始化方法* 实例化servlet之后&#xff0c;该方法仅调用一次 * init方法必须执行完…