學習筆記 K D樹

2022-05-31 17:21:12 字數 2272 閱讀 9934

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個最相鄰的樣本中的大多數屬於某乙個類別,...