美文网首页
分治法求解最近点对问题(python实现)

分治法求解最近点对问题(python实现)

作者: 追上我的速度 | 来源:发表于2020-05-03 15:37 被阅读0次

问题描述

在一个点集合中找到一对距离最近的点。(二维点)

解决办法

1. 枚举

比较
p0, p1; p0, p2; p0, p3...
p1, p2; p1, p3...
...

def find_c_p(arr):
    size = len(arr)
    mid_d = distance(arr[0], arr[1])
    x, y = 0, 0
    for i in range(size):
        for j in range(i+1, size):
            if i!=j:
                d = distance(arr[i], arr[j])
                if d<mid_d:
                    mid_d = d
                    x, y = arr[i], arr[j]
    return mid_d, x, y
1. 分治法

枚举的时间复杂度是n的平方,用分治法可降低时间复杂度。

准备: 对于点集S,首先将S中的点按照x坐标排序,排序结果保存到A中, 同时,将S点按y坐标排序,结果保存到B
思路: 集合A中的点划分左右两个子集,递归地找到子集中的解,取较小者,存为d,再考虑横跨左右区间的点对,取B中x坐标值在[mid-d, mid+d]中的点,保存到集合R中,此时,R内点按y坐标有序排布,找到R中的解, 与d比较, 返回最小者
代码

def find_closet_points(ls: list):
    a_a = sorted(ls, key=lambda x:x[0])
    a_b = sorted(ls, key=lambda x:x[1])

    def fun(a, b, left, right):
        if right - left <= 4:
            return find_c_p(a[left: right+1])
        if left < right:
            mid = (left + right) // 2
            d_l, plx, ply = fun(a, b, left, mid-1)
            d_r, prx, pry = fun(a, b, mid+1, right)
            if d_l < d_r:
                d = d_l
                ansx, ansy = plx, ply
            else:
                d = d_r
                ansx, ansy = prx, pry
            point = a[mid]
            b1 = find_points(d, point[0], b)
            d_b, px, py = find_closet(b1)
            if d_b<d:
                return d_b, px, py
            return d, ansx, ansy
    def find_points(radius, center, b):
        l, r = center-radius, center+radius
        b1 = []
        for x, y in b:
            if l <= x <= r:
                b1.append([x, y])
        return b1

    def find_closet(b1):
        size = len(b1)
        min_d = distance(b1[1], b1[0])
        x, y = 0, 0
        for i in range(size):
            for j in range(size-i):
                if j == 8:
                    break
                if i != j:
                    dis = distance(b1[i], b1[j])
                    if dis < min_d:
                        min_d = dis
                        x, y = b1[i], b1[j]
        return min_d, x, y

    return fun(a_a, a_b, 0, len(a_a) - 1)
def distance(p1, p2):
    return (p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2

参考资料 李春葆《算法设计与分析》

相关文章

  • 分治法求解最近点对问题(python实现)

    问题描述 在一个点集合中找到一对距离最近的点。(二维点) 解决办法 1. 枚举 比较p0, p1; p0, p2;...

  • 分治策略

    求解递归式方法 最大子数组问题 分治策略 分治法流程 伪代码 C++实现 线性解 流程 代入法求解递归式 递归树法...

  • 分治法-最近点对问题

    一.实验目的 (1)掌握分治法思想。 (2)学会最近点对问题求解方法。 二.实验步骤与结果 实验总体思路: 本实验...

  • 分治求解一维最近点对问题

    为最近对问题的一维版本设计一个直接基于分治技术的算法,并确定它的时间复杂度。假设输入的点是以升序保存在数组A中。(...

  • 动态规划

    动态规划用于求解多阶段决策最优解的问题。 其基本思想与分治法类似,也是将求解问题分解为多个子问题,与分治法不同的是...

  • 分治法

    分治法求解的思想是将整个问题分成若干小问题后分而治之。通常,由分治法多得到的小问题与原问题具有相同的类型。并且在求...

  • 数据结构与算法--分治法、归并排序

    分治法 分治法的思想是:将原问题分解成若干个规模较小但是与原问题类似的问题,递归地求解这些子问题,然后再合并这些子...

  • 0x01 分治法

    1、分治策略分治法是采用分而治之,逐个解决的策略。孙子兵法曰:凡治众如寡者,分数是也。 采用分治求解的问题必须具有...

  • 《算法导论》--动态规划

    1. 概述 动态规划与分治法相似,都是通过组合子问题来求解原问题。区别在于,分治法将问题划分为互不相交的子问题,递...

  • 《python算法教程》Day11 - 分治法求解平面凸包问题

    这是《python算法教程》的第11篇读书笔记,笔记主要内容是使用分治法求解凸包。 平面凸包问题简介 在一个平面点...

网友评论

      本文标题:分治法求解最近点对问题(python实现)

      本文链接:https://www.haomeiwen.com/subject/hyidghtx.html