Skip to content

Commit 88f8155

Browse files
committed
Refactorized ClosestPair.java in order to be compliant with java sun rules
commit divideconquer\ClosesPair.java Refactorized ClosestPair.java. Finding nearest cartesian points. Refactorized ClosestPair.java. Finding nearest cartesian points.
1 parent 826e7b5 commit 88f8155

File tree

1 file changed

+348
-0
lines changed

1 file changed

+348
-0
lines changed

divideconquer/ClosestPair.java

+348
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,348 @@
1+
package divideconquer;
2+
3+
/**
4+
5+
* For a set of points in a coordinates system (10000 maximum),
6+
* ClosestPair class calculates the two closest points.
7+
8+
* @author: anonymous
9+
* @author: Marisa Afuera
10+
*/
11+
12+
public final class ClosestPair {
13+
14+
15+
/** Number of points */
16+
int numberPoints = 0;
17+
/** Input data, maximum 10000. */
18+
private Location[] array;
19+
/** Minimum point coordinate. */
20+
Location point1 = null;
21+
/** Minimum point coordinate. */
22+
Location point2 = null;
23+
/** Minimum point length. */
24+
private static double minNum = Double.MAX_VALUE;
25+
/** secondCount */
26+
private static int secondCount = 0;
27+
28+
/**
29+
* Constructor.
30+
*/
31+
ClosestPair(int points) {
32+
numberPoints = points;
33+
array = new Location[numberPoints];
34+
}
35+
36+
/**
37+
Location class is an auxiliary type to keep points coordinates.
38+
*/
39+
40+
public static class Location {
41+
42+
double x = 0;
43+
double y = 0;
44+
45+
/**
46+
* @param xpar (IN Parameter) x coordinate <br/>
47+
* @param ypar (IN Parameter) y coordinate <br/>
48+
*/
49+
50+
Location(final double xpar, final double ypar) { //Save x, y coordinates
51+
this.x = xpar;
52+
this.y = ypar;
53+
}
54+
55+
}
56+
57+
public Location[] createLocation(int numberValues) {
58+
return new Location[numberValues];
59+
60+
}
61+
62+
public Location buildLocation(double x, double y){
63+
return new Location(x,y);
64+
}
65+
66+
67+
/** xPartition function: arrange x-axis.
68+
* @param a (IN Parameter) array of points <br/>
69+
* @param first (IN Parameter) first point <br/>
70+
* @param last (IN Parameter) last point <br/>
71+
* @return pivot index
72+
*/
73+
74+
public int xPartition(
75+
final Location[] a, final int first, final int last) {
76+
77+
Location pivot = a[last]; // pivot
78+
int pIndex = last;
79+
int i = first - 1;
80+
Location temp; // Temporarily store value for position transformation
81+
for (int j = first; j <= last - 1; j++) {
82+
if (a[j].x <= pivot.x) { // Less than or less than pivot
83+
i++;
84+
temp = a[i]; // array[i] <-> array[j]
85+
a[i] = a[j];
86+
a[j] = temp;
87+
}
88+
}
89+
i++;
90+
temp = a[i]; // array[pivot] <-> array[i]
91+
a[i] = a[pIndex];
92+
a[pIndex] = temp;
93+
return i; // pivot index
94+
}
95+
96+
/** yPartition function: arrange y-axis.
97+
* @param a (IN Parameter) array of points <br/>
98+
* @param first (IN Parameter) first point <br/>
99+
* @param last (IN Parameter) last point <br/>
100+
* @return pivot index
101+
*/
102+
103+
public int yPartition(
104+
final Location[] a, final int first, final int last) {
105+
106+
Location pivot = a[last]; // pivot
107+
int pIndex = last;
108+
int i = first - 1;
109+
Location temp; // Temporarily store value for position transformation
110+
for (int j = first; j <= last - 1; j++) {
111+
if (a[j].y <= pivot.y) { // Less than or less than pivot
112+
i++;
113+
temp = a[i]; // array[i] <-> array[j]
114+
a[i] = a[j];
115+
a[j] = temp;
116+
}
117+
}
118+
i++;
119+
temp = a[i]; // array[pivot] <-> array[i]
120+
a[i] = a[pIndex];
121+
a[pIndex] = temp;
122+
return i; // pivot index
123+
}
124+
125+
/** xQuickSort function: //x-axis Quick Sorting.
126+
* @param a (IN Parameter) array of points <br/>
127+
* @param first (IN Parameter) first point <br/>
128+
* @param last (IN Parameter) last point <br/>
129+
*/
130+
131+
public void xQuickSort(
132+
final Location[] a, final int first, final int last) {
133+
134+
if (first < last) {
135+
int q = xPartition(a, first, last); // pivot
136+
xQuickSort(a, first, q - 1); // Left
137+
xQuickSort(a, q + 1, last); // Right
138+
}
139+
}
140+
141+
/** yQuickSort function: //y-axis Quick Sorting.
142+
* @param a (IN Parameter) array of points <br/>
143+
* @param first (IN Parameter) first point <br/>
144+
* @param last (IN Parameter) last point <br/>
145+
*/
146+
147+
public void yQuickSort(
148+
final Location[] a, final int first, final int last) {
149+
150+
if (first < last) {
151+
int q = yPartition(a, first, last); // pivot
152+
yQuickSort(a, first, q - 1); // Left
153+
yQuickSort(a, q + 1, last); // Right
154+
}
155+
}
156+
157+
/** closestPair function: find closest pair.
158+
* @param a (IN Parameter) array stored before divide <br/>
159+
* @param indexNum (IN Parameter) number coordinates divideArray <br/>
160+
* @return minimum distance <br/>
161+
*/
162+
163+
public double closestPair(final Location[] a, final int indexNum) {
164+
165+
Location[] divideArray = new Location[indexNum];
166+
System.arraycopy(a, 0, divideArray, 0, indexNum); // Copy previous array
167+
int totalNum = indexNum; // number of coordinates in the divideArray
168+
int divideX = indexNum / 2; // Intermediate value for divide
169+
Location[] leftArray = new Location[divideX]; //divide - left array
170+
//divide-right array
171+
Location[] rightArray = new Location[totalNum - divideX];
172+
if (indexNum <= 3) { // If the number of coordinates is 3 or less
173+
return bruteForce(divideArray);
174+
}
175+
//divide-left array
176+
System.arraycopy(divideArray, 0, leftArray, 0, divideX);
177+
//divide-right array
178+
System.arraycopy(
179+
divideArray, divideX, rightArray, 0, totalNum - divideX);
180+
181+
double minLeftArea = 0; //Minimum length of left array
182+
double minRightArea = 0; //Minimum length of right array
183+
double minValue = 0; //Minimum lengt
184+
185+
minLeftArea = closestPair(leftArray, divideX); // recursive closestPair
186+
minRightArea = closestPair(rightArray, totalNum - divideX);
187+
// window size (= minimum length)
188+
minValue = Math.min(minLeftArea, minRightArea);
189+
190+
// Create window. Set the size for creating a window
191+
// and creating a new array for the coordinates in the window
192+
for (int i = 0; i < totalNum; i++) {
193+
double xGap = Math.abs(divideArray[divideX].x - divideArray[i].x);
194+
if (xGap < minValue) {
195+
secondCount++; // size of the array
196+
} else {
197+
if (divideArray[i].x > divideArray[divideX].x) {
198+
break;
199+
}
200+
}
201+
}
202+
// new array for coordinates in window
203+
Location[] firstWindow = new Location[secondCount];
204+
int k = 0;
205+
for (int i = 0; i < totalNum; i++) {
206+
double xGap = Math.abs(divideArray[divideX].x - divideArray[i].x);
207+
if (xGap < minValue) { // if it's inside a window
208+
firstWindow[k] = divideArray[i]; // put in an array
209+
k++;
210+
} else {
211+
if (divideArray[i].x > divideArray[divideX].x) {
212+
break;
213+
}
214+
}
215+
}
216+
yQuickSort(firstWindow, 0, secondCount - 1); // Sort by y coordinates
217+
/* Coordinates in Window */
218+
double length = 0;
219+
// size comparison within window
220+
for (int i = 0; i < secondCount - 1; i++) {
221+
for (int j = (i + 1); j < secondCount; j++) {
222+
double xGap = Math.abs(firstWindow[i].x - firstWindow[j].x);
223+
double yGap = Math.abs(firstWindow[i].y - firstWindow[j].y);
224+
if (yGap < minValue) {
225+
length = Math.sqrt(Math.pow(xGap, 2) + Math.pow(yGap, 2));
226+
// If measured distance is less than current min distance
227+
if (length < minValue) {
228+
// Change minimum distance to current distance
229+
minValue = length;
230+
// Conditional for registering final coordinate
231+
if (length < minNum) {
232+
minNum = length;
233+
point1 = firstWindow[i];
234+
point2 = firstWindow[j];
235+
}
236+
}
237+
}
238+
else {
239+
break;
240+
}
241+
}
242+
}
243+
secondCount = 0;
244+
return minValue;
245+
}
246+
247+
/** bruteForce function: When the number of coordinates is less than 3.
248+
* @param arrayParam (IN Parameter) array stored before divide <br/>
249+
* @return <br/>
250+
*/
251+
252+
public double bruteForce(final Location[] arrayParam) {
253+
254+
double minValue = Double.MAX_VALUE; // minimum distance
255+
double length = 0;
256+
double xGap = 0; // Difference between x coordinates
257+
double yGap = 0; // Difference between y coordinates
258+
double result = 0;
259+
260+
if (arrayParam.length == 2) {
261+
// Difference between x coordinates
262+
xGap = (arrayParam[0].x - arrayParam[1].x);
263+
// Difference between y coordinates
264+
yGap = (arrayParam[0].y - arrayParam[1].y);
265+
// distance between coordinates
266+
length = Math.sqrt(Math.pow(xGap, 2) + Math.pow(yGap, 2));
267+
// Conditional statement for registering final coordinate
268+
if (length < minNum) {
269+
minNum = length;
270+
271+
}
272+
point1 = arrayParam[0];
273+
point2 = arrayParam[1];
274+
result = length;
275+
}
276+
if (arrayParam.length == 3) {
277+
for (int i = 0; i < arrayParam.length - 1; i++) {
278+
for (int j = (i + 1); j < arrayParam.length; j++) {
279+
// Difference between x coordinates
280+
xGap = (arrayParam[i].x - arrayParam[j].x);
281+
// Difference between y coordinates
282+
yGap = (arrayParam[i].y - arrayParam[j].y);
283+
// distance between coordinates
284+
length =
285+
Math.sqrt(Math.pow(xGap, 2) + Math.pow(yGap, 2));
286+
// If measured distance is less than current min distance
287+
if (length < minValue) {
288+
// Change minimum distance to current distance
289+
minValue = length;
290+
if (length < minNum) {
291+
// Registering final coordinate
292+
minNum = length;
293+
point1 = arrayParam[i];
294+
point2 = arrayParam[j];
295+
}
296+
}
297+
}
298+
}
299+
result = minValue;
300+
301+
}
302+
return result; // If only one point returns 0.
303+
}
304+
305+
/** main function: execute class.
306+
* @param args (IN Parameter) <br/>
307+
* @throws IOException If an input or output
308+
* exception occurred
309+
*/
310+
311+
public static void main(final String[] args) {
312+
313+
//Input data consists of one x-coordinate and one y-coordinate
314+
315+
ClosestPair cp = new ClosestPair(12);
316+
cp.array[0]=cp.buildLocation(2,3);
317+
cp.array[1]=cp.buildLocation(2,16);
318+
cp.array[2]=cp.buildLocation(3,9);
319+
cp.array[3]=cp.buildLocation(6,3);
320+
cp.array[4]=cp.buildLocation(7,7);
321+
cp.array[5]=cp.buildLocation(19,4);
322+
cp.array[6]=cp.buildLocation(10,11);
323+
cp.array[7]=cp.buildLocation(15,2);
324+
cp.array[8]=cp.buildLocation(15,19);
325+
cp.array[9]=cp.buildLocation(16,11);
326+
cp.array[10]=cp.buildLocation(17,13);
327+
cp.array[11]=cp.buildLocation(9,12);
328+
329+
System.out.println("Input data");
330+
System.out.println("Number of points: "+ cp.array.length);
331+
for (int i=0;i<cp.array.length;i++){
332+
System.out.println("x: " + cp.array[i].x + ", y: " + cp.array[i].y);
333+
}
334+
335+
cp.xQuickSort(cp.array, 0, cp.array.length-1); // Sorting by x value
336+
337+
double result; // minimum distance
338+
339+
result = cp.closestPair(cp.array, cp.array.length);
340+
// ClosestPair start
341+
// minimum distance coordinates and distance output
342+
System.out.println("Output Data");
343+
System.out.println("(" + cp.point1.x + ", " + cp.point1.y + ")");
344+
System.out.println("(" + cp.point2.x + ", " + cp.point2.y + ")");
345+
System.out.println("Minimum Distance : " + result);
346+
347+
}
348+
}

0 commit comments

Comments
 (0)