Question: There are several points in the plane to find the closest two points.
Analysis:
Method 1: compare two vertices to find the nearest two vertices. The complexity is O (n ^ 2). The advantage code is simple and error-prone.
Method 2: Observe the two-to-two comparison methods and find that there are many useless comparisons. For each vertex, you only need to calculate the distance from the closest vertex, and enumerate all vertices, finally, we can get a pair of vertices closest to it. But for a given point, how can we find the point closest to it? Some heuristic rules can be used to reduce the number of comparisons. For example, for (x, y), obtain the closest point P1 (x1, Y1) on the X axis projection) and take the point P2 (X2, Y2) closest to the projection on the Y axis, take (x, y) as a fixed point, take the larger ones in X1 and X2 x', Y1, the larger vertex y' in Y2, which forms (x', y') as another vertex of the rectangle. The distance between all vertices in the rectangle and (x, y) is calculated, this reduces the number of comparisons. Take (x, y) as the center, judge all points within the four conditions, and finally obtain the smallest point of distance (x, y. The complexity is O (n * K), and K is the average number of points to be judged.
Method 3: divide and divide the data into two parts from the X axis. The nearest two points of the two parts are smaller. In the comparison between the two parts, the minimum distance between the two parts is obtained, this reduces the number of points in the intermediate band. For details, see the analysis of the beauty of programming.
The procedure for method 3 is as follows:
#include <stdio.h>#include <algorithm>#include <vector>#include <math.h>class Point { public: Point(int x, int y) : x_(x), y_(y) {} Point() : x_(0), y_(0) {} static bool OrderByX(const Point& left, const Point& right) { return left.x_ < right.x_; } static bool OrderByY(const Point& left, const Point& right) { return left.y_ < right.y_; } int x_; int y_;};float Distance(const Point& left, const Point& right) { return sqrt(pow(left.x_ - right.x_, 2) + pow(left.y_ - right.y_, 2));}int NearestPoints(const std::vector<Point>& points, int start, int end, Point* point1, Point* point2) { if (end > start) { int middle = (start + end) / 2; int left_min_distance = NearestPoints(points, start, middle, point1, point2); int right_min_distance = NearestPoints(points, middle + 1, end, point1, point2); int min_distance = left_min_distance > right_min_distance ? right_min_distance : left_min_distance; std::vector<Point> left_part_points; for (int i = start; i <= middle; ++i) { if (points[middle].x_ - points[i].x_ <= min_distance) { left_part_points.push_back(points[i]); } } sort(left_part_points.begin(), left_part_points.end(), Point::OrderByY); std::vector<Point> right_part_points; for (int i = middle + 1; i <= end; ++i) { if (points[i].x_ - points[middle].x_ <= min_distance) { right_part_points.push_back(points[i]); } } sort(right_part_points.begin(), right_part_points.end(), Point::OrderByY); int distance_y = 0; int point_distance = 0; for(int i = 0; i < left_part_points.size(); ++i) { for(int j = 0; j < right_part_points.size(); ++j) { distance_y = left_part_points[i].y_ > right_part_points[j].y_ ? left_part_points[i].y_ - right_part_points[j].y_ : right_part_points[j].y_ - left_part_points[i].y_; if (distance_y <= min_distance) { point_distance = Distance(left_part_points[i], right_part_points[j]); if (point_distance < min_distance) { min_distance = point_distance; *point1 = left_part_points[i]; *point2 = right_part_points[j]; } } } } return min_distance; } else { return 0x7FFFFFFF; }} int main(int argc, char** argv) { std::vector<Point> points; points.push_back(Point(2,3)); points.push_back(Point(1,4)); points.push_back(Point(3,0)); points.push_back(Point(5,0)); points.push_back(Point(5,1)); sort(points.begin(), points.end(), Point::OrderByX); Point point1; Point point2; NearestPoints(points, 0, points.size() - 1, &point1, &point2); printf("Point1: (%d, %d) <--> Point2: (%d, %d)\n", point1.x_, point1.y_, point2.x_, point2.y_);}
You can search for vertices in a rectangle by means of binary search. For simplicity, you can search for vertices in a loop.
References:
Programming beauty 2.11