Open In App

Closest Pair of Points in C

Last Updated : 07 Aug, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

The Closest Pair of Points problem is a classic problem in computational geometry. It involves finding the pair of points with the smallest distance between them in a given set of points on a plane. This problem has significant applications, such as in air-traffic control where it is important to monitor planes that come too close together.

In this article, we will learn how to solve this problem using the C programming language with a Divide and Conquer approach.

Example:

Consider a set of points in a 2D plane. The goal is to find the pair of points that have the minimum distance between them.

Input:
Point P[] = {{2, 3}, {12, 30}, {40, 50}, {5, 1}, {12, 10}, {3, 4}};

Output:
The smallest distance is 1.41421

Closest Pair of Points Using Divide and Conquer in C

To solve this problem, we first sort the points according to their x-coordinates. We then recursively divide the points into smaller subsets and solve for the closest pair in each subset. Finally, we merge the results to find the overall closest pair of points.

Approach:

  • Sort the input array according to x-coordinates.
  • Find the middle point in the sorted array and divide the array into two halves.
  • Recursively find the smallest distances in both subarrays. Let the distances be dl and dr. The minimum of dl and dr is d.
  • Build an array strip[] of points whose x-coordinates are within ddd distance from the middle line.
  • Sort the strip array according to y-coordinates.
  • Check for the smallest distance in strip[]. This step is O(n).
  • Finally, return the minimum of ddd and the smallest distance found in the strip.

C Program to Solve Closest Pair of Points using Divide and Conquer

Below is a C program that demonstrates how to solve the Closest Pair of Points problem using the Divide and Conquer technique.

C++
// C program to find the smallest distance from a given set of points using Divide and Conquer algorithm.

#include 
#include 
#include 
#include 

// A structure to represent a Point in 2D plane
struct Point
{
    int x, y;
};

// Needed to sort array of points according to X coordinate
int compareX(const void *a, const void *b)
{
    Point *p1 = (Point *)a, *p2 = (Point *)b;
    return (p1->x - p2->x);
}

// Needed to sort array of points according to Y coordinate
int compareY(const void *a, const void *b)
{
    Point *p1 = (Point *)a, *p2 = (Point *)b;
    return (p1->y - p2->y);
}

// A utility function to find the distance between two points
float dist(Point p1, Point p2)
{
    return sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));
}

// A Brute Force method to return the smallest distance between two points in P[] of size n
float bruteForce(Point P[], int n)
{
    float min = FLT_MAX;
    for (int i = 0; i < n; ++i)
        for (int j = i + 1; j < n; ++j)
            if (dist(P[i], P[j]) < min)
                min = dist(P[i], P[j]);
    return min;
}

// A utility function to find a minimum of two float values
float min(float x, float y)
{
    return (x < y) ? x : y;
}

// A utility function to find the distance between the closest points of strip of a given size.
// All points in strip[] are sorted according to y coordinate.
// They all have an upper bound on minimum distance as d.
// Note that this method seems to be a O(n^2) method, but it's a O(n) method as the inner loop runs at most 6
// times
float stripClosest(Point strip[], int size, float d)
{
    // Initialize the minimum distance as d
    float min = d;

    qsort(strip, size, sizeof(Point), compareY);

    // Pick all points one by one and try the next points till the difference
    // between y coordinates is smaller than d.
    // This is a proven fact that this loop runs at most 6 times
    for (int i = 0; i < size; ++i)
        for (int j = i + 1; j < size && (strip[j].y - strip[i].y) < min; ++j)
            if (dist(strip[i], strip[j]) < min)
                min = dist(strip[i], strip[j]);

    return min;
}

// A recursive function to find the smallest distance. The array P contains all points sorted according to x
// coordinate
float closestUtil(Point P[], int n)
{
    // If there are 2 or 3 points, then use brute force
    if (n <= 3)
        return bruteForce(P, n);

    // Find the middle point
    int mid = n / 2;
    Point midPoint = P[mid];

    // Consider the vertical line passing through the middle point
    // calculate the smallest distance dl on left of middle point and
    // dr on right side
    float dl = closestUtil(P, mid);
    float dr = closestUtil(P + mid, n - mid);

    // Find the smaller of two distances
    float d = min(dl, dr);

    // Build an array strip[] that contains points close (closer than d)
    // to the line passing through the middle point
    Point strip[n];
    int j = 0;
    for (int i = 0; i < n; i++)
        if (abs(P[i].x - midPoint.x) < d)
            strip[j] = P[i], j++;

    // Find the closest points in strip. Return the minimum of d and closest distance in strip[]
    return min(d, stripClosest(strip, j, d));
}

// The main function that finds the smallest distance
// This method mainly uses closestUtil()
float closest(Point P[], int n)
{
    qsort(P, n, sizeof(Point), compareX);

    // Use recursive function closestUtil() to find the smallest distance
    return closestUtil(P, n);
}

// Driver program to test above functions
int main()
{
    Point P[] = {{2, 3}, {12, 30}, {40, 50}, {5, 1}, {12, 10}, {3, 4}};
    int n = sizeof(P) / sizeof(P[0]);
    printf("The smallest distance is %f ", closest(P, n));
    return 0;
}

Output
The smallest distance is 1.414214 

Time Complexity: Let Time complexity of above algorithm be T(n). Let us assume that we use a O(nLogn) sorting algorithm. The above algorithm divides all points in two sets and recursively calls for two sets. After dividing, it finds the strip in O(n) time, sorts the strip in O(nLogn) time and finally finds the closest points in strip in O(n) time.

So T(n) can expressed as follows 

T(n) = 2T(n/2) + O(n) + O(nLogn) + O(n) 
T(n) = 2T(n/2) + O(nLogn) 
T(n) = T(n x Logn x Logn)

Auxiliary Space: O(log n)


Next Article
Article Tags :

Similar Reads