




已阅读5页,还剩5页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
蛮力法与分治法求解最近对问题1、蛮力法蛮力法是一种简单直接地解决问题的方法,常常直接基于问题的描述和所涉及的概念定义,来求解问题。虽然巧妙和高效的算法很少来自于蛮力法,但它仍是一种重要的算法设计策略:(1)适用泛围广,是能解决几乎所有问题的一般性方法;(2)常用于一些非常基本、但又十分重要的算法(排序、查找、矩阵乘法和字符串匹配等);(3)解决一些规模小或价值低的问题;(4)可以做为同样问题的更高效算法的一个标准;(5)可以通过对蛮力法的改进来得到更好的算法。2、分治法 分治法,就是分而治之即把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题直到问题解决。分治法在求解问题时,效率比较高,也是一种重要的算法策略:(1)该问题的规模缩小到一定的程度就可以容易地解决; (2)该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质; (3)利用该问题分解出的子问题的解可以合并为该问题的解; (4)该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子子问题。 算法的基本思想及复杂度分析1蛮力法(1)基本思想蛮力法求解最近对问题的过程是:分别计算每一对点之间的距离,然后通过排序找出距离最小的一对,为了避免对同一对点计算两次距离,只考虑ij的那些点对(Pi,Pj)。(2)复杂度分析算法的基本操作是计算两个点的欧几里得距离。在求欧几里得距离时,我们要避免求平方根操作,因为求平方根时要浪费时间,而在求解此问题时,求解平方根并没什么更大的意义。如果被开方的数越小,则它的平方根也越小。因此,算法的基本操作就是求平方即可,其执行次数为:T(n)= =2=n(n-1)=O(n)2.分治法(1)基本思想用分治法解决最近对问题,就是将集合S分成两个子集S1和S2,每个子集中有n/2个点。然后在每个子集中递归的求其最接近的点对,在求出每个子集的最接近点对后,关键问题是如何实现分治法中的合并步骤,如果组成S的最接近点对的2个点都在S1中或都在S2中,则问题很容易解决。但是,如果这2个点分别在S1和S2中,则对于S1中任一点p,S2中最多只有n/2个点与它构成最接近点对的候选者,仍需计算才能得到准确结果。 (2)复杂度分析应用分治法求解含有n个点得最近对问题,其时间复杂性可由下面的递推式表示:T(n)=2T(n/2)+f(n)合并子问题的解的时间f(n)=O(1),由通用分治递推式的主定理可得:T(n)=O(nlogn) 为提高算法效率,在算法中采用预排序技术,即在使用分治法之前,预先将S中的n个点依其y坐标排序好。经过预排序处理后的算法所需的计算时间T(n)满足递归方程:当n小于4时,T(n)=O(1);当n大于等于4时,T(n)=2T(n/2)+O(n)。由此易知,T(n)=O(nlogn)。预排序所需的计算时间显然为O(nlogn)。因此,整个算法所需的计算时间为O(nlogn) 在点的个数比较少的时候,蛮力法所用时间比分治法少,点数比较多的情况下,分治法的优势就很明显了,所用时间明显比蛮力法少。算法描述(1)蛮力法在最近对问题中的算法描述程序:import java.util.*;public class manlifa public static void main(String args) Scanner in=new Scanner(System.in); System.out.println(有多少对点需要比较?); int n=in.nextInt(); int x=new intn; int y=new intn; System.out.println(请输入这些点,横坐标:); for(int i=0;i n;i+) xi=in.nextInt(); System.out.println(请输入这些点,纵坐标:); for(int i=0;i n;i+) yi=in.nextInt(); double minDist=Double.POSITIVE_INFINITY; double d; int indexI=0; int indexJ=0; double startTime=System.currentTimeMillis();/startTime for(int i=0;i n-1;i+) for(int j=i+1;j n;j+) d=Math.sqrt(xi-xj)*(xi-xj)+(yi-yj)*(yi-yj); if(d minDist) minDist=d; indexI=i; indexJ=j; double endTime=System.currentTimeMillis();/endTime System.out.println(比较的点为:(+xindexI+,+yindexI+) and (+xindexJ+,+yindexJ+); System.out.println(最近距离为: +minDist); System.out.println(基本语句用时 +(endTime-startTime)+ milliseconds!); 运行结果:(2) 分治法在最近对问题中的算法描述 import java.util.*;public class fenzhifa public static void main(String args) Scanner in=new Scanner(System.in); System.out.println(有多少对点需要比较?); int n=in.nextInt(); System.out.println(请输入这些点,x坐标和y坐标:); Point S=new Pointn; double startTime=System.currentTimeMillis(); for(int i=0;i n;i+) int x=in.nextInt(); int y=in.nextInt(); Si=new Point(x,y); System.out.println(+Si.getX()+,+Si.getY()+); /* *求出这点的x坐标的中位数mid */ int minX=(int)Double.POSITIVE_INFINITY; int maxX=(int)Double.NEGATIVE_INFINITY; for(int i=0;i n;i+) if(Si.getX()maxX) maxX=Si.getX(); int mid=(minX+maxX)/2; ArrayList point1=new ArrayList(); ArrayList point2=new ArrayList(); for(int i=0;i n;i+) if(Si.getX()=mid) point1.add(Si); else point2.add(Si); Point S1=new Pointpoint1.size(); Point S2=new Pointpoint2.size(); point1.toArray(S1); point2.toArray(S2); sortX(S1); sortX(S2); double minDist1=Double.POSITIVE_INFINITY; int indexI1=0; int indexJ1=0; for(int i=0;i S1.length-1;i+) for(int j=i+1;j S1.length;j+) double d=Math.sqrt(Math.pow(S1i.getX()-S1j.getX(),2)+Math.pow(S1i.getY()-S1j.getY(),2); if(d minDist1) minDist1=d; indexI1=i; indexJ1=j; double minDist2=Double.POSITIVE_INFINITY; int indexI2=0; int indexJ2=0; for(int i=0;i S2.length-1;i+) for(int j=i+1;j S2.length;j+) double d=Math.sqrt(Math.pow(S2i.getX()-S2j.getX(),2)+Math.pow(S2i.getY()-S2j.getY(),2); if(d minDist2) minDist2=d; indexI2=i; indexJ2=j; double d1=Math.min(minDist1,minDist2); ArrayList pp1=new ArrayList(); ArrayList pp2=new ArrayList(); for(int i=0;i S1.length;i+) if(mid-S1i.getX() d1) pp1.add(S1i); for(int i=0;i S2.length;i+) if(S2i.getX()-mid) d1) pp2.add(S2i); Point P1=new Pointpp1.size(); Point P2=new Pointpp2.size(); pp1.toArray(P1); pp2.toArray(P2); /* *将P1和P2中的点按Y坐标升序排列 */ sortY(P1); sortY(P2); double d2=Double.POSITIVE_INFINITY; for(int i=0;i P1.length;i+) for(int j=0;j P2.length;j+) if(Math.abs(P1i.getY()-P2j.getY() d1) double temp=Math.sqrt(Math.pow(P1i.getX()-P2j.getX(),2)+Math.pow(P1i.getX()-P2j.getX(),2); if(temp d2) d2=temp; double endTime=System.currentTimeMillis();/endtime double minDist=Math.min(d1,d2); System.out.println(最近距离为: +minDist); System.out.println(基本语句用时+(endTime-startTime)+ milliseconds!); public static void sortX(Point p) for(int i=0;i p.length-1;i+) for(int j=0;jpj+1.getX() int t=pj.getX(); pj.setX(pj+1.getX(); pj+1.setX(t); int n=pj.getY(); pj.setY(pj+1.getY(); pj+1.setY(n); public static void sortY(Point p) for(int i=0;i p.length-1;i+) for(int j=0;jpj+1.getY() int t=pj.getY(); pj.setY(pj+1.getY(); pj+1.setY(t); int n=pj.getX(); pj.setX(pj+1.getX(); pj+1.setX(n); class Po
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论