Java 对最近的一对点不给出相同的距离回答的暴力、征服和分割

Java 对最近的一对点不给出相同的距离回答的暴力、征服和分割,java,Java,我创建了一个程序,生成用户输入的点数对。然后,它通过暴力和分而治之的方法找到最近的一对点。bruteforce方法非常有效。另一方面,分而治之的方法给了我一个输出,但它几乎90%的时间都不同于蛮力距离。我似乎不明白为什么在我的代码中是这样。注意:函数中的一些注释来自我的老师。另外,我的老师给了我最近的一对函数以及rec\u cl\u对,我必须使用它们,但必须适应我的代码(它们大部分是伪代码) 我的代码是: import java.util.*; import static java.lang.M

我创建了一个程序,生成用户输入的点数对。然后,它通过暴力和分而治之的方法找到最近的一对点。bruteforce方法非常有效。另一方面,分而治之的方法给了我一个输出,但它几乎90%的时间都不同于蛮力距离。我似乎不明白为什么在我的代码中是这样。注意:函数中的一些注释来自我的老师。另外,我的老师给了我
最近的一对
函数以及
rec\u cl\u对
,我必须使用它们,但必须适应我的代码(它们大部分是伪代码)

我的代码是:

import java.util.*;
import static java.lang.Math.min;

public class ClosestPair{

 private Double x;
 private Double y;

 private static Double minDist = Double.POSITIVE_INFINITY;

 private static ClosestPair closestPair1 = new ClosestPair(0.0,0.0);
 private static ClosestPair closestPair2 = new ClosestPair(0.0,0.0);

 public ClosestPair(Double x, Double y){

     this.x = x;
     this.y = y;
 }

 public static void main(String[] args) {

     Double rangeMin = 0.0;
     Double rangeMax = 1000.0;

     Random r = new Random();
     Scanner scan = new Scanner(System.in);

     System.out.print("\nEnter the number of two dimensional arrays: ");
     int dim = scan.nextInt();

     ClosestPair[] pair = new ClosestPair[dim];
     ClosestPair[] pairCopy = new ClosestPair[dim];

     for(int i = 0; i < dim; i++){

         Double xVal = rangeMin + (rangeMax - rangeMin) * r.nextDouble();
         Double yVal = rangeMin + (rangeMax - rangeMin) * r.nextDouble();

         pair[i] = new ClosestPair(xVal,yVal);
         //System.out.print(pair[i].x + ", " + pair[i].y + "\n");
     }

    /*
    for(int j = 0; j < pair.length; j++){
        System.out.print(pair[j].x + ", " + pair[j].y + "\n");
    }
    */

    pairCopy = pair;
    pair = mergeSort(pair);

    /*
    System.out.print("\n\n\n");

    for(int j = 0; j < pair.length; j++){
        System.out.print(pair[j].x + ", " + pair[j].y + "\n");
    }
    */ 

    //BRUTE FORCE PRINT STATEMENTS
    long startTime = System.nanoTime();
    bruteForce(pair);
    long endTime = System.nanoTime();
    long timeSpent = endTime - startTime;

    System.out.print("\nMin Distance = " + minDist);
    System.out.print("\n(x1,y1) = " + closestPair1.x + ", " + closestPair1.y);
    System.out.print("\n(x2,y2) = " + closestPair2.x + ", " + closestPair2.y);
    System.out.print("\nTime: " + timeSpent + "\n\n");

    minDist = 0.0;

    //CONQUER DIVIDE PRINT STATEMENTS
    startTime = System.nanoTime();
    minDist = closest_pair(pairCopy);
    endTime = System.nanoTime();
    timeSpent = endTime - startTime;

    System.out.print("Min Distance = " + minDist);
    System.out.print("\nTime: " + timeSpent);

    scan.close();
 }

 private static void bruteForce(ClosestPair[] pair) {

     for(int i = 1; i < pair.length - 1; i++){

         for(int j = i + 1; j < pair.length; j++){

             ClosestPair p = new ClosestPair(pair[i].x,pair[i].y);
             //System.out.print("\np:" + pair[i].x + ", " + pair[i].y);

             ClosestPair q = new ClosestPair(pair[j].x,pair[j].y);
             //System.out.print("\nq: " + pair[j].x + ", " + pair[j].y);

             if(getDistance(p, q) < minDist){
                    minDist = getDistance(p, q);
                    closestPair1.x = p.x;
                    closestPair1.y = p.y;
                    closestPair2.x = q.x;
                    closestPair2.y = q.y;
             }           
         }
     }
 }

 private static Double getDistance(ClosestPair p1, ClosestPair p2) {

     double xdist = p2.x - p1.x;
     double ydist = p2.y - p1.y;
     return Math.hypot(xdist, ydist);

}

 static ClosestPair[] mergeSort(ClosestPair[] a) {
     if (a.length > 1) {
         int q = a.length/2;

         ClosestPair[] leftArray = Arrays.copyOfRange(a, 0, q);
         ClosestPair[] rightArray = Arrays.copyOfRange(a,q,a.length);

         mergeSort(leftArray);
         mergeSort(rightArray);

         a = merge(a,leftArray,rightArray);
     }
    return a;
 }

 static ClosestPair[] merge(ClosestPair[] a, ClosestPair[] l, ClosestPair[] r) {

     int totElem = l.length + r.length;
     //int[] a = new int[totElem];

     int i,li,ri;

     i = li = ri = 0;

     while ( i < totElem) {
         if ((li < l.length) && (ri<r.length)) {

             if (l[li].x < r[ri].x) {
                 a[i] = l[li];
                 i++;
                 li++;
             }
             else {
                 a[i] = r[ri];
                 i++;
                 ri++;
             }
         }
         else {
             if (li >= l.length) {
                 while (ri < r.length) {
                     a[i] = r[ri];
                     i++;
                     ri++;
                 }
             }
             if (ri >= r.length) {
                 while (li < l.length) {
                     a[i] = l[li];
                     li++;
                     i++;
                 }
             }
         }
     }
     return a;

 }

 //START OF CONQUER DIVIDE SECTOIN

 static double closest_pair(ClosestPair[] p){
     int n = p.length - 1;
     p = mergeSortDC(p, 0, n); // sort all  n  points by  x-coordinate
     return rec_cl_pair(p, 0, n);
 }

 static double rec_cl_pair(ClosestPair[] p, int i, int j){ // finds closest pair between points in  p[i..j]

     // assumes input is sorted by  x-coordinate
     // at termination, input is sorted by  y-coordinate
     // i is the left index of the subarray, j is the right index

     if (j - i < 3){             // at most  3  points in  p[i..j]
         p = mergeSortDC (p, i, j);    // sort  p[i..j]  by  y-coordinate
         double delta = getDistance(p[i], p[i+1]);
         if (j - i == 1) { // two points

             minDist = delta;
             return delta;
         }
         else{

              double min1 = min(getDistance(p[i+1], p[i+2]), getDistance(p[i], p[i+2]));
              minDist = min(delta,min1);
              return minDist;
         }
     }

     int m = (i + j)/2;
     double line = p[m].x;
     double deltaL = rec_cl_pair(p, i, m);   // p[i..m]  is sorted by y-coordinate
     double deltaR = rec_cl_pair(p, m+1, j); // p[m+1..j]  is sorted by y-coordinate
     double delta = min(deltaL, deltaR);
     p = mergeDC(p, i, m, j);  // p[i..j]  is now sorted by  y-coordinate

     // Of points in p[i..j], find points in vertical strip of width 2*delta,
     // centered at line (middle of x-values), and store in array v
     int t = 0;

     ClosestPair[] v = new ClosestPair[j+1];

     for(int k = i; k < j; k++){
         if ((p[k].x > line - delta) && (p[k].x < line + delta)){
             t = t + 1;
             v[t] = p[k];
         }
     }

     // Find closest pairs among points in array  v.  NOTE: Cool math shows
     // there are at most 8 points in the strip at distance < delta. Thus,
     // in the loops below, each point is compared to at most 7 other points.
     for(int k = 1;k < t-1; k++){

         for(int s = k+1; k < min(t,k+7); s++){ // inner loop iterates <= 7 times

             delta = min(delta, getDistance(v[k],v[s]));
             minDist = delta;
             return delta;
         }
     }
     return minDist;
 }

 private static ClosestPair[] mergeSortDC(ClosestPair[] p, int low, int high) {

     // check if low is smaller then high, if not then the array is sorted
     if (low < high) {
             // Get the index of the element which is in the middle
             int middle = low + (high - low) / 2;
             // Sort the left side of the array
             mergeSortDC(p, low, middle);
             // Sort the right side of the array
             mergeSortDC(p, middle + 1, high);
             // Combine them both
             p = mergeDC(p, low, middle, high);
     }
    return p;
 }

 private static ClosestPair[] mergeDC(ClosestPair[] p, int low, int middle, int high) {

     ClosestPair[] helper = new ClosestPair[p.length];

     // Copy both parts into the helper array
     for (int i = low; i <= high; i++) {
             helper[i] = p[i];
     }

     int i = low;
     int j = middle + 1;
     int k = low;
     // Copy the smallest values from either the left or the right side back
     // to the original array
     while (i <= middle && j <= high) {
             if (helper[i].x <= helper[j].x) {
                     p[k] = helper[i];
                     i++;
             } else {
                     p[k] = helper[j];
                     j++;
             }
             k++;
     }
     // Copy the rest of the left side of the array into the target array
     while (i <= middle) {
             p[k] = helper[i];
             k++;
             i++;
     }

     return p;
 }
}

第一个最小距离是bruteforce结果。第二个是分治结果

mergeDC在代码中不按y坐标排序(helper[i]。x mergeDC在代码中不按y坐标排序(helper[i]。x
Enter the number of two dimensional arrays: 50

Min Distance = 19.014027210555614
(x1,y1) = 76.99595098629398, 600.1657767818473
(x2,y2) = 87.04091889578226, 616.3098732403395
Time: 3852815

Min Distance = 29.457199999686082
Time: 414081