Skip to content

Commit 762482d

Browse files
harshildarjicclauss
authored andcommitted
Update closest_pair_of_points.py (TheAlgorithms#1109)
1 parent d21b4cf commit 762482d

File tree

1 file changed

+57
-50
lines changed

1 file changed

+57
-50
lines changed

divide_and_conquer/closest_pair_of_points.py

+57-50
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,54 @@
11
"""
2-
The algorithm finds distance between closest pair of points
2+
The algorithm finds distance between closest pair of points
33
in the given n points.
4-
Approach used -> Divide and conquer
5-
The points are sorted based on Xco-ords and
4+
Approach used -> Divide and conquer
5+
The points are sorted based on Xco-ords and
66
then based on Yco-ords separately.
7-
And by applying divide and conquer approach,
7+
And by applying divide and conquer approach,
88
minimum distance is obtained recursively.
99
1010
>> Closest points can lie on different sides of partition.
11-
This case handled by forming a strip of points
11+
This case handled by forming a strip of points
1212
whose Xco-ords distance is less than closest_pair_dis
13-
from mid-point's Xco-ords. Points sorted based on Yco-ords
13+
from mid-point's Xco-ords. Points sorted based on Yco-ords
1414
are used in this step to reduce sorting time.
1515
Closest pair distance is found in the strip of points. (closest_in_strip)
1616
1717
min(closest_pair_dis, closest_in_strip) would be the final answer.
18-
19-
Time complexity: O(n * log n)
20-
"""
2118
22-
"""
23-
doctests
24-
>>> euclidean_distance_sqr([1,2],[2,4])
25-
5
26-
>>> dis_between_closest_pair([[1,2],[2,4],[5,7],[8,9],[11,0]],5)
27-
5
28-
>>> dis_between_closest_in_strip([[1,2],[2,4],[5,7],[8,9],[11,0]],5)
29-
85
30-
>>> points = [(2, 3), (12, 30), (40, 50), (5, 1), (12, 10), (3, 4)]
31-
>>> print("Distance:", closest_pair_of_points(points, len(points)))
32-
"Distance: 1.4142135623730951"
19+
Time complexity: O(n * log n)
3320
"""
3421

3522

3623
def euclidean_distance_sqr(point1, point2):
24+
"""
25+
>>> euclidean_distance_sqr([1,2],[2,4])
26+
5
27+
"""
3728
return (point1[0] - point2[0]) ** 2 + (point1[1] - point2[1]) ** 2
3829

3930

4031
def column_based_sort(array, column = 0):
32+
"""
33+
>>> column_based_sort([(5, 1), (4, 2), (3, 0)], 1)
34+
[(3, 0), (5, 1), (4, 2)]
35+
"""
4136
return sorted(array, key = lambda x: x[column])
42-
37+
4338

4439
def dis_between_closest_pair(points, points_counts, min_dis = float("inf")):
45-
""" brute force approach to find distance between closest pair points
40+
"""
41+
brute force approach to find distance between closest pair points
42+
43+
Parameters :
44+
points, points_count, min_dis (list(tuple(int, int)), int, int)
4645
47-
Parameters :
48-
points, points_count, min_dis (list(tuple(int, int)), int, int)
49-
50-
Returns :
46+
Returns :
5147
min_dis (float): distance between closest pair of points
5248
49+
>>> dis_between_closest_pair([[1,2],[2,4],[5,7],[8,9],[11,0]],5)
50+
5
51+
5352
"""
5453

5554
for i in range(points_counts - 1):
@@ -61,14 +60,17 @@ def dis_between_closest_pair(points, points_counts, min_dis = float("inf")):
6160

6261

6362
def dis_between_closest_in_strip(points, points_counts, min_dis = float("inf")):
64-
""" closest pair of points in strip
63+
"""
64+
closest pair of points in strip
65+
66+
Parameters :
67+
points, points_count, min_dis (list(tuple(int, int)), int, int)
6568
66-
Parameters :
67-
points, points_count, min_dis (list(tuple(int, int)), int, int)
68-
69-
Returns :
69+
Returns :
7070
min_dis (float): distance btw closest pair of points in the strip (< min_dis)
7171
72+
>>> dis_between_closest_in_strip([[1,2],[2,4],[5,7],[8,9],[11,0]],5)
73+
85
7274
"""
7375

7476
for i in range(min(6, points_counts - 1), points_counts):
@@ -82,29 +84,32 @@ def dis_between_closest_in_strip(points, points_counts, min_dis = float("inf")):
8284
def closest_pair_of_points_sqr(points_sorted_on_x, points_sorted_on_y, points_counts):
8385
""" divide and conquer approach
8486
85-
Parameters :
86-
points, points_count (list(tuple(int, int)), int)
87-
88-
Returns :
89-
(float): distance btw closest pair of points
87+
Parameters :
88+
points, points_count (list(tuple(int, int)), int)
89+
90+
Returns :
91+
(float): distance btw closest pair of points
9092
93+
>>> closest_pair_of_points_sqr([(1, 2), (3, 4)], [(5, 6), (7, 8)], 2)
94+
8
9195
"""
9296

9397
# base case
9498
if points_counts <= 3:
9599
return dis_between_closest_pair(points_sorted_on_x, points_counts)
96-
100+
97101
# recursion
98102
mid = points_counts//2
99-
closest_in_left = closest_pair_of_points_sqr(points_sorted_on_x,
100-
points_sorted_on_y[:mid],
103+
closest_in_left = closest_pair_of_points_sqr(points_sorted_on_x,
104+
points_sorted_on_y[:mid],
101105
mid)
102-
closest_in_right = closest_pair_of_points_sqr(points_sorted_on_y,
103-
points_sorted_on_y[mid:],
106+
closest_in_right = closest_pair_of_points_sqr(points_sorted_on_y,
107+
points_sorted_on_y[mid:],
104108
points_counts - mid)
105109
closest_pair_dis = min(closest_in_left, closest_in_right)
106-
107-
""" cross_strip contains the points, whose Xcoords are at a
110+
111+
"""
112+
cross_strip contains the points, whose Xcoords are at a
108113
distance(< closest_pair_dis) from mid's Xcoord
109114
"""
110115

@@ -113,21 +118,23 @@ def closest_pair_of_points_sqr(points_sorted_on_x, points_sorted_on_y, points_co
113118
if abs(point[0] - points_sorted_on_x[mid][0]) < closest_pair_dis:
114119
cross_strip.append(point)
115120

116-
closest_in_strip = dis_between_closest_in_strip(cross_strip,
121+
closest_in_strip = dis_between_closest_in_strip(cross_strip,
117122
len(cross_strip), closest_pair_dis)
118123
return min(closest_pair_dis, closest_in_strip)
119124

120-
125+
121126
def closest_pair_of_points(points, points_counts):
127+
"""
128+
>>> closest_pair_of_points([(2, 3), (12, 30)], len([(2, 3), (12, 30)]))
129+
28.792360097775937
130+
"""
122131
points_sorted_on_x = column_based_sort(points, column = 0)
123132
points_sorted_on_y = column_based_sort(points, column = 1)
124-
return (closest_pair_of_points_sqr(points_sorted_on_x,
125-
points_sorted_on_y,
133+
return (closest_pair_of_points_sqr(points_sorted_on_x,
134+
points_sorted_on_y,
126135
points_counts)) ** 0.5
127136

128137

129138
if __name__ == "__main__":
130-
points = [(2, 3), (12, 30), (40, 50), (5, 1), (12, 10), (3, 4)]
139+
points = [(2, 3), (12, 30), (40, 50), (5, 1), (12, 10), (3, 4)]
131140
print("Distance:", closest_pair_of_points(points, len(points)))
132-
133-

0 commit comments

Comments
 (0)