真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

kd樹(shù)構(gòu)造代碼java,kd樹(shù)索引

什么叫平衡二叉樹(shù),KD樹(shù)是不是就是平衡二叉樹(shù)呢?

是的。

我們提供的服務(wù)有:成都做網(wǎng)站、網(wǎng)站設(shè)計(jì)、外貿(mào)營(yíng)銷(xiāo)網(wǎng)站建設(shè)、微信公眾號(hào)開(kāi)發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、瀾滄ssl等。為成百上千家企事業(yè)單位解決了網(wǎng)站和推廣的問(wèn)題。提供周到的售前咨詢(xún)和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的瀾滄網(wǎng)站制作公司

平衡二叉樹(shù)(Balanced Binary Tree)又被稱(chēng)為AVL樹(shù)(有別于A(yíng)VL算法),且具有以下性質(zhì):它是一 棵空樹(shù)或它的左右兩個(gè)子樹(shù)的高度差的絕對(duì)值不超過(guò)1,并且左右兩個(gè)子樹(shù)都是一棵平衡二叉樹(shù)。構(gòu)造與調(diào)整方法 平衡二叉樹(shù)的常用算法有紅黑樹(shù)、AVL、Treap、伸展樹(shù)等。 最小二叉平衡樹(shù)的節(jié)點(diǎn)的公式如下 F(n)=F(n-1)+F(n-2)+1 這個(gè)類(lèi)似于一個(gè)遞歸的數(shù)列,可以參考Fibonacci數(shù)列 1是根節(jié)點(diǎn) F(n-1)是左子樹(shù)的節(jié)點(diǎn)數(shù)量 F(n-2)是右子數(shù)的節(jié)點(diǎn)數(shù)量。

kd-

樹(shù)(

k

維搜索樹(shù))是把二叉搜索樹(shù)推廣到多維數(shù)據(jù)的一種主存數(shù)據(jù)結(jié)構(gòu)。我們將先

介紹這種思想,然后討論怎樣使這種思想適合存儲(chǔ)的塊模型。

kd-

樹(shù)是一個(gè)二叉樹(shù),它的內(nèi)

部結(jié)點(diǎn)有一個(gè)相關(guān)聯(lián)的屬性

a

和一個(gè)值

V

,它將數(shù)據(jù)點(diǎn)集分成兩個(gè)部分:

a

值小于

V

的部分

a

值大于等于

V

的部分。

由于所有維的屬性在層間交替出現(xiàn),

所以樹(shù)的不同層上的屬性是

不同的

KNN算法-4-算法優(yōu)化-KD樹(shù)

KNN算法的重要步驟是對(duì)所有的實(shí)例點(diǎn)進(jìn)行快速k近鄰搜索。如果采用線(xiàn)性?huà)呙瑁╨inear scan),要計(jì)算輸入點(diǎn)與每一個(gè)點(diǎn)的距離,時(shí)間復(fù)雜度非常高。因此在查詢(xún)操作時(shí),可以使用kd樹(shù)對(duì)查詢(xún)操作進(jìn)行優(yōu)化。

Kd-樹(shù)是K-dimension tree的縮寫(xiě),是對(duì)數(shù)據(jù)點(diǎn)在k維空間(如二維(x,y),三維(x,y,z),k維(x1,y,z..))中劃分的一種數(shù)據(jù)結(jié)構(gòu),主要應(yīng)用于多維空間關(guān)鍵數(shù)據(jù)的搜索(如:范圍搜索和最近鄰搜索)。本質(zhì)上說(shuō),Kd-樹(shù)就是一種平衡二叉樹(shù)。

k-d tree是每個(gè)節(jié)點(diǎn)均為k維樣本點(diǎn)的二叉樹(shù),其上的每個(gè)樣本點(diǎn)代表一個(gè)超平面,該超平面垂直于當(dāng)前劃分維度的坐標(biāo)軸,并在該維度上將空間劃分為兩部分,一部分在其左子樹(shù),另一部分在其右子樹(shù)。即若當(dāng)前節(jié)點(diǎn)的劃分維度為d,其左子樹(shù)上所有點(diǎn)在d維的坐標(biāo)值均小于當(dāng)前值,右子樹(shù)上所有點(diǎn)在d維的坐標(biāo)值均大于等于當(dāng)前值,本定義對(duì)其任意子節(jié)點(diǎn)均成立。

必須搞清楚的是,k-d樹(shù)是一種空間劃分樹(shù),說(shuō)白了,就是把整個(gè)空間劃分為特定的幾個(gè)部分,然后在特定空間的部分內(nèi)進(jìn)行相關(guān)搜索操作。想像一個(gè)三維(多維有點(diǎn)為難你的想象力了)空間,kd樹(shù)按照一定的劃分規(guī)則把這個(gè)三維空間劃分了多個(gè)空間,如下圖所示:

首先,邊框?yàn)榧t色的豎直平面將整個(gè)空間劃分為兩部分,此兩部分又分別被邊框?yàn)榫G色的水平平面劃分為上下兩部分。最后此4個(gè)子空間又分別被邊框?yàn)樗{(lán)色的豎直平面分割為兩部分,變?yōu)?個(gè)子空間,此8個(gè)子空間即為葉子節(jié)點(diǎn)。

常規(guī)的k-d tree的構(gòu)建過(guò)程為:

對(duì)于構(gòu)建過(guò)程,有兩個(gè)優(yōu)化點(diǎn):

例子:采用常規(guī)的構(gòu)建方式,以二維平面點(diǎn)(x,y)的集合(2,3),(5,4),(9,6),(4,7),(8,1),(7,2) 為例結(jié)合下圖來(lái)說(shuō)明k-d tree的構(gòu)建過(guò)程:

如上算法所述,kd樹(shù)的構(gòu)建是一個(gè)遞歸過(guò)程,我們對(duì)左子空間和右子空間內(nèi)的數(shù)據(jù)重復(fù)根節(jié)點(diǎn)的過(guò)程就可以得到一級(jí)子節(jié)點(diǎn)(5,4)和(9,6),同時(shí)將空間和數(shù)據(jù)集進(jìn)一步細(xì)分,如此往復(fù)直到空間中只包含一個(gè)數(shù)據(jù)點(diǎn)。

如之前所述,kd樹(shù)中,kd代表k-dimension,每個(gè)節(jié)點(diǎn)即為一個(gè)k維的點(diǎn)。每個(gè)非葉節(jié)點(diǎn)可以想象為一個(gè)分割超平面,用垂直于坐標(biāo)軸的超平面將空間分為兩個(gè)部分,這樣遞歸的從根節(jié)點(diǎn)不停的劃分,直到?jīng)]有實(shí)例為止。經(jīng)典的構(gòu)造k-d tree的規(guī)則如下:

kd樹(shù)的檢索是KNN算法至關(guān)重要的一步,給定點(diǎn)p,查詢(xún)數(shù)據(jù)集中與其距離最近點(diǎn)的過(guò)程即為最近鄰搜索。

如在構(gòu)建好的k-d tree上搜索(3,5)的最近鄰時(shí),對(duì)二維空間的最近鄰搜索過(guò)程作分析。

首先從根節(jié)點(diǎn)(7,2)出發(fā),將當(dāng)前最近鄰設(shè)為(7,2),對(duì)該k-d tree作深度優(yōu)先遍歷。

以(3,5)為圓心,其到(7,2)的距離為半徑畫(huà)圓(多維空間為超球面),可以看出(8,1)右側(cè)的區(qū)域與該圓不相交,所以(8,1)的右子樹(shù)全部忽略。

接著走到(7,2)左子樹(shù)根節(jié)點(diǎn)(5,4),與原最近鄰對(duì)比距離后,更新當(dāng)前最近鄰為(5,4)。

以(3,5)為圓心,其到(5,4)的距離為半徑畫(huà)圓,發(fā)現(xiàn)(7,2)右側(cè)的區(qū)域與該圓不相交,忽略該側(cè)所有節(jié)點(diǎn),這樣(7,2)的整個(gè)右子樹(shù)被標(biāo)記為已忽略。

遍歷完(5,4)的左右葉子節(jié)點(diǎn),發(fā)現(xiàn)與當(dāng)前最優(yōu)距離相等,不更新最近鄰。所以(3,5)的最近鄰為(5,4)。

舉例:查詢(xún)點(diǎn)(2.1,3.1)

星號(hào)表示要查詢(xún)的點(diǎn)(2.1,3.1)。通過(guò)二叉搜索,順著搜索路徑很快就能找到最鄰近的近似點(diǎn),也就是葉子節(jié)點(diǎn)(2,3)。而找到的葉子節(jié)點(diǎn)并不一定就是最鄰近的,最鄰近肯定距離查詢(xún)點(diǎn)更近,應(yīng)該位于以查詢(xún)點(diǎn)為圓心且通過(guò)葉子節(jié)點(diǎn)的圓域內(nèi)。為了找到真正的最近鄰,還需要進(jìn)行相關(guān)的‘回溯'操作。也就是說(shuō),算法首先沿搜索路徑反向查找是否有距離查詢(xún)點(diǎn)更近的數(shù)據(jù)點(diǎn)。

舉例:查詢(xún)點(diǎn)(2,4.5)

一個(gè)復(fù)雜點(diǎn)了例子如查找點(diǎn)為(2,4.5),具體步驟依次如下:

上述兩次實(shí)例表明,當(dāng)查詢(xún)點(diǎn)的鄰域與分割超平面兩側(cè)空間交割時(shí),需要查找另一側(cè)子空間,導(dǎo)致檢索過(guò)程復(fù)雜,效率下降。

一般來(lái)講,最臨近搜索只需要檢測(cè)幾個(gè)葉子結(jié)點(diǎn)即可,如下圖所示: 

但是,如果當(dāng)實(shí)例點(diǎn)的分布比較糟糕時(shí),幾乎要遍歷所有的結(jié)點(diǎn),如下所示:

研究表明N個(gè)節(jié)點(diǎn)的K維k-d樹(shù)搜索過(guò)程時(shí)間復(fù)雜度為: 。

同時(shí),以上為了介紹方便,討論的是二維或三維情形。但在實(shí)際的應(yīng)用中,如SIFT特征矢量128維,SURF特征矢量64維,維度都比較大,直接利用k-d樹(shù)快速檢索(維數(shù)不超過(guò)20)的性能急劇下降,幾乎接近貪婪線(xiàn)性?huà)呙?。假設(shè)數(shù)據(jù)集的維數(shù)為D,一般來(lái)說(shuō)要求數(shù)據(jù)的規(guī)模N滿(mǎn)足N?2D,才能達(dá)到高效的搜索。

Sklearn中有KDTree的實(shí)現(xiàn),僅構(gòu)建了一個(gè)二維空間的k-d tree,然后對(duì)其作k近鄰搜索及指定半徑的范圍搜索。多維空間的檢索,調(diào)用方式與此例相差無(wú)多。

2 Kd樹(shù)的構(gòu)造與搜索

實(shí)現(xiàn)kNN算法時(shí),最簡(jiǎn)單的實(shí)現(xiàn)方法就是線(xiàn)性?huà)呙?,正如我們上一章?jié)內(nèi)容介紹的一樣- K近鄰算法 ,需要計(jì)算輸入實(shí)例與每一個(gè)訓(xùn)練樣本的距離。當(dāng)訓(xùn)練集很大時(shí),會(huì)非常耗時(shí)。

為了提高kNN搜索的效率,可以考慮使用特殊的結(jié)構(gòu)存儲(chǔ)訓(xùn)練數(shù)據(jù),以減少計(jì)算距離的次數(shù),KD-Tree就是其中的一種方法。

K維空間數(shù)據(jù)集

其中

隨機(jī)生成 13 個(gè)點(diǎn)作為我們的數(shù)據(jù)集

首先先沿 x 坐標(biāo)進(jìn)行切分,我們選出 x 坐標(biāo)的中位點(diǎn),獲取最根部節(jié)點(diǎn)的坐標(biāo)

并且按照該點(diǎn)的x坐標(biāo)將空間進(jìn)行切分,所有 x 坐標(biāo)小于 6.27 的數(shù)據(jù)用于構(gòu)建左分支,x坐標(biāo)大于 6.27 的點(diǎn)用于構(gòu)建右分支。

在下一步中 ,對(duì)應(yīng) y 軸,左右兩邊再按照 y 軸的排序進(jìn)行切分,中位點(diǎn)記載于左右枝的節(jié)點(diǎn)。得到下面的樹(shù),左邊的 x 是指這該層的節(jié)點(diǎn)都是沿 x 軸進(jìn)行分割的。

空間的切分如下

下一步中 ,對(duì)應(yīng) x 軸,所以下面再按照 x 坐標(biāo)進(jìn)行排序和切分,有

最后只剩下了葉子結(jié)點(diǎn),就此完成了 kd 樹(shù)的構(gòu)造。

輸入:已構(gòu)造的kd樹(shù),目標(biāo)點(diǎn)x

輸出:x的k個(gè)最近鄰集合L

KD-Tree的平均時(shí)間復(fù)雜度為 ,N為訓(xùn)練樣本的數(shù)量。

KD-Tree試用于訓(xùn)練樣本數(shù)遠(yuǎn)大于空間維度的k近鄰搜索。當(dāng)空間維數(shù)接近訓(xùn)練樣本數(shù)時(shí),他的效率會(huì)迅速下降,幾乎接近線(xiàn)性?huà)呙琛?/p>

設(shè)我們想查詢(xún)的點(diǎn)為 p=(?1,?5),設(shè)距離函數(shù)是普通的距離,我們想找距離目標(biāo)點(diǎn)最近的 k=3 個(gè)點(diǎn)。如下:

首先我們按照構(gòu)造好的KD-Tree,從根結(jié)點(diǎn)開(kāi)始查找

和這個(gè)節(jié)點(diǎn)的 x 軸比較一下,p 的 x 軸更小。因此我們向左枝進(jìn)行搜索:

接下來(lái)需要對(duì)比 y 軸

p 的 y 值更小,因此向左枝進(jìn)行搜索:

這個(gè)節(jié)點(diǎn)只有一個(gè)子枝,就不需要對(duì)比了。由此找到了葉子節(jié)點(diǎn) (?4.6,?10.55)。

在二維圖上是藍(lán)色的點(diǎn)

此時(shí)我們要執(zhí)行第二步,將當(dāng)前結(jié)點(diǎn)插入到集合L中,并記錄下 L=[(?4.6,?10.55)]。訪(fǎng)問(wèn)過(guò)的節(jié)點(diǎn)就在二叉樹(shù)上顯示為被劃掉的好了。

然后執(zhí)行第三步,不是最頂端節(jié)點(diǎn)。我回退。上面的結(jié)點(diǎn)是 (?6.88,?5.4)。

執(zhí)行 3a,因?yàn)槲覀冇涗浵碌狞c(diǎn)只有一個(gè),小于 k=3,所以也將當(dāng)前節(jié)點(diǎn)記錄下,插入到集合L中,有 L=[(?4.6,?10.55),(?6.88,?5.4)].。 因?yàn)楫?dāng)前節(jié)點(diǎn)的左枝是空的,所以直接跳過(guò),繼續(xù)回退,判斷不是頂部根節(jié)點(diǎn)

由于還是不夠三個(gè)點(diǎn),于是將當(dāng)前點(diǎn)也插入到集合L中,有 L=[(?4.6,?10.55),(?6.88,?5.4),(1.24,?2.86)]。

此時(shí)發(fā)現(xiàn),當(dāng)前節(jié)點(diǎn)有其他的分枝,執(zhí)行3b,計(jì)算得出 p 點(diǎn)和 L 中的三個(gè)點(diǎn)的距離分別是 6.62, 5.89, 3.10,但是 p 和當(dāng)前節(jié)點(diǎn)的分割線(xiàn)的距離只有 2.14,小于與 L 的最大距離:

因此,在分割線(xiàn)的另一端可能有更近的點(diǎn)。于是我們?cè)诋?dāng)前結(jié)點(diǎn)的另一個(gè)分枝從頭執(zhí)行步驟1。好,我們?cè)诩t線(xiàn)這里:

此時(shí)處于x軸切分,因此要用 p 和這個(gè)節(jié)點(diǎn)比較 x 坐標(biāo):

p 的 x 坐標(biāo)更大,因此探索右枝 (1.75,12.26),并且發(fā)現(xiàn)右枝已經(jīng)是最底部節(jié)點(diǎn),執(zhí)行步驟2與3a。

經(jīng)計(jì)算,(1.75,12.26) 與 p 的距離是 17.48,要大于 p 與 L 的距離,因此我們不將其放入記錄中。

然后 回退,判斷出不是頂端節(jié)點(diǎn),往上爬。

執(zhí)行3a,這個(gè)節(jié)點(diǎn)與 p 的距離是 4.91,要小于 p 與 L 的最大距離 6.62。

因此,我們用這個(gè)新的節(jié)點(diǎn)替代 L 中離 p 最遠(yuǎn)的 (?4.6,?10.55)。

然后3b,我們比對(duì) p 和當(dāng)前節(jié)點(diǎn)的分割線(xiàn)的距離

這個(gè)距離小于 L 與 p 的最大距離,因此我們要到當(dāng)前節(jié)點(diǎn)的另一個(gè)枝執(zhí)行步驟1。當(dāng)然,那個(gè)枝只有一個(gè)點(diǎn)。

計(jì)算距離發(fā)現(xiàn)這個(gè)點(diǎn)離 p 比 L 更遠(yuǎn),因此不進(jìn)行替代。

然后回退,不是根結(jié)點(diǎn),我們向上爬

這個(gè)是已經(jīng)訪(fǎng)問(wèn)過(guò)的了,所以再向上爬

再爬

此時(shí)到頂點(diǎn)了 。所以完了嗎?當(dāng)然不,還要執(zhí)行3b呢。現(xiàn)在是步驟1的回合。

我們進(jìn)行計(jì)算比對(duì)發(fā)現(xiàn)頂端節(jié)點(diǎn)與p的距離比L還要更遠(yuǎn),因此不進(jìn)行更新。

然后計(jì)算 p 和分割線(xiàn)的距離發(fā)現(xiàn)也是更遠(yuǎn)。

因此也不需要檢查另一個(gè)分枝。

判斷當(dāng)前節(jié)點(diǎn)是頂點(diǎn),因此計(jì)算完成!輸出距離 p 最近的三個(gè)樣本是 L=[(?6.88,?5.4),(1.24,?2.86),(?2.96,?2.5)]。

聲明:此文章為本人學(xué)習(xí)筆記,參考于:


本文名稱(chēng):kd樹(shù)構(gòu)造代碼java,kd樹(shù)索引
網(wǎng)頁(yè)地址:http://weahome.cn/article/hegghh.html

其他資訊

在線(xiàn)咨詢(xún)

微信咨詢(xún)

電話(huà)咨詢(xún)

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部