Closest Pair of Points using Divide and Conquer algorithm | A divide and conquer program in Python3 to find the smallest distance from a given set of points . ; A class to represent a Point in 2D plane ; A utility function to find the distance between two points ; A Brute Force method to return the smallest distance between two points in P [ ] of size n ; A utility function to find the distance beween the closest points of strip of given size . All points in strip [ ] are sorted accordint to y coordinate . They all have an upper bound on minimum distance as d . Note that this method seems to be a O ( n ^ 2 ) method , but it 's a O(n) method as the inner loop runs at most 6 times ; Initialize the minimum distance as d ; Pick all points one by one and try the next points till the difference between y coordinates is smaller than d . This is a proven fact that this loop runs at most 6 times ; A recursive function to find the smallest distance . The array P contains all points sorted according to x coordinate ; If there are 2 or 3 points , then use brute force ; Find the middle point ; keep a copy of left and right branch ; Consider the vertical line passing through the middle point calculate the smallest distance dl on left of middle point and dr on right side ; Find the smaller of two distances ; Build an array strip [ ] that contains points close ( closer than d ) to the line passing through the middle point ; < -- REQUIRED ; Find the self . closest points in strip . Return the minimum of d and self . closest distance is strip [ ] ; The main function that finds the smallest distance . This method mainly uses closestUtil ( ) ; Use recursive function closestUtil ( ) to find the smallest distance ; Driver code
import math NEW_LINE import copy NEW_LINE class Point ( ) : NEW_LINE INDENT def __init__ ( self , x , y ) : NEW_LINE INDENT self . x = x NEW_LINE self . y = y NEW_LINE DEDENT DEDENT def dist ( p1 , p2 ) : NEW_LINE INDENT return math . sqrt ( ( p1 . x - p2 . x ) * ( p1 . x - p2 . x ) + ( p1 . y - p2 . y ) * ( p1 . y - p2 . y ) ) NEW_LINE DEDENT def bruteForce ( P , n ) : NEW_LINE INDENT min_val = float ( ' inf ' ) NEW_LINE for i in range ( n ) : NEW_LINE INDENT for j in range ( i + 1 , n ) : NEW_LINE INDENT if dist ( P [ i ] , P [ j ] ) < min_val : NEW_LINE INDENT min_val = dist ( P [ i ] , P [ j ] ) NEW_LINE DEDENT DEDENT DEDENT return min_val NEW_LINE DEDENT def stripClosest ( strip , size , d ) : NEW_LINE INDENT min_val = d NEW_LINE for i in range ( size ) : NEW_LINE INDENT j = i + 1 NEW_LINE while j < size and ( strip [ j ] . y - strip [ i ] . y ) < min_val : NEW_LINE INDENT min_val = dist ( strip [ i ] , strip [ j ] ) NEW_LINE j += 1 NEW_LINE DEDENT DEDENT return min_val NEW_LINE DEDENT def closestUtil ( P , Q , n ) : NEW_LINE INDENT if n <= 3 : NEW_LINE INDENT return bruteForce ( P , n ) NEW_LINE DEDENT mid = n // 2 NEW_LINE midPoint = P [ mid ] NEW_LINE Pl = P [ : mid ] NEW_LINE Pr = P [ mid : ] NEW_LINE dl = closestUtil ( Pl , Q , mid ) NEW_LINE dr = closestUtil ( Pr , Q , n - mid ) NEW_LINE d = min ( dl , dr ) NEW_LINE stripP = [ ] NEW_LINE stripQ = [ ] NEW_LINE lr = Pl + Pr NEW_LINE for i in range ( n ) : NEW_LINE INDENT if abs ( lr [ i ] . x - midPoint . x ) < d : NEW_LINE INDENT stripP . append ( lr [ i ] ) NEW_LINE DEDENT if abs ( Q [ i ] . x - midPoint . x ) < d : NEW_LINE INDENT stripQ . append ( Q [ i ] ) NEW_LINE DEDENT DEDENT stripP . sort ( key = lambda point : point . y ) NEW_LINE min_a = min ( d , stripClosest ( stripP , len ( stripP ) , d ) ) NEW_LINE min_b = min ( d , stripClosest ( stripQ , len ( stripQ ) , d ) ) NEW_LINE return min ( min_a , min_b ) NEW_LINE DEDENT def closest ( P , n ) : NEW_LINE INDENT P . sort ( key = lambda point : point . x ) NEW_LINE Q = copy . deepcopy ( P ) NEW_LINE Q . sort ( key = lambda point : point . y ) NEW_LINE return closestUtil ( P , Q , n ) NEW_LINE DEDENT P = [ Point ( 2 , 3 ) , Point ( 12 , 30 ) , Point ( 40 , 50 ) , Point ( 5 , 1 ) , Point ( 12 , 10 ) , Point ( 3 , 4 ) ] NEW_LINE n = len ( P ) NEW_LINE print ( " The ▁ smallest ▁ distance ▁ is " , closest ( P , n ) ) NEW_LINE