1. 程式人生 > >蠻力法和分治法 求最近對問題——Java 實現

蠻力法和分治法 求最近對問題——Java 實現

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);