ImageVerifierCode 换一换
格式:DOCX , 页数:23 ,大小:112.72KB ,
资源ID:12277143      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/12277143.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(0007算法笔记分治法最接近点对问题.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

0007算法笔记分治法最接近点对问题.docx

1、0007算法笔记分治法最接近点对问题问题场景:在应用中,常用诸如点、圆等简单的几何对象代表现实世界中的实体.在涉及这些几何对象的问题中,常需要了解其邻域中其他几何对象的信息.例如,在空中交通控制问题中,若将飞机作为空间中移动的一个点来看待,则具有最大碰撞危险的2架飞机,就是这个空间中最接近的一对点。这类问题是计算几何学中研究的基本问题之一。问题描述:给定平面上n个点,找其中的一对点,使得在n个点的所有点对中,该点对的距离最小。严格地说,最接近点对可能多于1对。为了简单起见,这里只限于找其中的一对. 1、一维最接近点对问题算法思路: 这个问题很容易理解,似乎也不难解决。我们只要将每一点与其他n1

2、个点的距离算出,找出达到最小距离的两个点即可。然而,这样做效率太低,需要O(n2)的计算时间。在问题的计算复杂性中我们可以看到,该问题的计算时间下界为(nlogn)。这个下界引导我们去找问题的一个(nlogn)算法.采用分治法思想,考虑将所给的n个点的集合S分成2个子集S1和S2,每个子集中约有n/2个点,然后在每个子集中递归地求其最接近的点对。在这里,一个关键的问题是如何实现分治法中的合并步骤,即由S1和S2的最接近点对,如何求得原集合S中的最接近点对,因为S1和S2的最接近点对未必就是S的最接近点对.如果组成S的最接近点对的2个点都在S1中或都在S2中,则问题很容易解决.但是,如果这2个点

3、分别在S1和S2中,则对于S1中任一点p,S2中最多只有n/2个点与它构成最接近点对的候选者,仍需做n2/4次计算和比较才能确定S的最接近点对.因此,依此思路,合并步骤耗时为O(n2)。整个算法所需计算时间T(n)应满足:T(n)=2T(n/2)+O(n2)。它的解为T(n)=O(n2),即与合并步骤的耗时同阶,这不比用穷举的方法好。从解递归方程的套用公式法,我们看到问题出在合并步骤耗时太多.这启发我们把注意力放在合并步骤上。 设S中的n个点为x轴上的n个实数x1,x2,。,xn.最接近点对即为这n个实数中相差最小的2个实数。我们显然可以先将x1,x2,。.,xn排好序,然后,用一次线性扫描就

4、可以找出最接近点对.这种方法主要计算时间花在排序上,在排序算法已经证明,时间复杂度为O(nlogn)。然而这种方法无法直接推广到二维的情形。因此,对这种一维的简单情形,我们还是尝试用分治法来求解,并希望能推广到二维的情形.假设我们用x轴上某个点m将S划分为2个子集S1和S2,使得S1=xSxm;S2=xS|xm.这样一来,对于所有pS1和qS2有pq.递归地在S1和S2上找出其最接近点对p1,p2和q1,q2,并设d=minp1p2|,|q1-q2,S中的最接近点对或者是p1,p2,或者是q1,q2,或者是某个p3,q3,其中p3S1且q3S2。如图所示。 如果S的最接近点对是p3,q3,即p

5、3q3d,则p3和q3两者与m的距离不超过d,即p3mm.然而,这样选取分割点m,有可能造成划分出的子集S1和S2的不平衡。例如在最坏情况下,S1=1,|S2|=n1,由此产生的分治法在最坏情况下所需的计算时间T(n)应满足递归方程: T(n)=T(n1)+O(n) 它的解是T(n)=O(n2)。这种效率降低的现象可以通过分治法中“平衡子问题”的方法加以解决。即通过适当选择分割点m,使S1和S2中有大致相等个数的点。自然地,我们会想到用S的n个点的坐标的中位数来作分割点.在选择算法中介绍的选取中位数的线性时间算法使我们可以在O(n)时间内确定一个平衡的分割点m. 本程序确定平衡点采用m=max

6、(S)+min(S)/2方法.如果需要利用中位数作分割点,看结合笔者博文0005算法笔记线性时间选择改写。 一维最接近临近点对问题程序清单如下:cppview plaincopy1./2d101一维最邻近点对问题2.#includestdafx。h”3.#includectime4.#includeiostream5.usingnamespacestd;6.7.constintL=100;8./点对结构体9.structPair10.11.floatd;/点对距离12.floatd1,d2;/点对坐标13.;14.floatRandom();15.intinput(floats);/构造S16

7、.floatMax(floats,intp,intq);17.floatMin(floats,intp,intq);18.templateclassType19.voidSwap(Typex,Type&y);20.templateclassType21.intPartition(Types,Typex,intl,intr);22.PairCpair(floats,intl,intr);23.24.intmain()25.26.srand(unsigned)time(NULL);27.intm;28.floatsL;29.Paird;30.m=input(s);31.d=Cpair(s,0,m1

8、);32.coutendl”最近点对坐标为:(d1:”d.d1”,d2:”d.d2”);33.coutendl这两点距离为:d。dendl;34.return0;35.36.37.38.floatRandom()39.40.floatresult=rand()%10000;41.returnresult0。01;42.43.44.intinput(floats)45.46.intlength;47.cout”输入点的数目:”;48.cinlength;49.cout点集在X轴上坐标为:;50.for(inti=0;ilength;i+)51.52.si=Random();53.coutsi”;

9、54.55.56.returnlength;57.58.59.60.floatMax(floats,intl,intr)/返回s中的最大值61.62.floats_max=sl;63.for(inti=l+1;i=r;i+)64.if(s_maxsi)65.s_max=si;66.returns_max;67.68.69.floatMin(floats,intl,intr)/返回s中的最小值70.71.floats_min=sl;72.for(inti=l+1;i=r;i+)73.if(s_minsi)74.s_min=si;75.returns_min;76.77.78.templatecl

10、assType79.voidSwap(Type&x,Typey)80.81.Typetemp=x;82.x=y;83.y=temp;84.85.86.templateclassType87.intPartition(Types,Typex,intl,intr)88.89.inti=l-1,j=r+1;90.91.while(true)92.93.while(s+ixix);95.if(i=j)96.97.break;98.99.Swap(si,sj);100.101.returnj;102.103.104./返回s中的具有最近距离的点对及其距离105.PairCpair(floats,intl

11、,intr)106.107.Pairmin_d=99999,0,0;/最短距离108.109.if(rl1)returnmin_d;110.floatm1=Max(s,l,r),m2=Min(s,l,r);111.112.floatm=(m1+m2)/2;/找出点集中的中位数113.114./将点集中的各元素按与m的大小关系分组115.intj=Partition(s,m,l,r);116.117.Paird1=Cpair(s,l,j),d2=Cpair(s,j+1,r);/递归118.floatp=Max(s,l,j),q=Min(s,j+1,r);119.120./返回s中的具有最近距离的

12、点对及其距离121.if(d1。dd2.d)122.123.if((q-p)d1。d)124.125.min_d。d=(q-p);126.min_d。d1=q;127.min_d。d2=p;128.returnmin_d;129.130.elsereturnd1;131.132.else133.134.if((q-p)d2。d)135.136.min_d。d=(qp);137.min_d.d1=q;138.min_d。d2=p;139.returnmin_d;140.141.elsereturnd2;142.143.程序运行结果如下: 该算法的分割步骤和合并步骤总共耗时O(n)。因此,算法耗费

13、的计算时间T(n)满足递归方程: 解此递归方程可得T(n)=O(nlogn). 2、二维最接近点对问题 将以上过程推广到二维最接近点对问题,设S中的点为平面上的点,它们都有2个坐标值x和y。为了将平面上点集S线性分割为大小大致相等的2个子集S1和S2,我们选取一垂直线l:x=m来作为分割直线。其中m为S中各点x坐标的中位数。由此将S分割为S1=pS|pxm和S2=pSpxm.从而使S1和S2分别位于直线l的左侧和右侧,且S=S1S2.由于m是S中各点x坐标值的中位数,因此S1和S2中的点数大致相等。递归地在S1和S2上解最接近点对问题,我们分别得到S1和S2中的最小距离d1和d2.现设d=mi

14、n(d1,d2).若S的最接近点对(p,q)之间的距离d(p,q)d则p和q必分属于S1和S2。不妨设pS1,qS2.那么p和q距直线l的距离均小于d。因此,我们若用P1和P2分别表示直线l的左边和右边的宽为d的2个垂直长条,则pS1,qS2,如图所示: 距直线l的距离小于d的所有点 在一维的情形,距分割点距离为d的2个区间(md,m(m,m+d中最多各有S中一个点。因而这2点成为唯一的末检查过的最接近点对候选者。二维的情形则要复杂些,此时,P1中所有点与P2中所有点构成的点对均为最接近点对的候选者。在最坏情况下有n2/4对这样的候选者。但是P1和P2中的点具有以下的稀疏性质,它使我们不必检查

15、所有这n2/4对候选者.考虑P1中任意一点p,它若与P2中的点q构成最接近点对的候选者,则必有d(p,q)d.满足这个条件的P2中的点有多少个呢?容易看出这样的点一定落在一个d2d的矩形R中,如下图所示:包含点q的dX2d矩形R 由d的意义可知P2中任何2个S中的点的距离都不小于d。由此可以推出矩形R中最多只有6个S中的点。事实上,我们可以将矩形R的长为2d的边3等分,将它的长为d的边2等分,由此导出6个(d/2)(2d/3)的矩形。如左图所示:矩阵R中点的稀疏性 若矩形R中有多于6个S中的点,则由鸽舍原理易知至少有一个2的小矩形中有2个以上S中的点。设u,v是这样2个点,它们位于同一小矩形中

16、,则:因此d(u,v)5d/6d .这与d的意义相矛盾.也就是说矩形R中最多只有6个S中的点。图4(b)是矩形R中含有S中的6个点的极端情形。由于这种稀疏性质,对于P1中任一点p,P2中最多只有6个点与它构成最接近点对的候选者。因此,在分治法的合并步骤中,我们最多只需要检查6n/2=3n对候选者,而不是n2/4对候选者。这是否就意味着我们可以在O(n)时间内完成分治法的合并步骤呢?现在还不能作出这个结论,因为我们只知道对于P1中每个S1中的点p最多只需要检查P2中的6个点,但是我们并不确切地知道要检查哪6个点。为了解决这个问题,我们可以将p和P2中所有S2的点投影到垂直线l上。由于能与p点一起

17、构成最接近点对候选者的S2中点一定在矩形R中,所以它们在直线l上的投影点距p在l上投影点的距离小于d。由上面的分析可知,这种投影点最多只有6个。因此,若将P1和P2中所有S的点按其y坐标排好序,则对P1中所有点p,对排好序的点列作一次扫描,就可以找出所有最接近点对的候选者,对P1中每一点最多只要检查P2中排好序的相继6个点.程序清单如下:cppview plaincopy1./2d102二维最邻近点对问题2.includestdafx。h3.includetime.h4.includeiostream5.#includecmath6.7.usingnamespacestd;8.constint

18、M=50;9.10./用类PointX和PointY表示依x坐标和y坐标排好序的点11.classPointX12.public:13.intoperator=(PointXa)const14.return(x=a。x);15.intID;/点编号16.floatx,y;/点坐标17.;18.19.classPointY20.public:21.intoperator=(PointYa)const22.return(y=a.y);23.intp;/同一点在数组x中的坐标24.floatx,y;/点坐标25.;26.27.floatRandom();28.template35.voidCopy(

19、Typea,Typeb,intleft,intright);36.37.templateclassType38.voidMerge(Typec,Typed,intl,intm,intr);39.40.templateclassType41.voidMergeSort(Typea,Typeb,intleft,intright);42.43.intmain()44.45.srand(unsigned)time(NULL));46.intlength;47.48.cout请输入点对数:”;49.cinlength;50.51.PointXXM;52.cout”随机生成的二维点对为:endl;53.5

20、4.for(inti=0;ilength;i+)55.56.Xi。ID=i;57.Xi.x=Random();58.Xi.y=Random();59.cout”(Xi。x”,”Xi.y”);60.61.62.PointXa;63.PointXb;64.floatd;65.66.Cpair2(X,length,a,b,d);67.68.coutendl;69.cout”最邻近点对为:(”a。x,”a.y”)和(”b。x,”b.y)”endl;70.cout”最邻近距离为:”dendl;71.72.return0;73.74.75.floatRandom()76.77.floatresult=ra

21、nd()%10000;78.returnresult0。01;79.80.81./平面上任意两点u和v之间的距离可计算如下82.templateclassType83.inlinefloatdis(constType&u,constTypev)84.85.floatdx=u。xv.x;86.floatdy=u。yv。y;87.returnsqrt(dx*dx+dydy);88.89.90.boolCpair2(PointXX,intn,PointXa,PointX&b,float&d)91.92.if(n2)returnfalse;93.94.PointXtmpX=newPointXn;95.MergeSort(X,tmpX,0,n-1);96.97.PointYY=newPointYn;98.for(inti=0;in;i+)/将数组X中的点复制到数组Y中99.100.Yi。p=i;101.Yi.x=Xi.x;102.Yi。y=Xi.y;103.104.105.PointY*tmpY=newPointYn;106.MergeSort(Y,tmpY,0,n1);107.108.PointY*Z=newPointYn;109.closest(X,Y,Z,0,n-1,a,b,d);110.111.deleteY;112.deleteZ;113.deletetmpX;114.del

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1