算法分析与设计作业
更新时间:2023-10-28 11:49:02 阅读量: 综合文库 文档下载
最接近点对问题
问题
此问题分为一维,二维,三维的情况
1. 一维: 给定直线上n个点,找其中一对点,使得在n个点组成的所有点对中,该点对间
的距离最小,这个问题比较简单,是引出二维解法的一个引子,因为一维的直线上的点,相邻点的距离肯定小于相隔的点的距离,只需要考虑相邻点即可。
2. 二维:给定平面上n个点,找其中一对点,使得在n个点组成的所有点对中,该点对间
的距离最小,这是我们这一问题的重点
3. 三维:给定空间上n个点,找其中一对点,使得在n个点组成的所有点对中,该点对间
的距离最小,此问题是二维的解法的复杂化,具体可以在飞机航线等问题上运用,但在此不多做介绍。
基本思想
由于该问题的基本解法是去考察每个点和其他所有点的距离。因此它的时间复杂度是
O(n2),这样做的效率太低,我们就要去寻找一个更高效的办法:分治法。
1. 因二维的情况太过复杂,先考虑一维的情况中,可以用分治法对其进行分部计算: 把直线分成两部分, s1s2,分别求出其最接近点的距离d1 d2。但分割开的地方的两点距离可能小于这两个值,这三个值进行比较之后,得到最后结果。 2. 鉴于此,二维的也可以用此方法进行计算:
把待计算的点s分成两部分s1 s2,分别求出其最接近点的距离d1 d2。但d1d2最小的未必是s中的最小距离d,它有可能是s1中的一个点和s2中的一个点组成的最接近点对。所以还要考虑s1中的所有点到s2中的每一个点的距离,一一比较之后得出一个最小值,再和d1d2比较,这就得出了最后结果。 3. 接下来是具体算法实现的步骤:
1. 把待计算的点s分成两部分s1 s2:
重要的如何去划分,这里采用在二维平面上的中线(用横坐标的最小值加上最大值的平均数)来划分。
2. 分别求出其最接近点的距离d1 d2:
这可以用一个递归来完成。
3. 计算s1中的所有点到s2中的每一个点的距离:
这个问题是此问题的关键。
页 1
首先要考虑的是,s1中的点,是不是每一个都有可能和s2中的某个点组成最接近点呢。答案是未必。假设中线的横坐标是x.而d1 d2中较小的值为d。则s1中距离中线大于d的点,它和s2中任意点的距离必定大于d。所以,只用考虑符合(X-x1 然后要考虑的是,对于每个中距离中线小于d的点,是不是s2中的每个点都有可能和其组成最接近点呢?答案也是未必。假设一个s1中距离中线小于d的点为n1,它的纵坐标为y,那么s2中距离n1小于于d的点,它的纵坐标和y之差的绝对值必然小于d。即一定在下图阴影部分之中。 在下图中,我们观察到:将阴影部分分成6块,每块顶多有一个点。否则,任意一块中的两个点,他们的距离一定小于等于(d)?(d),即小于d,这和d的定义矛盾。 至此,我们得到结论,不是每个s2中的点都需要计算的。我们只需要计算s1中距离中线x不超过d的点和与此点对应的符合阴影部分的s2中的点。 122232 4. 在第三步中的所有距离中得到一个最小距离d3,和d1 d2相比之后,得出最终 答案。 4. 现在要考虑的是这个算法和基本算法的O(n)的时间复杂度相比,它有优越性么? 假设问题的规模为n,在这个算法中,它的分割步骤和合并步骤总共耗时O(n)。因此, 2页 2 算法耗费的计算时间为T(n)满足递归方程T(n)??解此方程得T(n)=O(nlogn)。 O(1)n?4 ?2T(n/2)?O(n)n?4?源代码 因课本上的关键代码是用C++编写的。本人不善于用C++,故进行修改并用C实现。 #include int point1,point2,x[MAX]; float point[MAX][2]; float distance(int a,int b) {//两点间距离 float dx,dy; dx=point[a][0]-point[b][0]; dy=point[a][1]-point[b][1]; return (sqrt(dx*dx+dy*dy)); } void record(int a,int b) {//用point1,point2来记录最接近点的编号。 if(point1==-1){point1=a;point2=b;} else if(distance(a,b) float closest(int m,int n) {//分治法求最接近距离 float d,d1,d2,mid; int i,j,k; if((n-m)==1) { d=distance(x[m],x[n]); record(x[m],x[n]); return d; } if((n-m)==2) { d=distance(x[m],x[m+1]); d1=distance(x[m],x[n]); d2=distance(x[m+1],x[n]); if(d<=d1&&d<=d2) {record(x[m],x[m+1]); return d;} if(d1<=d&&d1<=d2) {record(x[m],x[n]); return d1;} if(d2<=d&&d2<=d1) {record(x[m+1],x[n]); return d2;} } //多于点的情况用分治法 k=(m+n)/2; d1=closest(m,k); d2=closest(k+1,n); if(d1 页 3 if(point[x[i]][0] void arrange(int n) { //对x[]进行赋值,赋值为以点的横坐标从小到大排列的点的序号 float x1[MAX],tem1; int tem; int i,j; for(i=0;i int main(void) { float x1[MAX],tem1; int i,j,n,tem; float a,b,d; point1=-1; //录入点的数据***** printf(\请输入点的个数(为大于等于的自然数):\); scanf(\,&n); for(i=0;i //****************** arrange(n); d=closest(0,n-1); printf(\最接近点对为第%d个点和第%d个点\,point1+1,point2+1); printf(\其距离为%.5f\\n\,d); system(\); return 0; } 页 4 测试数据及运行结果 为验证程序的正确性,特寻找几组独特的数据进行检测 测试数据 N 1 2 5 4 1 ,1 1 ,1 1,1 0,0 2,2 1,2 0,8 1000,1000 4,4 1050,50 4,-4 50,1050 结果 无结果 1,2 1,2 1,4 1.41421 1.0000 5.65685 观察以上测试,基本符合题意要求。但此程序仅得到一个最接近点对,若出现相等的情况, 只给出其中一个。 调试心得和源程序 源程序在源代码部分已经给出。 在调试过程中,我发现对于数组地址的传递比较容易出错,鉴于时间问题,只好采取设置全局变量的办法解决了问题。 另:本程序几乎被我重新编写,和书中的代码有巨大的差异,但算法思想是一致的。 页 5
正在阅读:
算法分析与设计作业10-28
复习题(11)01-12
2018年度医院领导个人述职述廉述德报告09-27
舞蹈仙子作文500字06-28
襄阳市第五轮学科带头人、骨干教师名单10-18
八年级英语下册Unit6Anoldmantriedtomovethemountains短语语03-16
资本结构优化决策分析12-01
世纪商务英语综合教程三(第三版)课文翻译03-26
甲级单位编制房车部件项目可行性报告(立项可研+贷款+用地+201305-03
第2章 快速入门教程01-20
- 多层物业服务方案
- (审判实务)习惯法与少数民族地区民间纠纷解决问题(孙 潋)
- 人教版新课标六年级下册语文全册教案
- 词语打卡
- photoshop实习报告
- 钢结构设计原理综合测试2
- 2014年期末练习题
- 高中数学中的逆向思维解题方法探讨
- 名师原创 全国通用2014-2015学年高二寒假作业 政治(一)Word版
- 北航《建筑结构检测鉴定与加固》在线作业三
- XX县卫生监督所工程建设项目可行性研究报告
- 小学四年级观察作文经典评语
- 浅谈110KV变电站电气一次设计-程泉焱(1)
- 安全员考试题库
- 国家电网公司变电运维管理规定(试行)
- 义务教育课程标准稿征求意见提纲
- 教学秘书面试技巧
- 钢结构工程施工组织设计
- 水利工程概论论文
- 09届九年级数学第四次模拟试卷
- 算法
- 作业
- 分析
- 设计
- 企业社工概论整理
- 公务员绩效考核
- 社会环境对消费者心理的影响
- 间位芳纶和超导材料IPO上市咨询(2014年最新政策+募投可研+细分市场调查)综合解决方案 - 图文
- 中南大学微控制器技术
- 中央广播电视大学2004—2005学年度第一学期“开放专科”期末考试
- 职业教育课程论考试试题及答案
- zemax优化浅谈
- 2018年全国高考真题(全国二卷)文科数学(word版附答案)
- 七年级下册英语复习笔记
- 第五章参数估计练习题
- 卫生系统开展医药购销和医疗服务中突出问题专项治理工作总结
- 我的承诺书
- (Java考试题)汇总
- 关于员工持股计划的探讨
- 2012苏教版五年级音乐下册教案
- 2018-2019学年青岛版八年级数学上册期末检测试卷含答案
- 系统集成与智能化培训方案
- 什么是DCS和DEH
- 李清照诗词全集赏析 - 图文