蠻力法和分治法 求最近對問題——Java 實現
阿新 • • 發佈:2019-02-05
public class ClosestPair2
{
public static void main(String[] args)
{
/**
*輸入需要比較的點的對數存在變數n中
*/
Scanner in=new Scanner(System.in);
System.out.println("How many pairs of points to compare?(有多少對點需要比較?)");
int n=in.nextInt();
/**
*輸入這些點的橫座標和縱座標,儲存在點陣列S[n]中
*/
System.out.println("Please enter these points,X-coordinate and Y-coordinate.(請輸入這些點,x座標和y座標):");
Point[] S=new Point[n];
double startTime=System.currentTimeMillis();//starttime
for(int i=0;i<n;i++)
{
int x=in.nextInt();
int y=in.nextInt();
S[i]=new Point(x,y);
System.out.println("("+S[i].getX()+","+S[i].getY()+")");
}
/**
*求出這點的x座標的中位數mid
*/
int minX=(int)Double.POSITIVE_INFINITY;
int maxX=(int)Double.NEGATIVE_INFINITY;
for(int i=0;i<n;i++)
{
if(S[i].getX()<minX)
minX=S[i].getX();
if(S[i].getX()>maxX)
maxX=S[i].getX();
}
int mid=(minX+maxX)/2;
/**
*以mid為界把S中的點分為兩組分別存放在範型陣列列表point1和point2中
*/
ArrayList<Point> point1=new ArrayList<Point>();
ArrayList<Point> point2=new ArrayList<Point>();
for(int i=0;i<n;i++)
{
if(S[i].getX()<=mid)
point1.add(S[i]);
else
point2.add(S[i]);
}
/**
*將範型陣列列表轉換為陣列型別S1和S2
*/
Point[] S1=new Point[point1.size()];
Point[] S2=new Point[point2.size()];
point1.toArray(S1);
point2.toArray(S2);
/**
*將S1和S2中的點按x 座標升序排列
*/
sortX(S1);
sortX(S2);
/**
*列印輸出排序後S1和S2的點
*/
System.out.print("The points in S1 are:");
for(int i=0;i<S1.length;i++)
System.out.print("("+S1[i].getX()+","+S1[i].getY()+") ");
System.out.println();
System.out.print("The points in S2 are:");
for(int i=0;i<S2.length;i++)
System.out.print("("+S2[i].getX()+","+S2[i].getY()+") ");
System.out.println();
/**
*求S1中點的最近對及其距離並列印輸出結果
*/
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((S1[i].getX()-S1[j].getX()),2)+Math.pow((S1[i].getY()-S1[j].getY()),2));
if(d<minDist1)
{
minDist1=d;
indexI1=i;
indexJ1=j;
}
}
}
System.out.println("The closest pair in S1 is: "+"("+S1[indexI1].getX()+","+S1[indexI1].getY()+")"+
"and("+S1[indexJ1].getX()+","+S1[indexJ1].getY()+")"+",and the distance is "+minDist1);
/**
*求S2中點的最近對及其距離並列印輸出結果
*/
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((S2[i].getX()-S2[j].getX()),2)+Math.pow((S2[i].getY()-S2[j].getY()),2));
if(d<minDist2)
{
minDist2=d;
indexI2=i;
indexJ2=j;
}
}
}
System.out.println("The closest pair in S2 is: "+"("+S2[indexI2].getX()+","+S2[indexI2].getY()+")"+
"and("+S2[indexJ2].getX()+","+S2[indexJ2].getY()+")"+",and the distance is "+minDist2);
double d1=Math.min(minDist1,minDist2);
/**
*求出S1和S2中點的橫座標離小於d1的所有點分別存在P1[]和P2[]中
*/
ArrayList<Point> pp1=new ArrayList<Point>();
ArrayList<Point> pp2=new ArrayList<Point>();
for(int i=0;i<S1.length;i++)
{
if((mid-S1[i].getX())<d1)
pp1.add(S1[i]);
}
for(int i=0;i<S2.length;i++)
{
if((S2[i].getX()-mid)<d1)
pp2.add(S2[i]);
}
Point[] P1=new Point[pp1.size()];
Point[] P2=new Point[pp2.size()];
pp1.toArray(P1);
pp2.toArray(P2);
/**
*將P1和P2中的點按Y座標升序排列
*/
sortY(P1);
sortY(P2);
/**
*求解P1和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(P1[i].getY()-P2[j].getY())<d1)
{
double temp=Math.sqrt(Math.pow((P1[i].getX()-P2[j].getX()),2)+Math.pow((P1[i].getX()-P2[j].getX()),2));
if(temp<d2)
d2=temp;
}
}
}
double endTime=System.currentTimeMillis();//endtime
/**
*列印輸出最後求出的結果,最近的是哪兩個點,以及最近距離和程式用的時間
*/
System.out.print("The points in P1 are:");
for(int i=0;i<P1.length;i++)
System.out.print("("+P1[i].getX()+","+P1[i].getY()+") ");
System.out.println();
System.out.print("The points in P2 are:");
for(int i=0;i<P2.length;i++)
System.out.print("("+P2[i].getX()+","+P2[i].getY()+") ");
System.out.println();
System.out.println("d2="+d2);
{
public static void main(String[] args)
{
/**
*輸入需要比較的點的對數存在變數n中
*/
Scanner in=new Scanner(System.in);
System.out.println("How many pairs of points to compare?(有多少對點需要比較?)");
int n=in.nextInt();
/**
*輸入這些點的橫座標和縱座標,儲存在點陣列S[n]中
*/
System.out.println("Please enter these points,X-coordinate and Y-coordinate.(請輸入這些點,x座標和y座標):");
Point[] S=new Point[n];
double startTime=System.currentTimeMillis();//starttime
for(int i=0;i<n;i++)
{
int x=in.nextInt();
int y=in.nextInt();
S[i]=new Point(x,y);
System.out.println("("+S[i].getX()+","+S[i].getY()+")");
}
/**
*求出這點的x座標的中位數mid
*/
int minX=(int)Double.POSITIVE_INFINITY;
int maxX=(int)Double.NEGATIVE_INFINITY;
for(int i=0;i<n;i++)
{
if(S[i].getX()<minX)
minX=S[i].getX();
if(S[i].getX()>maxX)
maxX=S[i].getX();
}
int mid=(minX+maxX)/2;
/**
*以mid為界把S中的點分為兩組分別存放在範型陣列列表point1和point2中
*/
ArrayList<Point> point1=new ArrayList<Point>();
ArrayList<Point> point2=new ArrayList<Point>();
for(int i=0;i<n;i++)
{
if(S[i].getX()<=mid)
point1.add(S[i]);
else
point2.add(S[i]);
}
/**
*將範型陣列列表轉換為陣列型別S1和S2
*/
Point[] S1=new Point[point1.size()];
Point[] S2=new Point[point2.size()];
point1.toArray(S1);
point2.toArray(S2);
/**
*將S1和S2中的點按x 座標升序排列
*/
sortX(S1);
sortX(S2);
/**
*列印輸出排序後S1和S2的點
*/
System.out.print("The points in S1 are:");
for(int i=0;i<S1.length;i++)
System.out.print("("+S1[i].getX()+","+S1[i].getY()+") ");
System.out.println();
System.out.print("The points in S2 are:");
for(int i=0;i<S2.length;i++)
System.out.print("("+S2[i].getX()+","+S2[i].getY()+") ");
System.out.println();
/**
*求S1中點的最近對及其距離並列印輸出結果
*/
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((S1[i].getX()-S1[j].getX()),2)+Math.pow((S1[i].getY()-S1[j].getY()),2));
if(d<minDist1)
{
minDist1=d;
indexI1=i;
indexJ1=j;
}
}
}
System.out.println("The closest pair in S1 is: "+"("+S1[indexI1].getX()+","+S1[indexI1].getY()+")"+
"and("+S1[indexJ1].getX()+","+S1[indexJ1].getY()+")"+",and the distance is "+minDist1);
/**
*求S2中點的最近對及其距離並列印輸出結果
*/
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((S2[i].getX()-S2[j].getX()),2)+Math.pow((S2[i].getY()-S2[j].getY()),2));
if(d<minDist2)
{
minDist2=d;
indexI2=i;
indexJ2=j;
}
}
}
System.out.println("The closest pair in S2 is: "+"("+S2[indexI2].getX()+","+S2[indexI2].getY()+")"+
"and("+S2[indexJ2].getX()+","+S2[indexJ2].getY()+")"+",and the distance is "+minDist2);
double d1=Math.min(minDist1,minDist2);
/**
*求出S1和S2中點的橫座標離小於d1的所有點分別存在P1[]和P2[]中
*/
ArrayList<Point> pp1=new ArrayList<Point>();
ArrayList<Point> pp2=new ArrayList<Point>();
for(int i=0;i<S1.length;i++)
{
if((mid-S1[i].getX())<d1)
pp1.add(S1[i]);
}
for(int i=0;i<S2.length;i++)
{
if((S2[i].getX()-mid)<d1)
pp2.add(S2[i]);
}
Point[] P1=new Point[pp1.size()];
Point[] P2=new Point[pp2.size()];
pp1.toArray(P1);
pp2.toArray(P2);
/**
*將P1和P2中的點按Y座標升序排列
*/
sortY(P1);
sortY(P2);
/**
*求解P1和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(P1[i].getY()-P2[j].getY())<d1)
{
double temp=Math.sqrt(Math.pow((P1[i].getX()-P2[j].getX()),2)+Math.pow((P1[i].getX()-P2[j].getX()),2));
if(temp<d2)
d2=temp;
}
}
}
double endTime=System.currentTimeMillis();//endtime
/**
*列印輸出最後求出的結果,最近的是哪兩個點,以及最近距離和程式用的時間
*/
System.out.print("The points in P1 are:");
for(int i=0;i<P1.length;i++)
System.out.print("("+P1[i].getX()+","+P1[i].getY()+") ");
System.out.println();
System.out.print("The points in P2 are:");
for(int i=0;i<P2.length;i++)
System.out.print("("+P2[i].getX()+","+P2[i].getY()+") ");
System.out.println();
System.out.println("d2="+d2);