Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Closest distance between two points(disjoint set)

enter image description here

This problem is a kind of closest pair between two disjoint set. Upperside picture is expressed this problem. there is two kind of disjoint set, blue dots in -x plane, red dots in +x plane.

I want to calculate minimum distance(distance is |y2-y1| + |x2 - x1|) between one blue dot and one red dot, and I think use binary search for finding distance. How to use binary search this kind of problem? I struggle on only expressing binary search two disjoint sets. I have already know for one set, but I don't know in case two disjoint sets.

++ ) it is can in linear time using Delaunay triangulation? (ah, it is only my curiosity, I want to use binary search)

below code which I had already coding one set case(using problem-solving technique, divide and qonquer) and coverting to two disjoint set. I don't understand how to do in two sets. Example, Hint. okay.. please someone help me?

#include <iostream>
#include <algorithm>
#include <iomanip>
#include <cmath>

/**
test input
10
-16 -4 
-1 -3 
-9 -1 
-4 -10 
-11 -6 
-20 4 
-13 6 
-3 -10 
-19 -1 
-12 -4
10
8 2
10 3 
10 10 
20 -3 
20 3 
16 2
3 -5 
14 -10
8 -2 
14 0

10
-3 39
-2 -28
-1 20
-3 11
-3 45
-2 -44
-1 -47
-5 -35
-5 -19
-5 -45
10
27 5
28 0
28 5
21 5
2 3
13 -1
16 -2
20 -2
33 -3
27 1
 **/


using namespace std;

const int MAX = 10001;

struct point{
    int x,y;
};

bool xCompare(struct point, struct point);
bool yCompare(struct point, struct point);
int dis(struct point, struct point);

int absd(int);
int trace(int,int,int,int);

point p[MAX], q[MAX], tmp[MAX];

int main(){

    int left;
    int right;

    scanf("%d\n", &left);
    memset(p,0,sizeof(p));
    memset(q,0,sizeof(q));
    memset(tmp,0,sizeof(tmp));


    for(int i=0; i<left; i++){
        cin >> p[i].x >> p[i].y;
    }

    scanf("%d\n", &right);

    for(int j=0; j<right; j++){
        cin >> q[j].x >> q[j].y;
    }

    sort(p, p+left, xCompare);
    sort(q, q+right, xCompare);

    int min = trace(0,0, left-1, right-1);

    printf("%d\n", min);


    /** this is one set case.
    while(true){
        cin >> n;

        if(n == 0)  break;

        memset(p,0,sizeof(p));
        memset(tmp,0,sizeof(tmp));

        for(int i= 0;i<n;i++)
            cin >> p[i].x >> p[i].y;

        sort(p,p+n,xCompare);

        int min = trace(0,n-1);

        if(min < 10000 && n > 1){
            cout << fixed;
            cout << setprecision(4) << min << endl;
        }
        else
            cout << "INFINITY" << endl;
    }
     **/

    return 0;
}

int trace(int low1, int low2, int high1, int high2){

    if(high1 - low1 < 3){
        int value = dis(p[low1],q[low2+1]);
        int nextValue;

        if(high1 - low1 == 2){  
            nextValue = dis(p[low1],q[low2+2]);

            if(value > nextValue)
                value = nextValue;

            nextValue = dis(p[low1+1],q[low2+2]);

            if(value > nextValue)
                value = nextValue;
        }
        return value;
    }
    else{

        /* DIVIDE & QONQUER */

        int mid1 = (low1 + high1) >> 1;
        int mid2 = (low2 + high2) >> 1;
        int cnt = 0;

        int leftValue = trace(low1,low2,mid1,mid2);     // left trace
        int rightValue = trace(mid1+1,mid2+1,high1,high2);  // right trace

        // min value find
        int value = leftValue < rightValue ? leftValue : rightValue;

        /* Middle Condition Check : Y Line */

        // saving left
        for(int i = low1;i<=mid1;i++){
            if(abs(p[i].x - q[mid2].x) <= value)
                tmp[cnt++] = p[i];
        }

        // saving right
        for(int i = mid1+1;i<=high1;i++){
            if(absd(p[i].x - q[mid2+1].x) <= value)
                tmp[cnt++] = p[i];
        }

        sort(tmp,tmp+cnt,yCompare);

        for(int i = 0;i<cnt;i++){
            int count = 0;

            for(int j = i-3;count < 6 && j < cnt;j++){
                if(j >= 0 && i != j){
                    int distance = dis(tmp[i],tmp[j]);

                    if(value > distance)
                        value = distance;

                    count++;
                }
            }
        }
        return value;
    }
}

int absd(int x){
    if( x < 0)
        return -x;
    return x;
}

int dis(struct point a, struct point b){
    return (abs(a.x-b.x) + abs(a.y-b.y));
}

bool xCompare(struct point a, struct point b){
    return a.x < b.x;
}

bool yCompare(struct point a, struct point b){
    return a.y < b.y;
}
like image 958
Silvester Avatar asked Nov 20 '11 18:11

Silvester


People also ask

What is the complexity of closest pair problem by using divide and conquer?

The Brute force solution is O(n^2), compute the distance between each pair and return the smallest. We can calculate the smallest distance in O(nLogn) time using Divide and Conquer strategy.

What is the average case complexity of closest pair problem?

What is the runtime efficiency of using brute force technique for the closest pair problem? Explanation: The efficiency of closest pair algorithm by brute force technique is mathematically found to be O(N2).


2 Answers

This problem is usually called the closest bichromatic pair problem. Here are a couple approaches.

  1. Delaunay triangulation. (This certainly works with L2 (= Euclidean) distances; I think the steps generalize to L1.) For every Delaunay triangulation (there can be more than one in degenerate cases), there exists a minimum spanning tree whose edges all belong to the triangulation. In turn, this minimum spanning tree contains a shortest edge crossing the cut between the color classes.

  2. Nearest neighbor data structures.

  3. If it is given that the red points are separated in x from the blue points, then you may be able to adapt the O(n) merge step of the Shamos–Hoey divide-and-conquer algorithm for the closest (monochromatic) pair problem, described here.

like image 88
Per Avatar answered Oct 21 '22 19:10

Per


If you want to do binary search on spatial data, you could use a spatial data structure, such as a quadtree or a k-d tree.

like image 1
Sebastian Negraszus Avatar answered Oct 21 '22 19:10

Sebastian Negraszus