import java.util.ArrayList; import java.util.Scanner; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.util.StringTokenizer; import java.util.Collections; // Find closest pair of points in the Cartesian plane. public class Driver { //////////////////////////////////////////////////////////////////////// // Optional: Implement the function closestPairWrapper // You may want to have a separate wrapper function which is called // from main. The recursive function would be called from here, // and when the algorithm is done we return here, and then back to main. // First, construct P_x and P_y, which are the list of all points // sorted by x-coordinate and y-coordinate, respectively. ////////////////////////////////////////////////////////////////////////////// // Implement the recursive function closestPair(). which takes as parameters // Given a list of points, we return a pair of points that is closest // to each other. // If P is the list, should sort by x and by y coordinate, to obtain px and py. // You could do it here at the beginning of this function, or in some // place before this function gets called and then you would be passing // both px and py to this function, instead of passing 1 list. // Note: px and py are the same set of points, just sorted differently. // Base cases: // If the sizes of px/py don't match, give up! // If the sizes are smaller than 2, just return null. // If size is 2 or 3, just return smallest pair by inspection. // Construct Q_x, Q_y, R_x, R_y. // Q is all points on the left half, and R is all points on the right. // Q and R sets will both be sorted by x and y coordinates, hence 4 lists total. // If the original P list has an odd number of points, then let Q be the // "larger" half. // Note that we already have sorted lists px and py, so this is not hard. // Find the closest pairs in the Q and R sets. This is the divide & conquer. // If you are sorting the list of points at the beginning of this function, // then it's probably not necessary to sort Q and R here. // Which closest pair, Q or R, is the closer? // Find the rightmost x-coordinate of a point in Q (i.e. qx or qy). // This should be from the last element in qx. // L = the vertical line going thru the rightmost point in qx. // We don't need to define this in the program; it's just a concept. // S = points in P within delta x-distance of L. // In other words, here is how to construct S: // for each point in P, if its X coordinate is within delta of xStar, add it. // I'm going to call S "sy" because we just need it sorted by y coordinate. // sort sy by the y coordinate. // For each point s in sy, compute distance from s to each of the // next 15 points in sy (there may be fewer than 15!) // Let [s,s'] be the pair of points achieving the min of these dist // which can be done in O(n) time. // // By default, let's start with first 2 points in sy. // If we don't have even 2 points, we can't do this analysis, so the // closest pair is either from Q or R we found earlier. // If dist[s,s'] < delta, return [s,s'] // else return closer of the Q pair and R pair. //////////////////////////////////////////////////////////////////////// /** Find distance between 2 points. It's a real number. */ public static double findDist(Point p1, Point p2) { int x1 = p1.getX(); int y1 = p1.getY(); int x2 = p2.getX(); int y2 = p2.getY(); double deltaX = x2 - x1; double deltaY = y2 - y1; return Math.sqrt((double)(deltaX * deltaX + deltaY * deltaY)); } //////////////////////////////////////////////////////////////////////// public static void main(String [] args) throws FileNotFoundException { System.out.printf("What file contains list of points? "); Scanner kbd = new Scanner(System.in); String fileName = kbd.nextLine(); ArrayList list = new ArrayList(); // We can read in points from a file. Scanner in = new Scanner(new FileInputStream(fileName)); while(in.hasNextLine()) { String line = in.nextLine(); StringTokenizer tok = new StringTokenizer(line, ", "); int x = Integer.parseInt(tok.nextToken()); int y = Integer.parseInt(tok.nextToken()); list.add(new Point(x, y)); } System.out.printf("There are %d points in the input.\n", list.size()); // Call appropriate function(s) to compute closest pair, // and print it out. } }