最近点对问题(蛮力法和分治法)

  • 1、一维空间
    • 1.1蛮力法
    • 1.2分治法
  • 2、二维空间

代码参考链接: http://t.csdn.cn/flREB

1、一维空间

1.1蛮力法

代码:

import numpy as np# 求解两个一维点的距离
def Distance(a_point, b_point):return np.abs(a_point-b_point)# 蛮力法求解最近两个点的距离
def ClosestPair(points):mindist = np.infclose_points = []for i in range(0, len(points)-1):distance = Distance(points[i], points[i+1])if distance < mindist:# 每次保存最近两个点的信息之前先清空列表close_points.clear()mindist = distance# 保存最近两个点的信息close_points.append(points[i])close_points.append(points[i+1])return mindist, close_points# 排序
def Sort(points):print('随机产生的数:', points)points = sorted(points)print('排序后:', points)return ClosestPair(points)# 随机产生[0,100]中的五个整数
points = np.random.randint(0, 100, 5)
mindist,close_points=Sort(points)
print('最近点对:',close_points)
print('最小距离:',mindist)

结果:
随机产生5个点:

随机产生8个点:

分析:
    首先对随机生成的一维点进行排序,时间复杂度为O(nlogn)O(nlogn)O(nlogn)。然后再遍历排序后的点,计算每一个点和后一个点的距离,于是就找到了距离最近的点对,时间复杂度为O(n)O(n)O(n)。故使用蛮力法解决一维最近点对问题的时间复杂度为O(nlogn)O(nlogn)O(nlogn)

1.2分治法

    最近点对问题的分治策略如下:
    1、划分:
    将集合SSS分成两个子集S1S_{1}S1​和S2S_{2}S2​,根据平衡子问题原则,用SSS中各点坐标的中位数作为分割点,则会得到一个平衡的分割点mmm,使得子集S1S_{1}S1​和S2S_{2}S2​中有个数大致相同的点,会出现以下三种情况:
    ①最近点对均在集合S1S_{1}S1​中;
    ②最近点对均在集合S2S_{2}S2​中;
    ③最近点对分别在集合S1S_{1}S1​和S2S_{2}S2​中。
    2、求解子问题:
    对于划分阶段的情况①和②可递归求解,如果出现情况③,问题就比较复杂了。
    下面讨论情况③:设最近点对是ppp和qqq,那么有p∈S1,q∈S2p\in S_{1},q\in S_{2}p∈S1​,q∈S2​。递归地在S1S_{1}S1​和S2S_{2}S2​上求解最近点对问题,分别得到S1S_{1}S1​和S2S_{2}S2​中的最近距离d1,d2d_{1},d_{2}d1​,d2​,令d=min(d1,d2)d=min(d_{1},d_{2})d=min(d1​,d2​)。情况③则说明最近点对(p,q)(p,q)(p,q)在(m−d,m+d)(m-d,m+d)(m−d,m+d)的范围内,计算它们的距离。
    3、合并:
    比较三种情况下的最近点对,取三者之中的距离最小者为问题的解。

代码:

import numpy as np# 求解两个一维点的距离
def Distance(a_point, b_point):return np.abs(a_point-b_point)# 蛮力法求解最近两个点的距离
def ClosestPair(points):mindist = np.infclose_points = []for i in range(0, len(points)-1):distance = Distance(points[i], points[i+1])if distance < mindist:# 每次保存最近两个点的信息之前先清空列表close_points.clear()mindist = distance# 保存最近两个点的信息close_points.append(points[i])close_points.append(points[i+1])return mindist, close_points# 分治法求解最近两个点的距离
def ClosePoints1(points):left_points = []right_points = []temp_points = []if len(points) <= 3:  # 如果少于3个点,直接用蛮力法求解distance, close_points = ClosestPair(points)return distance, close_points# 求中间位置midindex = int(len(points)/2)# 将points分为左右部分for i in range(len(points)):if points[i] < points[midindex]:left_points.append(points[i])else:right_points.append(points[i])distance1, close_points1 = ClosePoints1(left_points)distance2, close_points2 = ClosePoints1(right_points)if distance1 < distance2:min_distance = distance1close_points = close_points1else:min_distance = distance2close_points = close_points2# 求中间部分最小距离for i in range(len(points)):   # 把中间宽度为2*min_distance的带状区域内的子集复制到temp_points中if np.abs(points[i]-points[midindex]) <= min_distance:temp_points.append(points[i])distance3 = np.infclose_points3 = []for i in range(len(temp_points)-1):if (temp_points[i+1]-temp_points[i]) >= min_distance:breaktemp_dis = Distance(temp_points[i], temp_points[i+1])if temp_dis < distance3:distance3 = temp_disclose_points3.append(points[i])close_points3.append(points[i+1])# 求最近点if min_distance > distance3:d = distance3close_points = close_points3else:d = min_distanceclose_points=close_pointsreturn d, close_points# 排序
def Sort(points):print('随机产生的数:', points)points = sorted(points)print('排序后:', points)return ClosePoints1(points)# 随机产生[0,100]中整数
points = np.random.randint(0, 100, 8)
mindist,close_points=Sort(points)
print('最近点对:',close_points)
print('最小距离:',mindist)

结果:

分析:
    首先对随机生成的一维点进行排序,时间复杂度为O(nlogn)O(nlogn)O(nlogn)。由于情况①和情况②可递归求解,情况③的时间复杂度是O(n)O(n)O(n),合并子问题解的时间复杂度为O(1)O(1)O(1),则算法的时间复杂性可由递推式表示:T(n)=2T(n/2)+O(n)T(n)=2T(n/2)+O(n)T(n)=2T(n/2)+O(n),即T(n)=O(nlogn)T(n)=O(nlogn)T(n)=O(nlogn)。故使用分治法解决一维最近点对问题的时间复杂度为O(nlogn)O(nlogn)O(nlogn)。
    一维空间的最近点对问题,分治法对于蛮力法而言看起来并没有优势,下面看看二维空间。

2、二维空间

待更新……

最近点对问题(蛮力法和分治法)相关推荐

  1. 二分法和分治法概念区别--记录

    1.二分法和分治法的概念区别: 二分搜索每次都要舍弃一半,从留下的一半中寻找目标:而分治法把一个大问题分成两个或多个小问题,递归地求这些小问题的解,最后再把它们小心谨慎的合并起来,并且要仔细考虑合并时 ...

  2. C语言实现最大字段和(动态规划法和分治法)

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.动态规划法 二.分治法 三.程序总代码 总结 前言 本次将对最大字段和使用C语言实现的两种方法实现,动态规划法和分 ...

  3. 蛮力法-分治法-处理最近对问题

    两种方法对最近对问题的解释 背景描述:   终于,隔了将近一周,开始更新第二篇算法博客.今天的问题是最近对问题.问题描述如下:对于二维坐标系中的若干个点,从中判断出相距最近的两个点,并输出最近的这个距 ...

  4. 最大元和最小元(直接求解法和分治法)

    给定一个数组,求数组中的最大元和最小元(即最大值和最小值) 法1:直接求解 #include<iostream> using namespace std;int main(){int n, ...

  5. 主元素问题(蒙特卡洛法和分治法)

    主元素问题描述 设T为一个有n个元素的数组,当T中某个元素x的个数大于n/2时,称x为T的主元素. 蒙特卡洛算法简介 蒙特卡洛算法(Monte Carlo),是一种不确定性化算法,并无法保证一定能够得 ...

  6. 求解最大连续子序列和问题(Java)蛮力法+分治法

    求解最大连续子序列和问题 [问题描述] 给定一个有n(n>=1)个整数的序列,要求求出其中最大连续子序列的和. [样例输入] 6 -2 11 -4 13 -5 -2 [样例输出] 20 [问题求 ...

  7. Leetcode 240 Search a 2D Matrix II (二分法和分治法解决有序二维数组查找)

    1.问题描述 写一个高效的算法,从一个 m×n m\times n的整数矩阵中查找出给定的值,矩阵具有如下特点: 每一行从左到右递增. 每一列从上到下递增. 2. 方法与思路 2.1 二分查找法 根据 ...

  8. 深大算法设计与分析实验二——分治法求最近点对问题

    源代码: 深大算法设计与分析实验二--分治法求最近点对问题代码-C/C++文档类资源-CSDN下载 目录 实验问题 一.实验目的: 二.内容: 三.算法思想提示 产生不重复的随机点算法: 蛮力算法: ...

  9. 算法设计与分析 实验二 分治法求解最近点对问题

    分治法求解最近点对问题 一.实验目的与要求 1.实验基本要求 2.实验亮点 二.实验内容与方法 三.实验步骤与过程 (一)一些准备工作 1.实验流程 2.数据生成与去除重复点 (二)暴力穷举法 1.算 ...

最新文章

  1. 大二菜鸟———无重复字符的最长子串
  2. Android中自定义checkbox样式
  3. 就linux学习的一点感受,谈谈前天面试后的感受吧,关于学习Linux
  4. Linux进程编程(PS: exec族函数、system、popen函数)
  5. 145_Power BI Report Server自定义Form登录
  6. echarts中国地图描绘
  7. excel多元线性拟合_[求助]excel里面的linest函数中多元回归怎么用啊?
  8. 景点旅游信息系统——C/C++程序设计、Qt图形化界面
  9. python 结构体数组的正确初始化方法
  10. 通过修改注册表权限修复ArcMap启动报错问题
  11. 眼光独到便能发现刷脸支付带来的商机
  12. 刷屏黑洞照片背后,有17名中国科学家
  13. 【防骗】来电显示号码竟可任意修改
  14. 杭电OJ--1717
  15. 使用psftp从宿主机win11向VMware的虚拟机上传文件
  16. 线性回归算法--拟合正弦函数
  17. Mysql数据库导入excel和乱码问题
  18. matlab基础-如何在Matlab绘图中添加x坐标文字标签
  19. 几个用于前端canvas图片查看编辑的js插件
  20. 操作系统中断/异常-测试题

热门文章

  1. JavaScript中slice()、splice()、split()、join()、unshift()、push()
  2. STM32F40x 最小系统
  3. matlab 群延迟,实现最小相位群延迟的音节切分算法的一些问题
  4. 【机器学习|数学基础】Mathematics for Machine Learning系列之矩阵理论(14):向量范数及其性质
  5. 解析光纤跳线的5大知识点,让安装使用更顺畅
  6. 前端文件上传,这8种场景
  7. android之WebView应用
  8. 【BZOJ1226/SDOI2009】学校食堂Dining
  9. Spring5的IOC容器
  10. Unity通过Animator获取动画clip时长