Kd-tree realization

Source: Internet
Author: User
Tags polyline
Kd-tree 1. Use the background

There is a problem in the project: How to calculate the nearest distance from a point to a polyline-the vertex of a polyline may have thousands of vertices, and the points that need to be retrieved may have tens of thousands of data, which is really a question to consider ~ 2. Brute Force solution

There is a more intuitive way: Calculate the distance from the point to the polyline, and then violence to find the shortest part ~ Get solution. However, the O (n) Complexity method obviously encounters large data volumes that can seriously slow down the performance of the server. 3.K Proximity algorithm-data structure

The

KNN gives a very ingenious revelation for approximate solutions, which can be obtained by 2d-tree (k=2).
to take a slightly more complicated example, let's find the point (2,4.5), test arrival at (7,2), test arrival (4,7) at (5,4), and then Search_path node in < (7,2), (5,4), (4,7); Remove from Search_path (4,7) as the current best node nearest, dist for 3.202,
then back to (5,4), with (2,4.5) as the center, with dist=3.202 as a radius to draw a circle with the super plane y=4 intersect, as shown below, So you need to jump to (5,4) the left dial hand space to search. So to add (2,3) to the Search_path, now the Search_path node is < (7,2), (2, 3) >; in addition, (5,4) and (2,4.5) the distance is 3.04 < dist = 3.202, so (5,4) Assigned to nearest, and dist=3.04.
Back to (2,3), (2,3) is a leaf node, the direct flat judgment (2,3) is closer to (2,4.5), calculate the distance is 1.5, so nearest update to (2,3), dist update to (1.5)
Back to (7,2), similarly, to ( 2,4.5) for the center, draw a circle with dist=1.5 radius does not intersect with the x=7, so you do not have to jump to the right subspace of the node (7,2) to search.
At this point, Search_path is empty, ending the entire search, returning nearest (2,3) as the nearest neighbor of (2,4.5), and the closest distance is 1.5.

4. Code implementation KDTree.h

#define Lson (RT << 1)//Left node #define Rson (rt << 1 | 1)//Right node #include <vector> #include <algorithm&gt
;
    #include <cmath> const int N = 50005; const int k = 2;
        2d-tree struct Node {float feature[2];//feature[0] = x, feature[1] = y static int idx;
            Node (float x0, float y0) {feature[0] = x0;
        FEATURE[1] = y0;
        } BOOL operator < (const Node &u) const {return FEATURE[IDX] < U.FEATURE[IDX];
            }//tood =hao Node () {feature[0] = 0;
        Feature[0] = 0;

    }
    };
        Class Kdtree {public:kdtree ();
        ~kdtree ();
        void Clean ();
        int read_in (float* ary_x, float* ary_y, int len);
        void build (int l, int r, int rt, int dept);
        int Find_nearest_point (float x, float y, node& result, float& Dist);
    float Distance (const node& x, const node& y);
   Private     void query (const node& p, node& res, float& Dist, int rt, int dept);
        Std::vector<node> _data;//uses vector to simulate the array std::vector<int> _flag;//to determine if there is an int _idx;
    Std::vector<node> _find_nth;
 };
Kd-tree.cpp
    #include "KDTree.h" int node::idx = 0;
        Kdtree::kdtree () {_data.reserve (N * 4); _flag.reserve (N * 4);//todo init} kdtree::~kdtree () {} int kdtree::read_in (float* ary_x, float* ary_y, int
        Len) {_find_nth.reserve (N * 4);
            for (int i = 0; i < len; ++i) {Node tmp (Ary_x[i], ary_y[i]);
        _find_nth.push_back (Node (Ary_x[i], ary_y[i]));
            } for (int i = 0; i < N * 4; ++i) {Node tmp;
            _data.push_back (TMP);
        _flag.push_back (0);
        } build (0, len-1, 1, 0);
    return 0;
        } void Kdtree::clean () {_find_nth.clear ();
        _data.clear ();
    _flag.clear ();
        }//Establish kd-tree void kdtree::build (int l, int r, int rt, int dept) {if (L > R) return;                  _FLAG[RT] = 1; A node indicating that the label is RT exists _flag[lson] = _flag[rson] =-1;
        The child of the current node is temporarily marked without the presence of int mid = (L + R + 1) >> 1; NOde::idx = dept% K;
        Divide std::nth_element (_find_nth.begin () + L, _find_nth.begin () + Mid, _find_nth.begin () + R + 1) according to the attributes that are numbered idx.
        _DATA[RT] = _find_nth[mid]; Build (L, Mid-1, Lson, dept + 1);
    Recursive left subtree Build (mid + 1, R, Rson, dept + 1);
        } int Kdtree::find_nearest_point (float x, float y, node &res, float& Dist) {node p (x, y);
        Query (P, RES, dist, 1, 0);
    return 0;
        }//Find Kd-tree distance p nearest point void Kdtree::query (const node& p, node& res, float& Dist, int rt, int dept) {
        if (_flag[rt] = =-1) {return;
        }//nodes that do not exist do not traverse float tmp_dist = distance (_data[rt], p); BOOL FG = FALSE; Used to mark whether you need to traverse right subtree int Dim = dept% K;
        As with achievements, ensure that the same node's Dim value does not change int x = Lson;
        int y = Rson;  if (P.feature[dim] >= _data[rt].feature[dim]) {std::swap (x, y); The dim characteristic value of the data p is greater than or equal to the current data, then it needs to go to the right subtree} if (~_flag[x]) {QUery (P, res, dist, x, dept + 1);
            Node x exists, then enter subtree to continue traversal} if (Tmp_dist < dist) {//If a smaller distance is found, replace the current result dist res = _data[rt];
        dist = tmp_dist;
        } tmp_dist = (P.feature[dim]-_data[rt].feature[dim]) * (P.feature[dim]-_data[rt].feature[dim]);
        if (Tmp_dist < dist) {//need to continue backtracking FG = true;
        } if (~_flag[y] && FG) {query (P, res, dist, y, dept + 1);
        }}//Calculate the distance between two points of the square float kdtree::d istance (const node& x, const node& y) {float res = 0;
        for (int i = 0; i < K; i++) {res + = (X.feature[i]-y.feature[i]) * (X.feature[i]-y.feature[i]);
    } return res;
 }

Self-Test no discovery bug~
Reference article:
(http://blog.csdn.net/acdreamers/article/details/44664645/"Kd-tree Implementation")
(HTTP/ blog.csdn.net/silangquan/article/details/41483689/"Detailed kd-tree")
Thanks to the Giants for their sharing

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.