jbenett
jbenett

Reputation: 1

Determining Multiple of the Closest Pairs in Plane

When determining the closest pair of vertices in a plane with the sweep algorithm outlined below, is it possible to determine multiple pairs without additional runs?

  1. Sort points according to their x-coordinates.
  2. Split the set of points into two equal-sized subsets by a vertical line x=xmid. Solve the problem recursively in the left and right subsets. This yields the left-side and right-side minimum distances dLmin and dRmin, respectively.
  3. Find the minimal distance dLRmin among the set of pairs of points in which one point lies on the left of the dividing vertical and the other point lies to the right.
  4. The final answer is the minimum among dLmin, dRmin, and dLRmin.

Upvotes: 0

Views: 486

Answers (2)

user1196549
user1196549

Reputation:

You need to store the equal Closest Pairs in a separate list.

Whenever you compare two distances, you must compare the shortest to that in the separate list.

If shorter, empty the list.

If equal, append to the list (possibly both pairs).

Using a constant-time store, this will not degrade the algorithm complexity.

Upvotes: 0

Patrick87
Patrick87

Reputation: 28312

It seems to me that when you are finding the minimum distance of a pair of points in a half, you can record the pair with minimum distance. If you find other pairs with the same distance, you could remember all of them by pushing them into some sort of collection. Do this for the left and right halves, and for the sliver you check in the middle, and you should be able to print out all the recorded elements of any list(s) corresponding to minimum distances. Something like:

AllPairsMinDist(points[1...n])
    sort points according to x coordinate
    return AllPairsMinDistInternal(points[1...n])

AllPairsMinDistInternal(points[1...n])
    if n = 1 then
        return (+infinity, [])
    else if n = 2 then
        d = distance(points[1], points[2])
        c = (points[1], points[2])
        return (d, c)
    else then
        (dL, cL) = AllPairsMinDistInternal(points[1...floor(n/2)])
        (dR, cR) = AllPairsMinDistInternal(points[floor(n/2)+1...n])
        (dM, cM) = PairsMinDistMiddle(points[1...n], dL, dR)
        dMin = min(dL, dR, dM)
        cMin = []
        if dL = dMin then cMin = cMin union cL
        if dR = dMin then cMin = cMin union cR
        if dM = dMin then cMin = cMin union cM
        return (dMin, cMin)

AllPairsMinDistMiddle(points[1...n], dL, dR)
    if n = 1 then
        return (+infinity, [])
    else if n = 2 then
        d = distance(points[1], points[2])
        c = (points[1], points[2])
        return (d, c)
    else then
        xV = (points[floor(n/2)].x + points[floor(n/2)+1].x) / 2

        minD = min(dL, dR)
        minC = []

        ll = binary search for index of point with smallest
             x coordinate satisfying xV - x <= minD

        rr = binary search for index of point with largest
             x coordinate satisfying x - xV <= minD

        for i = ll to floor(n/2) do
            for j = floor(n/2) + 1 to rr do
                d = distance(points[i], points[j])
                if d = minD then
                    minC = minC union [(points[i], points[j])]
                else if d < minD then
                    minD = d
                    minC = [(points[i], points[j])]

        alternative to for loop:
            (dMin, cMin) = AllPairsMinDistInternal(points[ll...rr])

        return (dMin, cMin)

There are probably some issues with the above - I just sort of typed it out ad-hoc and without really understanding the algorithm that's being used - but from your high-level description this sounds doable.

Upvotes: 0

Related Questions