KD樹 BBF KNN使用C 實現(2)

2021-06-17 19:07:08 字數 3337 閱讀 4093

在上一節中我們講解了kd的構造過程,這裡我們主要講解的kd的搜尋過程,如何查詢距離目標點最近的點。

我們先把kd樹的最鄰近搜尋(knn)的**貼上出來:

private node kdtreefindnearest(node tree, train target)

else

searchnode = searchnode.righnode;

}else if (searchnode.split == 1)

else

searchnode = searchnode.righnode;

}else

else

searchnode = searchnode.righnode;}}

#endregion

nearest = searchpath[searchpath.count - 1]; //獲取搜尋路徑最後乙個節點

searchpath.remove(nearest); //從搜尋路徑中刪除假定的最近鄰節點

//計算兩個節點之間的距離

dist = this.distance(nearest.point, target);

#region 回溯路徑搜尋

node backnode;

int split = -1;

while (searchpath.count > 0)

}else

//確定是否進入子空間搜尋

float distmp = math.abs(target.positionx - backnode.point.positionx);

if (distmp < dist)

else

searchnode = backnode.righnode;

searchpath.add(searchnode); //新增搜尋節點}}

else if (split == 1)

//確定是否進入子空間搜尋

float distmp = math.abs(target.positiony - backnode.point.positiony);

if (distmp < dist)

else

searchnode = backnode.righnode;

searchpath.add(searchnode); //新增搜尋節點}}

else

//確定是否進入子空間搜尋

float distmp = math.abs(target.positionz - backnode.point.positionz);

if (distmp < dist)

else

searchnode = backnode.righnode;

searchpath.add(searchnode); //新增搜尋節點}}

}searchpath.remove(backnode);

}#endregion

return nearest; //返回最近鄰節點

}

下面我們講解一下搜尋過程。

首先,我們從根節點開始搜尋,一直搜尋到目標點所在區域的葉子節點,同時假定葉子節點時距離目標點最近的節點,計算他們之間的歐幾里德距離,並且假定這個距離值最近的距離。即:

double dist = double.maxvalue; //最近鄰和目標點之間的距離

node nearest = null; //最近鄰節點

node searchnode = tree; //根節點

listsearchpath = new list(); //搜尋路徑

#region 檢索搜尋路徑

while (searchnode != null)

else

searchnode = searchnode.righnode;

}else if (searchnode.split == 1)

else

searchnode = searchnode.righnode;

}else

else

searchnode = searchnode.righnode;}}

#endregion

nearest = searchpath[searchpath.count - 1]; //獲取搜尋路徑最後乙個節點

searchpath.remove(nearest); //從搜尋路徑中刪除假定的最近鄰節點

//計算兩個節點之間的距離

dist = this.distance(nearest.point, target);

其次,當搜尋到葉子節點的時候,搜尋路徑已經確定,然後我們需要進行回溯查詢,一直到搜尋路徑為空的時候,那麼就結束搜尋,返回搜尋到的最近鄰節點。當然在回溯查詢的過程中,我們也是搜尋到子樹的葉子節點問題。

#region 回溯路徑搜尋

node backnode;

int split = -1;

while (searchpath.count > 0)

}else

//確定是否進入子空間搜尋

float distmp = math.abs(target.positionx - backnode.point.positionx);

if (distmp < dist)

else

searchnode = backnode.righnode;

searchpath.add(searchnode); //新增搜尋節點}}

else if (split == 1)

//確定是否進入子空間搜尋

float distmp = math.abs(target.positiony - backnode.point.positiony);

if (distmp < dist)

else

searchnode = backnode.righnode;

searchpath.add(searchnode); //新增搜尋節點}}

else

//確定是否進入子空間搜尋

float distmp = math.abs(target.positionz - backnode.point.positionz);

if (distmp < dist)

else

searchnode = backnode.righnode;

searchpath.add(searchnode); //新增搜尋節點}}

}searchpath.remove(backnode);

}#endregion

KD樹的C 實現

kd樹 k dimension tree 是一種對k維空間中的例項點進行儲存以便對其進行快速檢索的樹形資料結構。kd樹是是一種二叉樹,表示對k維空間的乙個劃分,構造kd樹相當於不斷地用垂直於座標軸的超平面將k維空間切分,構成一系列的k維超矩形區域。kd樹的每個結點對應於乙個k維超矩形區域。利用kd樹...

KNN演算法的KD樹C 實現

kd樹本質上是一種二叉樹,它擁有具備特定排列順序的 節點以便查詢資料,即在二叉排序樹之中,某個 節點左子樹的值均小於 節點的值,而右側均大於 節點的值,如果用中序遍歷這棵樹,它的列印順序將是從小到大遞增的順序。當然剩下的科普就不說了,這也是在pcl庫當中,最常用的輪子之一,處理點雲速度非常快。另外,...

KNN的實現 KD樹

實現knn時,主要考慮的問題是如何對訓練資料進行快速近鄰搜尋.這點在特徵空間的維數大及訓練資料容量大時尤其必要.knn最簡單的實現方法是線性掃瞄 linear scan 這時要計算輸入例項與每乙個訓練例項的距離.當訓練集很大時,計算非常耗時,這種方法是不可行的.為了提高knn搜尋的效率,可以考慮使用...