Skip to content

Commit 3bf3564

Browse files
committed
additional file in divide_and_conqure (closest pair of points)
1 parent cfbbb7b commit 3bf3564

File tree

2 files changed

+83
-33
lines changed

2 files changed

+83
-33
lines changed

Diff for: divide_and_conquer/closest_pair_of_points.py

+72-25
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,113 @@
11
"""
2-
The algorithm finds distance between closest pair of points in the given n points.
3-
Approach: Divide and conquer
4-
The points are sorted based on x-cords
2+
The algorithm finds distance btw closest pair of points in the given n points.
3+
Approach used -> Divide and conquer
4+
The points are sorted based on Xco-ords
55
& by applying divide and conquer approach,
66
minimum distance is obtained recursively.
77
8-
Edge case: closest points lie on different sides of partition
8+
>> closest points lie on different sides of partition
99
This case handled by forming a strip of points
10-
which are at a distance (< closest_pair_dis) from mid-point.
11-
(It is a proven that strip contains at most 6 points)
12-
And brute force method is applied on strip to find closest points.
10+
whose Xco-ords distance is less than closest_pair_dis
11+
from mid-point's Xco-ords.
12+
Closest pair distance is found in the strip of points. (closest_in_strip)
1313
14-
Time complexity: O(n * (logn) ^ 2)
14+
min(closest_pair_dis, closest_in_strip) would be the final answer.
15+
16+
Time complexity: O(n * (logn)^2)
1517
"""
1618

1719

1820
import math
1921

2022

21-
def euclidean_distance(point1, point2):
22-
return math.sqrt(pow(point1[0] - point2[0], 2) + pow(point1[1] - point2[1], 2))
23+
def euclidean_distance_sqr(point1, point2):
24+
return pow(point1[0] - point2[0], 2) + pow(point1[1] - point2[1], 2)
2325

2426

2527
def column_based_sort(array, column = 0):
2628
return sorted(array, key = lambda x: x[column])
2729

2830

29-
#brute force approach to find distance between closest pair points
30-
def dis_btw_closest_pair(points, no_of_points, min_dis = float("inf")):
31-
for i in range(no_of_points - 1):
32-
for j in range(i+1, no_of_points):
33-
current_dis = euclidean_distance(points[i], points[j])
31+
def dis_btw_closest_pair(points, points_counts, min_dis = float("inf")):
32+
""" brute force approach to find distance between closest pair points
33+
34+
Parameters :
35+
points, points_count, min_dis (tuple(tuple(int, int)), int, int)
36+
37+
Returns :
38+
min_dis (float): distance between closest pair of points
39+
40+
"""
41+
42+
for i in range(points_counts - 1):
43+
for j in range(i+1, points_counts):
44+
current_dis = euclidean_distance_sqr(points[i], points[j])
3445
if current_dis < min_dis:
3546
min_dis = current_dis
3647
return min_dis
3748

3849

39-
#divide and conquer approach
40-
def closest_pair_of_points(points, no_of_points):
50+
def dis_btw_closest_in_strip(points, points_counts, min_dis = float("inf")):
51+
""" closest pair of points in strip
52+
53+
Parameters :
54+
points, points_count, min_dis (tuple(tuple(int, int)), int, int)
55+
56+
Returns :
57+
min_dis (float): distance btw closest pair of points in the strip (< min_dis)
58+
59+
"""
60+
61+
for i in range(min(6, points_counts - 1), points_counts):
62+
for j in range(max(0, i-6), i):
63+
current_dis = euclidean_distance_sqr(points[i], points[j])
64+
if current_dis < min_dis:
65+
min_dis = current_dis
66+
return min_dis
67+
68+
69+
70+
def closest_pair_of_points_sqr(points, points_counts):
71+
""" divide and conquer approach
72+
73+
Parameters :
74+
points, points_count (tuple(tuple(int, int)), int)
75+
76+
Returns :
77+
(float): distance btw closest pair of points
78+
79+
"""
80+
4181
# base case
42-
if no_of_points <= 3:
43-
return dis_btw_closest_pair(points, no_of_points)
82+
if points_counts <= 3:
83+
return dis_btw_closest_pair(points, points_counts)
4484

45-
#recursion
46-
mid = no_of_points//2
85+
# recursion
86+
mid = points_counts//2
4787
closest_in_left = closest_pair_of_points(points[:mid], mid)
48-
closest_in_right = closest_pair_of_points(points[mid:], no_of_points - mid)
88+
closest_in_right = closest_pair_of_points(points[mid:], points_counts - mid)
4989
closest_pair_dis = min(closest_in_left, closest_in_right)
5090

51-
#points which are at a distance (< closest_pair_dis) from mid-point
91+
""" cross_strip contains the points, whose Xcoords are at a
92+
distance(< closest_pair_dis) from mid's Xcoord
93+
"""
94+
5295
cross_strip = []
5396
for point in points:
5497
if abs(point[0] - points[mid][0]) < closest_pair_dis:
5598
cross_strip.append(point)
5699

57100
cross_strip = column_based_sort(cross_strip, 1)
58-
closest_in_strip = dis_btw_closest_pair(cross_strip,
101+
closest_in_strip = dis_btw_closest_in_strip(cross_strip,
59102
len(cross_strip), closest_pair_dis)
60103
return min(closest_pair_dis, closest_in_strip)
104+
61105

106+
def closest_pair_of_points(points, points_counts):
107+
return math.sqrt(closest_pair_of_points_sqr(points, points_counts))
108+
62109

63-
points = [[2, 3], [12, 30], [40, 50], [5, 1], [12, 10]]
110+
points = ((2, 3), (12, 30), (40, 50), (5, 1), (12, 10), (0, 2), (5, 6), (1, 2))
64111
points = column_based_sort(points)
65112
print("Distance:", closest_pair_of_points(points, len(points)))
66113

Diff for: divide_and_conquer/max_sub_array_sum.py renamed to divide_and_conquer/max_subarray_sum.py

+11-8
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
"""
2-
Given a array of length n, max_sub_array_sum() finds the maximum of sum of contiguous sub-array using divide and conquer method.
2+
Given a array of length n, max_subarray_sum() finds
3+
the maximum of sum of contiguous sub-array using divide and conquer method.
34
45
Time complexity : O(n log n)
56
6-
Ref : INTRODUCTION TO ALGORITHMS THIRD EDITION (section : 4, sub-section : 4.1, page : 70)
7+
Ref : INTRODUCTION TO ALGORITHMS THIRD EDITION
8+
(section : 4, sub-section : 4.1, page : 70)
79
810
"""
911

@@ -43,11 +45,12 @@ def max_cross_array_sum(array, left, mid, right):
4345
return max_sum_of_left + max_sum_of_right
4446

4547

46-
def max_sub_array_sum(array, left, right):
47-
""" This function finds the maximum of sum of contiguous sub-array using divide and conquer method
48+
def max_subarray_sum(array, left, right):
49+
""" Maximum contiguous sub-array sum, using divide and conquer method
4850
4951
Parameters :
50-
array, left, right (list[int], int, int) : given array, current left index and current right index
52+
array, left, right (list[int], int, int) :
53+
given array, current left index and current right index
5154
5255
Returns :
5356
int : maximum of sum of contiguous sub-array
@@ -60,13 +63,13 @@ def max_sub_array_sum(array, left, right):
6063

6164
# Recursion
6265
mid = (left + right) // 2
63-
left_half_sum = max_sub_array_sum(array, left, mid)
64-
right_half_sum = max_sub_array_sum(array, mid + 1, right)
66+
left_half_sum = max_subarray_sum(array, left, mid)
67+
right_half_sum = max_subarray_sum(array, mid + 1, right)
6568
cross_sum = max_cross_array_sum(array, left, mid, right)
6669
return max(left_half_sum, right_half_sum, cross_sum)
6770

6871

6972
array = [-2, -5, 6, -2, -3, 1, 5, -6]
7073
array_length = len(array)
71-
print("Maximum sum of contiguous subarray:", max_sub_array_sum(array, 0, array_length - 1))
74+
print("Maximum sum of contiguous subarray:", max_subarray_sum(array, 0, array_length - 1))
7275

0 commit comments

Comments
 (0)