0

First off, I was reading about the sweep-line algorithm to find closest pair of points in O(N lgN) time over at topcoder. I mostly understood the algorithm, however when I look at the implementation provided here (copied and made more readable below), I notice some striking differences.

#define x first
#define y second
typedef pair<long long, long long> pll;
   ...
set <pll> boundingBox;
boundingBox.insert(points[0]); //Points have been already sorted by x-coordinate
for (int i = 1; i < numPoints; i++)
{
    while ((left < i) && (points[i].x - points[left].x > shortestDistSoFar))
    {
        boundingBox.erase(points[left]);
        left++;
    }

    for (auto it = boundingBox.lower_bound(pll(points[i].y - shortestDistSoFar, points[i].x - shortestDistSoFar)); it != boundingBox.end() && it->y <= points[i].y + shortestDistSoFar; it++)
    {
        if (dist(*it, points[i]) < shortestDistSoFar)
        {
            shortestDistSoFar = dist(*it, points[i]);
            best1 = *it;
            best2 = points[i];
        }
    }
    boundingBox.insert(points[i]);
}

First, in the implementation snippet above, the std::set that holds the points and represents the bounding rectangle is not sorted by y-coordinate (instead by x-coordinate) which is contrary to what almost every other source says: The set is ordered by y coordinate. (Topcoder).

Next, even though the set is not sorted by y-coordinate, when the iterator is used to consider points in the active set ... whose y coordinates are in the range yN − h to yN + h, it is taken as the lower bound of pll(points[i].y - shortestDistSoFar, points[i].x - shortestDistSoFar). Why does the y come first? I would think that the correct order would be pll(points[i].x, points[i].y - shortestDistSoFar) but changing it to this breaks the algorithm.

Can someone please help address these seemingly inconsistent things?

1110101001
  • 4,662
  • 7
  • 26
  • 48
  • I didn't understand. Where is it given that Y is the first element ?? ` (typeof(box.begin()) it=box.lower_bound(make_pair(pnts[i].py-best, pnts[i].px-best)); ` Please explain – Aditya Mhatre Oct 06 '16 at 06:04

1 Answers1

1

In the original code, y coordinate is the first element of a pair. That's why points in a set are ordered correctly.

kraskevich
  • 18,368
  • 4
  • 33
  • 45
  • Actually, I found another interesting thing. Simply changing the #defines to make x second and y first without updating the sorting of the points (which is what `compx` does in the original code) also seems to give the correct answer. That is, visiting the points in order of y-coordinate for the sweep line seems to give the right answer too. Is there a good reason for this? Perhaps something to do with how the distance from (x, y) to (a, b) is the same as distance from (y, x) to (b, a)? – 1110101001 Dec 30 '14 at 02:32
  • @1110101001 Of course, we can sort them by y coordinate and then maintain a set ordered by x coordinate. Swapping x and y is a rotation by 90 degrees, so it leaves distances unchanged. – kraskevich Dec 30 '14 at 08:56