【基礎不牢,地動山搖】K-D樹

爲什麼在這裏介紹最爲基礎的數據結構“樹”呢?
因爲在最近鄰算法中樹有很重要的作用。首先回顧一下二叉樹:

二叉樹

二叉樹是每個結點最多有兩個子樹的樹結構。通常子樹被稱作“左子樹”和“右子樹”。二叉樹常被用於實現二叉查找樹和二叉堆。一張圖快速理解二叉樹:
在這裏插入圖片描述
二叉樹的搜索和構造就不再這裏介紹了,大家可以參考這篇文章。link

K-D樹

爲什麼在上一節介紹二叉樹?因爲K-D樹是每個節點都爲k維點的二叉樹。是一種對K維空間內的實例點進行存儲,以便對其進行快速的搜索的方法。構造K-D 樹相當於不斷的用垂直與座標軸的超平面將K維空間切分。K-D樹的每個節點對應一個K維超矩形區域。很拗口?來個例子吧

例子

一個二維數據集
T={(2,3)T,(5,4)T,(9,6)T,(4,7)T,(9,6)T,(4,7)T,(8,1)T,(7,2)T} T=\{(2,3)^T,(5,4)^T,(9,6)^T,(4,7)^T,(9,6)^T,(4,7)^T,(8,1)^T,(7,2)^T\}

  • (1)選擇xx軸的6個數據點2,4,5,7,8,9的中位數7,分爲兩個矩形。(這裏需要看下源代碼,理解下這裏的中位數)
point_list.sort(key=itemgetter(axis))
median = len(point_list) // 2 # choose median
location=point_list[median]
  • (2)左矩形以yy軸4分爲兩個子矩形,右矩形以y=6y=6分爲兩個子矩形。
  • (3)遞歸哈劃分,直到完成。

在這裏插入圖片描述
如何構造KD樹?
具體的算法流程如下所是:
輸入: K維空間的數據集T=x1,x2,...xN,(xi=(xi(1),xi(2)),...xi(K))T={x_1,x_2,...x_N},(x_i=(x^{(1)}_i,x^{(2)}_i),...x^{(K)}_i)
輸出: KD樹

  • 構造根節點,根節點對應與包含TT的K維空間的超矩形區域。以x1x^{1}的中位數且分爲兩個矩形區域,
  • 重複切分步驟
  • 直到兩個子區域沒有且分點爲止。

K-D樹搜索

輸入: KD樹,目標點xx
輸出: KD樹

  • 在KD樹中找到包含目標點xx的葉節點。從根節點出發,遞歸的向下訪問KD樹。若目標點x維當前的座標小於切分的的座標,則移動到左節點,否則到右節點。
  • 以此節點爲當前的最近點。
  • 遞歸的向上回退。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章