Skip to content

Added 22_07 Exercise Solution. Cleaned up. #35

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions ch_03/Exercise03_09.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
package ch_03;

import javafx.scene.transform.Scale;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;

/**
Expand Down
27 changes: 27 additions & 0 deletions ch_22/exercise22_07/CompareY.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package ch_22.exercise22_07;

import java.util.Comparator;

public class CompareY implements Comparator<Point> {
@Override
public int compare(Point p1, Point p2) {
int resultY;
if (p1.y < p2.y) {
resultY = -1;
} else if (p1.y > p2.y) {
resultY = 1;
} else {
resultY = 0;
}
if (resultY == 0) {
if (p1.x < p2.x) {
return -1;
}
if (p1.x > p2.x) {
return 1;
}
return 0;
}
return resultY;
}
}
163 changes: 163 additions & 0 deletions ch_22/exercise22_07/Exercise22_07.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
package ch_22.exercise22_07;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;

/**
* *22.7 (Closest pair of points) Section 22.8 introduced an algorithm for finding the
* closest pair of points using a divide-and-conquer approach.
* <p>
* Implement the algorithm to meet the following requirements:
* ■ Define the classes Point and CompareY in the same way as in Programming Exercise 20.4.
* ■ Define a class named Pair with the data fields p1 and p2 to represent two
* points, and a method named getDistance() that returns the distance
* between the two points.
* </p>
* ---------------------------------------------------------------------- <br>
* ■ Implement the following methods:
* /** Return the distance of the closest pair of points *
* public static Pair getClosestPair(double[][] points)
* ---------------------------------------------------------------------- <br>
* /** Return the distance of the closest pair of points
* public static Pair getClosestPair(Point[] points)
* ---------------------------------------------------------------------- <br>
* /** Return the distance of the closest pair of points
* in pointsOrderedOnX[low..high]. This is a recursive
* method. pointsOrderedOnX and pointsOrderedOnY are
* not changed in the subsequent recursive calls. *
* public static Pair distance(Point[] pointsOrderedOnX, int low, int high, Point[] pointsOrderedOnY)
* *************************************************************************************************
* <p>
* From Section 22.8:
* LISTING 22.8 Algorithm for Finding the Closest Pair
* Step 1: Sort the points in increasing order of x-coordinates. For the
* points with the same x-coordinates, sort on y-coordinates. This results
* in a sorted list S of points.
* Step 2: Divide S into two subsets, S1 and S2, of equal size using the
* midpoint in the sorted list. Let the midpoint be in S1. Recursively find
* the closest pair in S1 and S2. Let d1 and d2 denote the distance of the
* closest pairs in the two subsets, respectively.
* Step 3: Find the closest pair between a point in S1 and a point in S2 and
* denote their distance as d3
* </p>
*/
public class Exercise22_07 {
private static Point[] S = new Point[]{new Point(65.72438591548975, 167.6922117473909),
new Point(182.85174298311438, 575.9888358534622),
new Point(240.22902231427315, 175.37793004083213),
new Point(317.5674265676426, 278.78240371327325),
new Point(356.00061370323124, 337.3921411106672),
new Point(302.54686547351093, 59.079345054498475),
new Point(163.48579149126033, 749.1901740238649),
new Point(277.76518877799515, 420.1256294206885),
new Point(108.51033510595356, 21.982331832110937),
new Point(108.5270214151543, 160.55324389043895),
};

public static void main(String[] args) {
Pair closestPair = getClosestPair(S);
System.out.println("Closest Pair is: ");
System.out.println(closestPair.toString());

}

/**
* Return the distance of the closest pair of points
*/
public static Pair getClosestPair(double[][] points) {
/* Convert to Point[] */
Point[] pts = new Point[points.length];
int idx = 0;
for (double[] pt : points) {
pts[idx] = new Point(pt[0], pt[1]);
idx++;
}
/* Use Point[] method to share common logic */
return getClosestPair(pts);
}

/**
* Return the distance of the closest pair of points
*/
public static Pair getClosestPair(Point[] pointsOrderedOnX) {
/* Sort Points by X first order, see Point.java */
Arrays.sort(pointsOrderedOnX);
/* Create deep copy of pointsOrderedOnX array */
Point[] pointsOrderedOnY = pointsOrderedOnX.clone();
/* Sort pointsOrderedOnY by Y first order, see CompareY.java*/
Arrays.sort(pointsOrderedOnY, new CompareY());
/* Start recursion at low = startIndex, and high = endIndex */
return distance(pointsOrderedOnX, 0, pointsOrderedOnX.length - 1, pointsOrderedOnY);

}

/**
* Return the distance of the closest pair of points
* in pointsOrderedOnX[low..high]. This is a recursive
* method. pointsOrderedOnX and pointsOrderedOnY are
* not changed in the subsequent recursive calls.
*/
public static Pair distance(Point[] pointsOrderedOnX,
int low, int high, Point[] pointsOrderedOnY) {
if (low >= high) {/* Recursive stopping condition */
return null;
} else if (low + 1 == high) { /* Only 2 Points possible to pair: pointsOrderedOnX[low], pointsOrderedOnX[high] */
return new Pair(pointsOrderedOnX[low], pointsOrderedOnX[high]);
} else {
/* Divide and Conquer */
int mid = (low + high) / 2;
/* Split sorted in half into S1 and S2, let d1 and d2 denote the distance of the closest pair in each subset */
Pair S1 = distance(pointsOrderedOnX, low, mid, pointsOrderedOnY); //d1
Pair S2 = distance(pointsOrderedOnX, mid + 1, high, pointsOrderedOnY); // d2
/* Find minDistance = min(d1,d2) distance */
double d = 0;
Pair p = null;
if (S1 != null && S2 != null) {
double leftPairDistance = S1.getDistance();
double rightPairDistance = S1.getDistance();
d = Math.min(leftPairDistance, rightPairDistance);
p = leftPairDistance == d ? S1 : S2;
} else if (S1 != null) {
d = S1.getDistance();
p = S1;
} else if (S2 != null) {
d = S2.getDistance();
p = S2;
}

List<Point> stripL = new ArrayList<>();
List<Point> stripR = new ArrayList<>();
/* Obtain stripL and stripR */
for (Point point : pointsOrderedOnY) {
/* if (p is in S1 and mid.x – p.x <= d) */
if (point.getX() <= pointsOrderedOnX[mid].getX() && pointsOrderedOnX[mid].getX() - point.getX() <= d) {
stripL.add(point);
/* else if (p is in S2 and p.x - mid.x <= d) */
} else if (point.getX() > pointsOrderedOnX[mid].getX() && point.getX() - pointsOrderedOnX[mid].getX() <= d) {
stripR.add(point);
}
}

int r = 0; // The index of the point in stripE
for (Point point : stripL) {
// Skip the points in stripR below p.y - d
while (r < stripR.size() && stripR.get(r).getY() <= point.getY() - d) {
r++;
}
int r1 = r;
while (r1 < stripR.size() && Math.abs(stripR.get(r1).getY() - point.getY()) <= d) {
/* Check if (p, q[r1]) is a possible closest pair */
if (new Pair(point, stripR.get(r1)).getDistance() < d) {
d = new Pair(point, stripR.get(r1)).getDistance();
p.setP1(point);
p.setP2(stripR.get(r1));
}
r1++;
}
}
return p;
}
}
}
48 changes: 48 additions & 0 deletions ch_22/exercise22_07/Pair.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package ch_22.exercise22_07;

/**
* ■ Define a class named Pair with the data fields p1 and p2 to represent two
* points, and a method named getDistance() that returns the distance
* between the two points.
*/
public class Pair {
private Point p1;
private Point p2;

public Pair(){}

public Pair(Point p1, Point p2) {
this.p1 = p1;
this.p2 = p2;
}

double getDistance() {
if (p1 == null || p2 == null) throw new IllegalArgumentException("Pair must have 2 non-null points defined....");
return Math.sqrt(Math.pow((p2.x - p1.x), 2) + Math.pow((p2.y - p1.y), 2));
}

public Point getP1() {
return p1;
}

public void setP1(Point p1) {
this.p1 = p1;
}

public Point getP2() {
return p2;
}

public void setP2(Point p2) {
this.p2 = p2;
}


@Override
public String toString() {
return "Pair{" +
"p1=" + p1 +
", p2=" + p2 +
'}';
}
}
67 changes: 67 additions & 0 deletions ch_22/exercise22_07/Point.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package ch_22.exercise22_07;

/**
* ■ Define a class named Point with two data fields x and y to represent a
* * point’s x- and y-coordinates.
* Implement the Comparable interface for comparing the points on x-coordinates.
* If two points have the same x-coordinates, compare their y-coordinates.
*/
public class Point implements Comparable<Point> {
double x;
double y;

public Point(double x, double y) {
this.x = x;
this.y = y;
}

public double getX() {
return x;
}

public Point setX(double x) {
this.x = x;
return this;
}

public double getY() {
return y;
}

public Point setY(double y) {
this.y = y;
return this;
}


@Override
public String toString() {
return "Point{" +
"x=" + x +
", y=" + y +
"}\n";
}

@Override
public int compareTo(Point that) {
if (this.x == that.x) {
if (this.y < that.y) {
return -1;
}
if (this.y > that.y) {
return 1;
}
return 0; // this.y == that.y

} else {
if (this.x < that.x) {
return -1;
}
if (this.x > that.x) {
return 1;
}
return 0;//this.x == that.x

}
}
}
11 changes: 11 additions & 0 deletions ch_22/package-info.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* <p>
* Chapter Twenty-Two:
* -------- Developing Efficient Algorithms --------
* Solutions for
* "Introduction to Java Programming" by Daniel Liang 10th Edition
* </p>
*
* @author Harry Dulaney
*/
package ch_22;
11 changes: 11 additions & 0 deletions ch_23/package-info.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* <p>
* Chapter Twenty-Three:
* -------- Sorting --------
* Solutions for
* "Introduction to Java Programming" by Daniel Liang 10th Edition
* </p>
*
* @author Harry Dulaney
*/
package ch_23;
4 changes: 3 additions & 1 deletion ch_25/package-info.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
/**
* <p>
* Chapter Twenty-Five Solutions for
* Chapter Twenty-Five
* ------------ Binary Search Trees -------------
* Solutions for
* "Introduction to Java Programming" by Daniel Liang 10th Edition
* </p>
*
Expand Down