k-d樹的本質是一棵二叉查詢樹,但每一層劃分的標準變為某一維度,以垂直於某一座標軸的超平面將當前區域劃分為兩個區域
但和二叉查詢樹不同的是k-d樹每個節點儲存了乙個樣本,簡單理解為每個節點都代表插入的乙個點
考慮當前區域按第\(dim\)維劃分,為了讓樹盡量平衡,將這個區域內所有點按第\(dim\)維排序後,從第\(mid\)個點處劃分最優,\(c++\)可以用\(nth\_element\)快速求出這個點,順便把排在這個點之前的點全都放到它左邊
當前節點存下第\(mid\)個點的資訊,然後遞迴的構建左子樹和右子樹
**(二維)如下:
kd_tree::node *kd_tree::build(int l, int r, int dim)
其中\(l\)到\(r\)的點是區域內的點,\(dim\)代表當前維度
以查詢距點\(p\)最近的點為例
依然是遞迴查詢
首先檢視當前節點所代表的點是否更優,然後估計左右子樹距這個點可能的最近距離
如果估計值更優,就繼續往子樹查詢,否則就不用找下去了
當左右子樹都更優時,顯然先找較優的子樹不會更差,若找完較優的子樹後另一棵子樹還有可能更優,再到查詢另一棵子樹中查詢
**(二維)如下:
ll querymin(kd_tree *rt, point &tar) else
return res;
}
通常需要記錄左右兒子、每一維座標的最大及最小值、所代表的點的資訊,劃分的維度可以記錄,也可以遞迴過程中處理出來
其它資訊根據題目要求
看起來非常高階的k-d樹其實是很樸素的搜尋加上很神奇的剪枝
兩句話概括就是:
構建——迴圈用每一維構建二叉查詢樹,記錄資訊
查詢——如果子樹中可能有更優解就進入查詢,否則退出,優先查詢可能的解更優的那顆子樹
是不是異常簡單?(然而我學了半個星期才打出模板)
最近點對的找不到了,放個這題[cqoi2016]k遠點對吧,也挺裸的
#include #include #include #include #include #define sqr(x) ((x) * (x))
#define maxn 100005
typedef long long ll;
struct point
} pt[maxn];
struct kd_tree * root;
void push_up(node *);
node* build(int, int, int);
void query(node *, int, const point &);
} kd;
int n, k;
std::priority_queue, std::greater> que;
bool cmp0(const point &, const point &);
bool cmp1(const point &, const point &);
bool (* cmp)(const point &, const point &) = ;
inline ll dist(const point &p1, const point &p2)
inline ll max_dist(const point &p, kd_tree::node *rt)
int main()
inline void max(ll &a, ll b)
inline void min(ll &a, ll b)
bool cmp0(const point &p1, const point &p2)
bool cmp1(const point &p1, const point &p2)
kd_tree::node *kd_tree::build(int l, int r, int dim)
void kd_tree::query(node *rt, int dim, const point &p)
ll dl = -0x3f3f3f3f3f3f3f3f, dr = -0x3f3f3f3f3f3f3f3f;
if (rt->ls) dl = max_dist(p, rt->ls);
if (rt->rs) dr = max_dist(p, rt->rs);
if (dl > dr) else
}void kd_tree::push_up(node *rt)
if (rt->rs)
}//rhein_e
KD樹演算法
學習了kd樹演算法,用來進行最近鄰匹配,其偽 如下 kd樹演算法的偽 節點結構 node 建立kd樹 輸入 點集list 輸出 kd樹根節點 def build tree list if list is none return none 計算所有點在每一維的方差並排序,從方差最大的維度vi維開始建樹...
KD樹的C 實現
kd樹 k dimension tree 是一種對k維空間中的例項點進行儲存以便對其進行快速檢索的樹形資料結構。kd樹是是一種二叉樹,表示對k維空間的乙個劃分,構造kd樹相當於不斷地用垂直於座標軸的超平面將k維空間切分,構成一系列的k維超矩形區域。kd樹的每個結點對應於乙個k維超矩形區域。利用kd樹...
KNN演算法和KD樹
knn k nearestneighbor 鄰近演算法,或者說k最近鄰分類演算法 是資料探勘分類技術中最簡單的方法之一。所謂k最近鄰,就是k個最近的鄰居的意思,說的是每個樣本都可以用它最接近的k個鄰居來代表。knn演算法的核心思想是如果乙個樣本在特徵空間中的k個最相鄰的樣本中的大多數屬於某乙個類別,...