-
Notifications
You must be signed in to change notification settings - Fork 96
/
Copy pathclosestPair.cpp
111 lines (87 loc) · 2.87 KB
/
closestPair.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#include <iostream>
#include<cmath>
#include<algorithm>
using namespace std;
//defining the structure containing the points
struct point {
int x, y;
};
int sortby_X(point p1, point p2) {
//to sort according to x value
return (p1.x < p2.x);
}
int sorby_Y(point p1, point p2) {
//to sort according to y value
return (p1.y < p2.y);
}
float dist(point p1, point p2) {
//find distance between points
return sqrt(pow((p1.x - p2.x),2) + pow((p1.y - p2.y),2));
}
float min_distance(point pts[], int n) {
//find minimum distance between two points in a set
float min = 9999;//we take a max value for the min distance
for (int i = 0; i < n; ++i)
for (int j = i+1; j < n; ++j)
if (dist(pts[i], pts[j]) < min)
min = dist(pts[i], pts[j]);
return min;
}
float min(float a, float b) {
return (a < b)? a : b;
}
float strip_distance_closest(point strip[], int size, float d) {
//find closest distance of two points in a strip
float min = d;
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;
}
float findClosest(point sorted_in_x[], point ySorted[], int n){
if (n <= 3)
return min_distance(sorted_in_x, n);
int mid = n/2;
point midPoint = sorted_in_x[mid];
point sorted_Y_left[mid+1]; // y sorted points in the left side
point sorted_y_right[n-mid-1]; // y sorted points in the right side
int leftIndex = 0, rightIndex = 0;
for (int i = 0; i < n; i++) { //separate y sorted points to left and right
if (ySorted[i].x <= midPoint.x)
sorted_Y_left[leftIndex++] = ySorted[i];
else
sorted_y_right[rightIndex++] = ySorted[i];
}
float leftDist = findClosest(sorted_in_x, sorted_Y_left, mid);
float rightDist = findClosest(ySorted + mid, sorted_y_right, n-mid);
float dist = min(leftDist, rightDist);
point strip[n]; //hold points closer to the vertical line
int j = 0;
for (int i = 0; i < n; i++)
if (abs(ySorted[i].x - midPoint.x) <dist) {
strip[j] = ySorted[i];
j++;
}
return min(dist, strip_distance_closest(strip, j, dist)); //find minimum using dist and closest pair in strip
}
float closestPair(point pts[], int n) {
//find distance of closest pair in a set of points
point sorted_in_x[n];
point ySorted[n];
for (int i = 0; i < n; i++) {
sorted_in_x[i] = pts[i];
ySorted[i] = pts[i];
}
sort(sorted_in_x, sorted_in_x+n, sortby_X);
sort(ySorted, ySorted+n, sorby_Y);
return findClosest(sorted_in_x, ySorted, n);
}
//main function with the test cases
int main() {
//format of input of points
point P[] ={{0,1},{5,3},{8,-6},{5,-5}};
//
int n = sizeof(P)/sizeof(P[0]);
cout<< "The minimum distance is : " << closestPair(P, n);
}