1
1
"""
2
2
The algorithm finds distance btw closest pair of points in the given n points.
3
3
Approach used -> Divide and conquer
4
- The points are sorted based on Xco-ords
4
+ The points are sorted based on Xco-ords and
5
+ then based on Yco-ords separetely.
5
6
& by applying divide and conquer approach,
6
7
minimum distance is obtained recursively.
7
8
8
9
>> closest points lie on different sides of partition
9
10
This case handled by forming a strip of points
10
11
whose Xco-ords distance is less than closest_pair_dis
11
- from mid-point's Xco-ords.
12
+ from mid-point's Xco-ords. points sorted based on Yco-ords
13
+ are used in this step to reduce sorting time.
12
14
Closest pair distance is found in the strip of points. (closest_in_strip)
13
15
14
16
min(closest_pair_dis, closest_in_strip) would be the final answer.
15
17
16
- Time complexity: O(n * ( logn)^2 )
18
+ Time complexity: O(n * logn)
17
19
"""
18
20
19
21
20
- import math
21
-
22
-
23
22
def euclidean_distance_sqr (point1 , point2 ):
24
23
return pow (point1 [0 ] - point2 [0 ], 2 ) + pow (point1 [1 ] - point2 [1 ], 2 )
25
24
@@ -66,7 +65,7 @@ def dis_between_closest_in_strip(points, points_counts, min_dis = float("inf")):
66
65
return min_dis
67
66
68
67
69
- def closest_pair_of_points_sqr (points , points_counts ):
68
+ def closest_pair_of_points_sqr (points_sorted_on_X , points_sorted_on_Y , points_counts ):
70
69
""" divide and conquer approach
71
70
72
71
Parameters :
@@ -79,35 +78,41 @@ def closest_pair_of_points_sqr(points, points_counts):
79
78
80
79
# base case
81
80
if points_counts <= 3 :
82
- return dis_between_closest_pair (points , points_counts )
81
+ return dis_between_closest_pair (points_sorted_on_X , points_counts )
83
82
84
83
# recursion
85
84
mid = points_counts // 2
86
- closest_in_left = closest_pair_of_points (points [:mid ], mid )
87
- closest_in_right = closest_pair_of_points (points [mid :], points_counts - mid )
85
+ closest_in_left = closest_pair_of_points_sqr (points_sorted_on_X ,
86
+ points_sorted_on_Y [:mid ],
87
+ mid )
88
+ closest_in_right = closest_pair_of_points_sqr (points_sorted_on_Y ,
89
+ points_sorted_on_Y [mid :],
90
+ points_counts - mid )
88
91
closest_pair_dis = min (closest_in_left , closest_in_right )
89
92
90
93
""" cross_strip contains the points, whose Xcoords are at a
91
94
distance(< closest_pair_dis) from mid's Xcoord
92
95
"""
93
96
94
97
cross_strip = []
95
- for point in points :
96
- if abs (point [0 ] - points [mid ][0 ]) < closest_pair_dis :
98
+ for point in points_sorted_on_X :
99
+ if abs (point [0 ] - points_sorted_on_X [mid ][0 ]) < closest_pair_dis :
97
100
cross_strip .append (point )
98
101
99
- cross_strip = column_based_sort (cross_strip , 1 )
100
102
closest_in_strip = dis_between_closest_in_strip (cross_strip ,
101
103
len (cross_strip ), closest_pair_dis )
102
104
return min (closest_pair_dis , closest_in_strip )
103
105
104
106
105
107
def closest_pair_of_points (points , points_counts ):
106
- return math .sqrt (closest_pair_of_points_sqr (points , points_counts ))
108
+ points_sorted_on_X = column_based_sort (points , column = 0 )
109
+ points_sorted_on_Y = column_based_sort (points , column = 1 )
110
+ return (closest_pair_of_points_sqr (points_sorted_on_X ,
111
+ points_sorted_on_Y ,
112
+ points_counts )) ** 0.5
107
113
108
114
109
- points = [(2 , 3 ), (12 , 30 ), (40 , 50 ), (5 , 1 ), (12 , 10 ), (0 , 2 ), (5 , 6 ), (1 , 2 )]
110
- points = column_based_sort (points )
115
+ points = [(2 , 3 ), (12 , 30 ), (40 , 50 ), (5 , 1 ), (12 , 10 ), (3 , 4 )]
111
116
print ("Distance:" , closest_pair_of_points (points , len (points )))
112
117
113
118
0 commit comments