Skip to content

Randomized closest 2 points algorithm #6251

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

Open
wants to merge 23 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
82fb1f5
closest pair program
bri-harris May 29, 2025
f1391bd
closest pair program
bri-harris May 30, 2025
63ddb36
As required for PRs, formatted with clang-format
bri-harris May 30, 2025
21fed7d
As required for PRs, URL of algorithm solution included in a comment
bri-harris May 30, 2025
b4c88a7
Fixed build errors
bri-harris May 30, 2025
d7949d6
Private constructor to prevent instanciation
bri-harris May 30, 2025
a7c2163
Fix bigDecimal erroref
bri-harris May 30, 2025
852c2e7
fix infer issue?
bri-harris May 30, 2025
f854cf7
Update .inferconfig
bri-harris May 30, 2025
b18bce9
Update infer.yml
bri-harris May 30, 2025
d1f7ec5
Trying to syncronise dependancies
bri-harris May 30, 2025
f49710a
fix: Remove pyml pin to resolve dependency conflict with Infer
DenizAltunkapan Jun 2, 2025
94c5ad4
Use a true randomized algorithm solution, Rabin's randomized
bri-harris Jun 3, 2025
b5c62ab
fix test case for identical points
bri-harris Jun 3, 2025
e89e6c4
used clang formatter on necessary file
bri-harris Jun 3, 2025
c93383b
fix build issues
bri-harris Jun 3, 2025
0e32962
rebase and fix build issues
bri-harris Jun 3, 2025
cac9706
remove * from import statments
bri-harris Jun 3, 2025
e05cfdd
no public or default constructors allowed
bri-harris Jun 3, 2025
c386ec9
closest pair class must be final
bri-harris Jun 3, 2025
bb66f17
not null error from workflow fixed
bri-harris Jun 3, 2025
92ff833
add null checker in algorithm
bri-harris Jun 3, 2025
20d0d31
add null checker in test and more distinct in rabin function
bri-harris Jun 3, 2025
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
Next Next commit
closest pair program
  • Loading branch information
bri-harris committed Jun 3, 2025
commit 82fb1f55e11416deb0e6b8d26d8dd7915c5e1710
87 changes: 87 additions & 0 deletions src/main/java/com/thealgorithms/randomized/ClosestPair.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package com.thealgorithms.randomized;
import java.util.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
/**
* This class implements the randomized Closest Pair Algorithm; given some number of points
* in a plane find the pair with minimum euclidean distance from each other. This solution
* uses the divide and conquer approach.
* @author Bri Harris
*/

import java.util.*;

class Point implements Comparable<Point> {
double x, y;

// Constructor to initialize a point with x and y coordinates
Point(double x, double y) {
this.x = x;
this.y = y;
}

// Compare points based on x-coordinates (for sorting)
public int compareTo(Point other) {
return Double.compare(this.x, other.x);
}

// Compute Euclidean distance between two points
static double distance(Point p1, Point p2) {
return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2));
}
}

public class ClosestPair {
public static double closest(List<Point> points) {
Collections.sort(points);
double result = closestRecursiveHelper(points, 0, points.size() - 1);

//Return distance of closest pair rounded to 2 decimal places
return new BigDecimal(result).setScale(2, RoundingMode.HALF_UP).doubleValue();
}

private static double closestRecursiveHelper(List<Point> points, int left, int right) {
//Base Case occurs with 3 or fewer points
if (right - left <= 2) return baseCase(points, left, right);


//Divide and conquer
int mid = (left + right) / 2;
double midX = points.get(mid).x;

double leftDist = closestRecursiveHelper(points, left, mid);
double rightDist = closestRecursiveHelper(points, mid + 1, right);

double minDist = Math.min(leftDist, rightDist);

return checkBoundary(points, left, right, midX, minDist);
}

private static double baseCase(List<Point> points, int left, int right) {
// Sub-problems fitting the base case can use brute force
double minDist = Double.MAX_VALUE;
for (int i = left; i <= right; i++) {
for (int j = i + 1; j <= right; j++) {
minDist = Math.min(minDist, Point.distance(points.get(i), points.get(j)));
}
}
return minDist;
}

private static double checkBoundary(List<Point> points, int left, int right, double midX, double minDist) {
//Consider a boundary by the dividing line
List<Point> boundary = new ArrayList<>();
for (int i = left; i <= right; i++) {
if (Math.abs(points.get(i).x - midX) < minDist) boundary.add(points.get(i));
}

//sort by y coordinate within the boundary and check for closer points
boundary.sort(Comparator.comparingDouble(p -> p.y));
for (int i = 0; i < boundary.size(); i++) {
for (int j = i + 1; j < boundary.size() && (boundary.get(j).y - boundary.get(i).y) < minDist; j++) {
minDist = Math.min(minDist, Point.distance(boundary.get(i), boundary.get(j)));
}
}
return minDist;
}
}