分治法求最近点对问题

news2024/9/27 5:44:38

目录

蛮力法

分治法

探究分治规模小于一定程度时采用暴力解法


蛮力法

  • 算法思想

蛮力法,顾名思义,即穷举所有点与点之间的距离,两层循环暴力找出最近点对。算法执行可视化如图1所示,word文档GIF静态显示,附件已含动图。

图1

  • 伪代码

matlab代码 

result=[];
for power=1:10
    scale=power*100000;
    count=0;
    for times=1:20
        x=randi(scale,1,scale);
        y=randi(scale,1,scale);
        tic;
        [i,j]=brute(x,y,scale);
        count=count+toc;           
    end
    count=count/20;
    result=[result,count];
end
function [mini,minj]=brute(x,y,scale)
    mini=1;
    minj=1;
    minDistance=Inf;
    for i=1:scale-1
        for j=1:scale
            if i==j
                break
            end
            distance=(x(i)-x(j))^2+(y(i)-y(j))^2;
            if distance<minDistance
                mini=i;
                minj=j;
                minDistance=distance;
            end
        end
    end
end
  • 实验结果

环境为MATLAB,数据规模为1w到5w,运行结果如图2所示。

图2

具体数据如表1所示。

表1

分析:

由实验结果可知,蛮力法的实验值与理论值基本一致,算法的时间复杂度确实为O(n2),确实很慢。

分治法

  • 算法思想

先对点进行预处理按横坐标排序,然后每次将点均分成左右两个子集,最短距离的两个点要么都在左子集,要么都在右子集,要么一个点在左子集中,一个点在右子集中,对于前面两种情况,问题变成递归寻找子集的最短距离,算法执行可视化如图3所示,word文档GIF静态显示,附件已含动图。

 

图3

而对于跨越中间线的情况,由左右两个子集可以算出一个目前最短距离minDistance,然后将距离中间点的距离小于minDistance的点找出来,如图4所示。

图4

如果存在最短距离,那么一定是一边一个点,所以我们需要将两边点的距离算一下,实际上,我们需要对于一边的点,我们需要计算距离的点最多不超过4个,因为同一边的点与点之间的距离肯定大于等于minDistance,所以对于另一边的点来说,范围小于minDistance内的点不会超过4个,如图5所示。

图5

  • 伪代码

matlab代 

result=[];
for power=1:10
    scale=power*100000;
    count=0;
    for times=1:20
        x=randi(scale,1,scale);
        y=randi(scale,1,scale);
        tic;
        [x,y]=Quick(1,scale,x,y);
        [mini,minj,minDistance]=divide(x,y,scale);
        count=count+toc;           
    end
    count=count/20;
    result=[result,count];
end
function [mini,minj,minDistance]=brute(x,y,scale)
    mini=1;
    minj=2;
    minDistance=Inf;
    for i=1:scale-1
        for j=i+1:scale
            distance=(x(i)-x(j))^2+(y(i)-y(j))^2;
            if distance<minDistance
                mini=i;
                minj=j;
                minDistance=distance;
            end
        end
    end
end
function [mini,minj,minDistance]=divide(x,y,scale)
    if length(x)<3
        [mini,minj,minDistance]=brute(x,y,scale);
        return;
    end
    half=floor(scale/2);
    [i,j,minLeft]=divide(x(1:half),y(1:half),half);
    [ii,jj,minRight]=divide(x(half+1:scale),y(half+1:scale),scale-half);
    if minLeft<minRight
        minDistance=minLeft;
        mini=i;
        minj=j;
    else
        minDistance=minRight;
        mini=ii;
        minj=jj;
    end
    left=[];
    right=[];
    for i=half-1:-1:1
        if abs(x(i)-x(half))>=sqrt(minDistance)
            break
        end
        left=[left,i];
    end
    for i=half+1:scale
        if abs(x(i)-x(half))>=sqrt(minDistance)
            break
        end
        right=[right,i];
    end
    for i=1:length(left)
        for j=1:length(right)
            if j>3
                break
            end
            distance=(x(left(i))-x(right(j)))^2+(y(left(i))-y(right(j)))^2;
            if distance<minDistance
                mini=left(i);
                minj=right(j);
                minDistance=distance;
            end
        end
    end
    for i=1:length(right)
        for j=1:length(left)
            if j>3
                break
            end
            distance=(x(left(j))-x(right(i)))^2+(y(left(j))-y(right(i)))^2;
            if distance<minDistance
                mini=left(j);
                minj=right(i);
                minDistance=distance;
            end
        end
    end
end
function[x,y]=Quick(low,high,x,y)
    i=low;
    j=high;
    pivot=x(low);
    temp=y(low);
    while low<high
        while low<high&&pivot<=x(high)
            high=high-1;
        end
        if low<high
            x(low)=x(high);
            y(low)=y(high);
            low=low+1;
        end
        while low<high&&pivot>x(low)
            low=low+1;
        end
        if low<high
            x(high)=x(low);
            y(high)=y(low);
            high=high-1;
        end
    end
    x(low)=pivot;
    y(low)=temp;
    if i<low-1
        [x,y]=Quick(i,low-1,x,y);
    end
    if high+1<j
        [x,y]=Quick(high+1,j,x,y);
    end
end
  • 算法复杂度

对于数据规模为n的情况,二分的次数为log2n次,而计算跨中间线距离的时候计算次数小于3n,即此处的时间复杂度是线性的,即T(n)=T(n/2)+O(n),可算得T(n)=nlogn。

  • 实验结果

先在小规模数据上跑,环境为MATLAB,数据规模为1w到5w,运行结果如图6所示。

图6

具体数据如表2所示。

表2

数据规模为10w到100w,运行结果如图7所示。

图7

具体数据如表3所示。

表3

分析:

由实验结果可知,分治法明显远远快于蛮力法,小规模数据时实验值略小于理论值,大规模时实验值与理论值基本一致。

探究分治规模小于一定程度时采用暴力解法

由于分治时不断递归调用函数,程序开销较大,考虑当分治到数据规模小于一定程度时采用暴力解法的运行效果,数据规模为1w,参数设置100到1000测试,结果如图8所示。

图8

由实验结果可知,分治规模达到200时使用暴力效果最佳,将参数设置为200,在数据规模为1w到5w上与原始分治法对比,如图9所示。

图9

在数据规模为10w到100w上与原始分治法对比,如图10所示。

图10

分析:

由实验结果可知,在分治规模小于一定数量时采用暴力求解效率更快,特别是在数据规模大的时候,这种暴力分治相结合的方法相比原始分治法具有很大的优势。

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

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

相关文章

BTY Carnival - Task2 | Get the OG Role Win USDT

欢迎来到比特元社区&#xff01; 比特元是一条兼具平行链与零知识证明技术的EVM兼容区块链。BitYuan的生态系统dns.bityuan.com即将开放公测。用户完成任务即获得白名单资格&#xff0c;可进入到DC群的DNS白名单频道 &#xff0c;我们将定期开展抽BTY等活动&#xff0c;并且将…

2022年第十三届JAVA B组国赛

文章目录 A.重合次数&#xff08;模拟&#xff09;B.数数&#xff08;数学&#xff09; A.重合次数&#xff08;模拟&#xff09; Answer:494 这个题目比较坑人&#xff0c; public class Main {static BufferedReader br new BufferedReader(new InputStreamReader(System.…

多元回归预测 | Matlab阿基米德算法(AOA)优化极限梯度提升树XGBoost回归预测,AOA-XGBoost回归预测模型,多变输入模型

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 阿基米德算法(AOA)优化极限梯度提升树XGBoost回归预测,AOA-XGBoost回归预测模型,多变输入模型,多变量输入模型,多变量输入模型,matlab代码回归预测,多变量输入模型,多变量输入模型 评价指标包括:MAE、RMSE和R2…

一文3000字从0到1带你进行Mock测试(建议收藏)

​什么是mock&#xff1f; ​mock测试是以可控的方式模拟真实的对象行为。程序员通常创造模拟对象来测试对象本身该具备的行为&#xff0c;很类似汽车设计者使用碰撞测试假人来模拟车辆碰撞中人的动态行为 为什么要使用Mock&#xff1f; 之所以使用mock测试&#xff0c;是因…

pdf怎么转换成jpg图片?分享几个实用的方法!

记灵在线工具是一种非常方便的工具&#xff0c;可以帮助我们将PDF文件转换为图片格式。下面介绍三种不同的方法&#xff0c;让我们来了解一下。 方法一&#xff1a;记灵在线工具 1、打开记灵在线工具&#xff0c;在工具列表中选择“PDF转图片”。 2、将需要转换的PDF文件添加…

[C语言][小游戏][猜数游戏]

C语言的奇妙旅行 目录&#xff1a;一、猜数判定二、重复到猜对为止三、随机设定目标数字四、限制输入次数五、保存输入的记录六、测试小游戏 目录&#xff1a; 带着梦想&#xff0c;带着好奇&#xff0c;带着执着&#xff0c;在C语言的世界里旅行。亲爱的朋友们&#xff0c;一…

能源结构变更图,传统能源结构对比新兴能源

以传统的能源&#xff08;煤、天然气&#xff09;提供能源&#xff0c;到新兴能源 目前新兴能源以 太阳能&#xff0c;风能为主以及其它行业&#xff0c; 一类企业以新兴能源这种为主&#xff0c;核心是能源接收&#xff0c;以及储存能源&#xff0c;存储通常两种方式&#x…

cmake列表

目录 cmake多行注释 求list长度 demo 获取list的值 demo 插入list demo 追加list demo 查找列表中的字符 demo 删除list list向前删除和向后删除数据 demo 字符串反转 demo 特殊操作 Readinglist(LENGTH <list> <out-var>)list(GET <list> &…

STM32CubeMX开发实战1-LED点灯

目录 点灯选择 MCU引脚设置时钟设置项目配置生成项目项目文件介绍Debugger 设置 点灯 这里将会以一个最简单的一个点灯实验来展示如何使用 STM32CubeMX 快速生成 STM32 工程并上手开发&#xff0c;包括对项目工程建立的详细内容分析解释 接下来使用正点原子探索者开发板 STM32F…

101、基于STM32单片机智能输液器红外点滴液位监控报警系统设计(程序+原理图+PCB源文件+参考论文+硬件设计资料+元器件清单等)

单片机主芯片选择方案 方案一&#xff1a;AT89C51是美国ATMEL公司生产的低电压&#xff0c;高性能CMOS型8位单片机&#xff0c;器件采用ATMEL公司的高密度、非易失性存储技术生产&#xff0c;兼容标准MCS-51指令系统&#xff0c;片内置通用8位中央处理器(CPU)和Flash存储单元&a…

Python程序设计

很多刚接触Python的同学会觉得Python就和shell语言一样&#xff0c;是一门脚本语言&#xff0c;并不需要设计&#xff0c;只需要关注要实现的功能。确实一门计算机语言的诞生就是为了去更好的解决当前的痛点&#xff0c;功能实现肯定是第一位的。但是如何在功能实现的前提下&am…

【人工智能】您必须了解的最佳聊天机器人框架

在本博客中&#xff0c;我们将讨论 7 大聊天机器人开发框架。 聊天机器人现在已成为许多企业不可或缺的一部分。他们利用聊天机器人提供客户支持服务。聊天机器人增强了人工代理以提供客户服务支持。企业每天都会收到大量查询。手动回答这些问题不仅耗时&#xff0c;而且还会增…

数据结构--由遍历序列构造二叉树

数据结构–由遍历序列构造二叉树 不同二叉树的中序遍历序列 中序遍历:中序遍历 左 \color{red}左 左子树、 根 \color{purple}根 根结点、中序遍历 右 \color{green}右 右子树 中序遍历序列:BDCAE 结论 : 一个中序遍历序列可能对应多种二叉树形态 \color{green}结论:一个中序…

4.4 x64dbg 绕过反调试保护机制

在Windows平台下&#xff0c;应用程序为了保护自己不被调试器调试会通过各种方法限制进程调试自身&#xff0c;通常此类反调试技术会限制我们对其进行软件逆向与漏洞分析&#xff0c;下面是一些常见的反调试保护方法&#xff1a; IsDebuggerPresent&#xff1a;检查当前程序是…

OpenCV 入门教程:图像读取和显示

OpenCV 入门教程&#xff1a;图像读取和显示 导语一、图像读取1.1、导入 OpenCV 库1.2、读取图像文件1.3、图像读取的返回值 二、图像显示2.1、创建窗口2.2、图像显示2.3、等待按键2.4、关闭窗口 三、示例应用总结 导语 在计算机视觉和图像处理领域&#xff0c;读取和显示图像…

非局部均值滤波(磨皮)

note 根据掩膜区域与其他区域的相似程度来赋予掩膜区域像素权重 相似程度由均方差来衡量 code /*\brief 矩阵求邻和\param type1&#xff0c;列方向&#xff1b;type2&#xff0c;行方向 */ static void MyCumSum(Mat& src, Mat& res, int type) {if ((src.channel…

关于impacket套件中的atexec.py在使用的时候报error: unrecognized arguments: 的解决方案

定位到库文件C:\Users\LC\AppData\Local\Programs\Python\Python311\Lib\argparse.py 加一个return args就行了 用完记得改回来&#xff0c;不然会影响其他脚本的功能

算法分析和设计选择和判断

算法分析和设计选择和判断 目录 平时测试 1.算法概述 1.1渐进符号的概念 1.2求时间复杂度 1.3比较时间复杂度 1.4时间复杂度定义 1.5算法的有效性 1.6算法的性质 1.7顺序搜索法 1.8渐进算法分析 2.递归和分治策略 2.1归并排序 2.2归并的空间复杂度 2.3插入排序 2.4递归 2.5归并…

Docker容器与HSM整合的好处

Docker透过容器使创建、部署和运行应用程式变得更加容易。容器允许开发人员可以将一个应用程式与它所需要的所有部分封包&#xff0c;然后将应用程式及其组件作为一个单一的套装软体。 Docker面临的挑战 : ● 遭受特权用户滥用的风险 Docker环境或容器内的权限配置不当可能会导…

Redis常见数据结构

文章目录 前言一、Redis通用命令二、String类型三、Key的层级结构四、Hash类型五、List类型六、Set类型七、SortedSet类型 前言 Redis是一个key-value的数据库&#xff0c;key一般是String类型&#xff0c;但是value的类型多种多样 在学习Redis不同数据类型时&#xff0c;我们…