最近点对问题-Read.DOCVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
最近点对问题-Read

最近点对问题 I.一维问题: 一、问题描述和分析 最近点对问题的提法是:给定平面上n个点,找其中的一对点,使得在n个点组成的所有点对中,该点对间的距离最小。 严格的讲,最接近点对可能多于1对,为简单起见,只找其中的1对作为问题的解。简单的说,只要将每一点与其它n-1个点的距离算出,找出达到最小距离的2点即可。但这样效率太低,故想到分治法来解决这个问题。也就是说,将所给的平面上n个点的集合S分成2个子集S1和S2,每个子集中约有n/2个点。然后在每个子集中递归的求其最接近的点对。这里,关键问题是如何实现分治法中的合并步骤,即由S1和S2的最接近点对,如何求得原集合S中的最接近点对。如果组成S的最接近点对的2个点都在S1中或都在S2中,则问题很容易解决,但如果这2个点分别在S1和S2中,问题就不那么简单了。下面的基本算法中,将对其作具体分析。 二、基本算法 假设用x轴上某个点m将S划分为2个集合S1和S2,使得S1={x∈S|x=m};S2={x∈S|xm}。因此,对于所有p∈S1和q∈S2有pq。 递归的在S1和S2上找出其最接近点对{p1,p2}和{q1,q2},并设d=min{|p1-p2|,|q1-q2|}。由此易知,S中的最接近点对或者是{p1,p2},或者是{q1,q2},或者是某个{p3,q3},其中p3∈S1且q3∈S2。如下图所示: 注意到,如果S的最接近点对是{p3,q3},即|p3-q3|d,则p3和q3两者与m的距离不超过d,即|p3-m|d,|q3-m|d。也就是说,p3∈(m-d,m],q3∈(m,m+d]。由于每个长度为d的半闭区间至多包含S1中的一个点,并且m是S1和S2的分割点,因此(m-d,m]中至少包含一个S中的点。同理,(m,m+d]中也至少包含一个S中的点。由上图知,若(m-d,m]中有S的点,则此点就是S1中最大点。同理,若(m,m+d]中有S的点,则此点就是S2中最小点。因此,用线性时间就可以找到区间(m-d,m]和(m,m+d]中所有点,即p3和q3。从而用线性时间就可以将S1的解和S2的解合并成为S的解。其中,为使S1和S2中有个数大致相等的点,选取S中个点坐标的中位数来作分割点m。具体算法实现见程序。 三、实现环境 本程序在VC++环境下实现。 四、测试情况 本程序可按屏幕提示进行输入操作,即相应输出如下: 输入一维点集的各元素(以-1结束): 5 3 9 6 8 15 26 -1 该一维点集中最近点对为(9,8),其距离为1 五、源代码 #include iostream.h #define M 20 struct cpair//表示具有最近距离的点对(d1,d2)的距离dist { float dist; float d1,d2; }; int input(float s[],int n)//s[]为一维点集,n为s[]中的元素个数 { cout输入一维点集的各元素(以-1结束):\n; n=0; cins[n]; while(s[n]!=-1) { n++; cins[n]; } return n; } float max(float s[],int b,int e)//返回s[b]到s[e]中的最大值 { float m1=s[b]; for(int i=b+1;i=e;i++) if(m1s[i]) m1=s[i]; return m1; } float min(float s[],int b,int e)//返回s[b]到s[e]中的最小值 { float m1=s[b]; for(int i=b+1;i=e;i++) if(m1s[i]) m1=s[i]; return m1; } //返回s[]中的具有最近距离的点对及其距离 cpair cpair1(float s[],int n) { cpair temp={1000,0,0}; //当点集中元素的个数不足2时,返回具有无穷大的dist值(此处设为1000)的temp if(n2) return temp; float m1=max(s,0,n-1),m2=min(s,0,n-1); float m=(m1+m2)/2;//找出点集中的中位数 int j=0,k=0; //将点集中的各元素按与m的大小关系分组 float s1[M],s2[M]; for(int i=0;in;i++) { if(s[i]=m) {s1[j]=s[i];j++;} else {s2[k]=s[i];k++;} } cpair d1=cpair1(s1,j),d2=cpair1(s2,k);//递归 float p=max(s1,0,j-1),q=max(s

文档评论(0)

wumanduo11 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档