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