您的位置:首页 > 其它

最近点对问题(欧几里得算法)

2015-08-01 16:10 239 查看
算法设计技巧与分析p123算法6.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));

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: