-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathshortest_distance.cpp
More file actions
126 lines (106 loc) · 2.88 KB
/
Copy pathshortest_distance.cpp
File metadata and controls
126 lines (106 loc) · 2.88 KB
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// Marta Dziêgielewska
// Shortest distance between two points
// 14.01.2020
#include <iostream>
#include <math.h>
#include <cfloat>
#include <cstdlib>
#include <ctime>
#include <vector>
using namespace std;
class Point {
public: int x, y;
};
int compareX(const void* a, const void* b) {
Point *p1 = (Point *)a;
Point *p2 = (Point *)b;
return (p1->x - p2->x);
}
int compareY(const void* a, const void* b) {
Point *p1 = (Point *)a;
Point *p2 = (Point *)b;
return (p1->y - p2->y);
}
float distance(Point p1, Point p2) {
return sqrt((p1.x - p2.x)*(p1.x - p2.x) + (p1.y - p2.y)*(p1.y - p2.y));
}
// the shortest distance in P[] n x n
float brute_force(Point P[], int n) {
float min = 9999;
for (int i=0; i<n; ++i) {
for (int j=i+1; j<n; ++j) {
if (distance(P[i], P[j]) < min) {
min = distance(P[i], P[j]);
}
}
}
return min;
}
// distance between the closes points on the strip
float strip_closest(Point strip[], int size, float d) {
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 (distance(strip[i], strip[j]) < min) {
min = distance(strip[i], strip[j]);
}
}
}
return min;
}
// finding smallest distance in P[] sorted according to x coordinate
float closest_util(Point PX[], Point PY[], int n) {
if (n <= 3)
return brute_force(PX, n);
int mid = n/2;
Point middle_point = PX[mid];
// separating the points
// assuming all x coordinates are distinct
// sorted points on the left
Point PY_L[mid];
// sorted points on the right
Point PY_R[n-mid];
int li = 0, ri = 0;
for (int i=0; i<n; i++) {
if (PY[i].x < middle_point.x)
PY_L[li++] = PY[i];
else
PY_R[ri++] = PY[i];
}
float distance_left = closest_util(PX, PY_L, mid);
float distance_right = closest_util(PX+mid, PY_R, n-mid);
float d = min(distance_left, distance_right);
// array of points close to the like passing through the middle point
Point strip[n];
int j=0;
for (int i=0; i<n; i++) {
if (abs(PY[i].x - middle_point.x) < d) {
strip[j] = PY[i];
j++;
}
}
return min(d, strip_closest(strip, j, d));
}
float closest(std::vector<Point> P, int n) {
// PX and PY are sorted
Point PX[n];
Point PY[n];
for (int i=0; i<n; i++) {
PX[i] = P[i];
PY[i] = P[i];
}
qsort(PX, n, sizeof(Point), compareX);
qsort(PY, n, sizeof(Point), compareY);
// recursion to find the smallest distance
return closest_util(PX, PY, n);
}
int main()
{
std::vector<Point> P;
for(int i=0 ; i<100 ; i++) {
P.push_back({rand()/100, rand()/100});
}
int n =P.size();
cout << "The shortest distance: " << closest(P, n-1);
return 0;
}