最近点对问题(欧几里得算法)
2015-08-01 16:10
239 查看
算法设计技巧与分析p123算法6.7
这是一个相当有难度的问题,给出n个点在O(nlogn)的时间复杂度内求出距离最近的两点间的距离,具体分析可以参考书本,用到了分治的思想,另外,注意每个点最多只需要和临近的7个点相比较就能求出最近距离,这是本算法的一个关键之处。
这是一个相当有难度的问题,给出n个点在O(nlogn)的时间复杂度内求出距离最近的两点间的距离,具体分析可以参考书本,用到了分治的思想,另外,注意每个点最多只需要和临近的7个点相比较就能求出最近距离,这是本算法的一个关键之处。
/** * * @author yyd * 欧几里得算法得出平面上举例最近的两个点 * */ class Point { double x; double y; public Point(double x, double y) { this.x = x; this.y = y; } public double getX() { return x; } public void setX(double x) { this.x = x; } public double getY() { return y; } public void setY(double y) { this.y = y; } } public class CLOSESTPAIR { public static double closet(int low,int high,Point[] S,Point[] Y){ if(high-low<=2){ if(high-low==1){ return dist(S[low],S[high]); } else{ //此时high-low=2 int temp=low+1; double d1=dist(S[low],S[temp]); double d2=dist(S[temp],S[high]); double d3=dist(S[low],S[high]); double min=d1<d2?d1:d2; min=min<d3?min:d3; return min; } } else{ int mid=(low+high)/2; double x=S[mid].getX(); double d1=closet(low,mid,S,Y); double d2=closet(mid+1,high,S,Y); double d=d1<d2?d1:d2; int k=0; Point T[]=new Point[Y.length]; for(int i=0;i<Y.length;i++){ //将离x的距离小于d的点抽取出来并按照他们的纵坐标放置在T中 if((Y[i].getX()-x)<d){ T[k++]=Y[i]; //注意数组T放置的是点而非坐标 } } k--; double dd=2*d; for(int i=0;i<k-1;i++){ for(int j=i+1;j<=(i+7<k?i+7:k);j++){ //最多只需要与邻近的7个点相比较就可以了 if(dist(T[i],T[j])<dd){ dd=dist(T[i],T[j]); } } } d=d<dd?d:dd; return d; } } public static double dist(Point x,Point y){ double distx=Math.abs(x.getX()-y.getX()); double disty=Math.abs(x.getY()-y.getY()); return Math.sqrt(disty*disty+distx*distx); } public static void preSortByX(Point[] S){ int len=S.length; for(int i=1;i<=len-1;i++){ for(int j=S.length-1;j>=i;j--){ if(S[j].getX()<S[j-1].getX()){ Point temp=S[j-1]; S[j-1]=S[j]; S[j]=temp; } } } } public static void preSortByY(Point[] S){ int len=S.length; for(int i=1;i<=len-1;i++){ for(int j=S.length-1;j>=i;j--){ if(S[j].getY()<S[j-1].getY()){ Point temp=S[j-1]; S[j-1]=S[j]; S[j]=temp; } } } } public static void main(String args[]){ Point x=new Point(1.2,2.5); Point y=new Point(1.5,2.0); Point z=new Point(1.7,2.0); Point w=new Point(0.8,2.5); Point u=new Point(0.1,2.5); Point[] S={x,y,z,u,w}; Point[] Y=new Point[5]; preSortByY(S); for(int i=0;i<S.length;i++){ Y[i]=S[i]; } preSortByX(S); System.out.println(closet(0,4,S,Y)); } }
相关文章推荐
- 静态初始化与构造函数,先执行静态初始化,再执行构造函数,总是先执行父类的,再执行子类的
- PsCreateSystemThread
- hihoCoder 1051 补提交卡
- 系统之家一键重装工具怎么使用?系统之家一键重装工具安装win8图文教程
- solr httpclient请求方式 原子更新索引
- [python]字符串的排序
- Android源码大放送(实战开发必备)
- java泛型之基础
- HDU 2435 There is a war Dinic 最小割
- WCF HTTP 错误 404.3 - Not Found(由于扩展配置问题而无法提供您请求的页面。如果该页面是脚本,请添加处理程序。如果应下载文件,请添加 MIME 映射。)
- 初等数论总结(填坑)
- WCF HTTP 错误 404.3 - Not Found(由于扩展配置问题而无法提供您请求的页面。如果该页面是脚本,请添加处理程序。如果应下载文件,请添加 MIME 映射。)
- Android Touch事件传递机制解析
- VK Cup 2015 - Finals F. Clique in the Divisibility Graph
- CodeForces-546D Soldier and Number Game
- Android studio引入百度地图时的bug
- Android开发----音乐播放器(界面设计)
- Flash&Flex大全资料大全(转自zrong's blog)
- Embedding SQLite in a c programm
- RecyclerView