Problem Description:
Given n points in a two-dimensional plane, find the two nearest points in these points;
Ideas:
We find that if we want to compare all of the points 22, we need at least O (n^2), so our idea is that if we ask for the closest point to a point a, we need to narrow it down without comparing each point.
We need to use the Division method to solve;
First we need to define some variables:
Px: sorted by x-coordinate for points;
Py: Sort by y-coordinate for points;
Qx: The point of the left part is sorted by x-coordinate;
Qy: For partial points, sort by y-coordinate;
Rx: The points in the right part are sorted by x-coordinate;
Ry: The points in the right part are sorted by y-coordinate;
The exit of recursion is that if there are only three points, the distance is calculated directly 22, and the minimum distance is returned;
We can clearly see from the above: each time the problem is divided into two small problems, so T (n) = 2*t (N/2) +f (n);
F (n) is the consumption of problem separation and combination;
You need to calculate qx,qy,rx,ry when separating, so it costs O (n)
The minimum distance between Q and R regions has been calculated, and d = min (d1,d2) We need to calculate a point at Q, a point at the minimum distance of R, we need to do the following steps:
(1) for lines separating Q and R, widen D to the left and right, and the points falling in this area may be the minimum distance point pairs, recorded as S; O (n)
(2) We order s according to Y after the Sy, for each point in the SY only need to calculate with his x, Y coordinate the difference between the points within the 2*d (up to 15 points); O (n)
(3) Calculate the minimum distance of the S region and compare with D, whichever is smaller; O (1)
So f (n) = O (n)
T (n) = 2*t (N/2) + O (n) ===> t (n) = O (Nlogn)
Code:
Import java.util.ArrayList;
Import Java.util.Arrays;
Import Java.util.Comparator;
public class Test {public static void main (string[] args) {initializepoint ();
Point[]result = Closest_pair (P);
Dist = distance (result);
System.out.println ("distance from the nearest two points:");
print (result);
System.out.println ("Distance:" +dist);
} private static Double dist;
private static point[] P; private static comparator<point> Ycompar = new comparator<point> () {//comparator based on y-coordinate @Override public int C
Ompare (Point O1, point O2) {if (o1.y<o2.y) {return-1;
} else if (O1.Y>O2.Y) {return 1;
} return 0;
}
}; private static comparator<point> Xcompar = new comparator<point> () {//Comparator based on x-coordinate @Override public int
Compare (Point O1, point O2) {if (o1.x<o2.x) {return-1;
} else if (o1.x>o2.x) {return 1;
} return 0;
}
}; Initialize array of points/** * (0,0) * (5,8) * (9,5) * (10,20) * (100,100) * * private static void InitIalizepoint () {P = new point[5];
for (int. i=0;i<p.length;i++) {P[i] = new Point ();
} p[0].x = 10;
P[0].y = 20;
p[1].x = 0;
P[1].Y = 0;
p[2].x = 100;
P[2].Y = 100;
p[3].x = 5;
P[3].Y = 8;
p[4].x = 9;
P[4].Y = 5;
}//Main function public static point[] Closest_pair (point[] points) {point[] px = Points.clone ();
Arrays.sort (Px,xcompar);
point[] py = Points.clone ();
Arrays.sort (Py,ycompar);
Point[] result = Closest_pair_rec (px,py);
return result;
} public static point[] Closest_pair_rec (point[]px,point[]py) {point minfirstpoint = null;
Point minsecondpoint = null;
Double mindistance = 0;
if (px.length<=3) {//export double mindist = Double.max_value;
int mini = 0;
int Minj = 0; for (int i=0;i<px.length;i++) {for (int j=i+1;j<px.length;j++) {if (Mindist>distance (new point[]{px[i],px[j
]}) {mindist = distance (new Point[]{px[i],px[j]});
mini = i;
Minj = j; }}} return new PoinT[]{px[mini],px[minj]};
} point[] Q = arrays.copyofrange (px, 0, px.length/2+1);
point[] R = Arrays.copyofrange (px, px.length/2+1, px.length);
point[] Qx = Q.clone ();
Arrays.sort (Qx, Xcompar);
point[] Qy = Q.clone ();
Arrays.sort (Qy, Ycompar);
point[] Rx = R.clone ();
Arrays.sort (Rx, Xcompar);
Point[]ry = R.clone ();
Arrays.sort (Ry, Ycompar);
point[] Q = Closest_pair_rec (qx,qy);
Point[] r = Closest_pair_rec (Rx,ry);
Double qd = distance (q);
Double rd = distance (r);
Double delta = math.min (QD,RD);
if (DELTA==QD) {minfirstpoint = q[0];
Minsecondpoint = q[1];
} else{minfirstpoint = r[0];
Minsecondpoint = r[1];
} mindistance = Delta; int maxx = qx[qx.length-1].x;
Split Line//Find the segment with split line distance less than delta drop into s arraylist<point> Stmp = new arraylist<point> ();
for (int i=0;i<px.length;i++) {if (Math.Abs (Px[i].x-maxx) <delta) {Stmp.add (px[i]);
}} point[]s = Stmp.toarray (new point[0]); point[] Sy = S.clonE ();
Arrays.sort (Sy,ycompar);
Look for points within 15 points and compare distances to find the minimum distance points, each point to compare 8 points, so the complexity is O (8n) Double secondmindistance = Double.max_value;
Point tmpminfirst = null;
Point tmpminsecond = null;
for (int. i=0;i<sy.length;i++) {Point basep = Sy[i];
for (int. j=i+1;j<sy.length;j++) {Point compp = sy[j];
if ((Compp.y-basep.y < 2*delta) &&math.abs (compp.x-basep.x) <2*delta) {//If within 15 points, that is, the x and y coordinate differences are within the 2*delta
Double Tmpdis = distance (new point[]{basep,compp});
if (Secondmindistance>tmpdis) {secondmindistance = Tmpdis;
Tmpminsecond = COMPP;
Tmpminfirst = Basep;
}} else{break;
}}} if (Secondmindistance<mindistance) {return new Point[]{tmpminfirst,tmpminsecond};
} else{return new Point[]{minfirstpoint,minsecondpoint}; }} private static double distance (point[] q) {return Math.pow (Math.pow (q[0].x-q[1].x,2) +math.pow (q[0].y-q[1].y,2),
0.5); } private static void print (Point[]ps) {for (point P:ps) {System.out.println ("x=" +p.x+ ", y=" +p.y);
}}} class point{int x;
int y;
}