在上一節中我們講解了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搜尋的效率,可以考慮使用...