二維K D樹的構造及搜尋

2021-08-20 00:11:25 字數 3115 閱讀 6395

k-d(k-dimensional)樹在很多聚類演算法中都有應用,例如cure演算法。k-d樹的構造說明請參考j_outsider的博文,本文這裡只給出其構造**如下:

主程式**:

clc;

clear;

%讀取資料檔案,生成點矩陣

fileid = fopen('d:\matlabfile\k-d tree\test.txt');

c=textscan(fileid,'%f %f');

fclose(fileid);

%構造資料集,第一列為x軸,第二列為y軸

d=cat(2,c,c);

%儲存構造結果

kd_tree=createkd_tree(d);

%節點中包含有分割域的構造結果

kd_tree_dim=createkd_tree_dim(d);

%測試點

point=[5.1 4.1];

%搜尋鄰近點

r=kd_tree_search(kd_tree_dim,point);

樹的建構函式:createkd_tree

function kdtree=createkd_tree(d)

%計算兩個維度上的資料方差,然後比較兩個維度的方差,確定分割的維度,1代表x軸,2代表y軸

dimension=1;

if var(d(:,1))<=var(d(:,2))

dimension=2;

end%取出分割域

col=sort(d(:,dimension));

index=ceil(length(col)/2);

%確定**點

split=col(index,1);

%對資料分組

node=; %結點

left_data=; %左枝資料集

right_data=;%右枝資料集

for i=1:size(d,1)

if (d(i,dimension)split)

right_data=cat(1,right_data,d(i,:));

else

node=d(i,:);

end

end%向下遍歷左結點

if isempty(left_data)

left_node=;

elseif size(left_data,1)==1

left_node=left_data;

else

left_node=createkd_tree(left_data);

end%向下遍歷右結點

if isempty(right_data)

right_node=;

elseif size(right_data,1)==1

right_node=right_data;

else

right_node=createkd_tree(right_data);

end%將左右結點的結果加入樹中

kdtree=;

包含分割域的建構函式createkd_tree_dim

%結點中包含分割域,例如結點[4 5 1],最後一位1代表分割域,目的是為了後續搜尋k-d樹:

function kdtree=createkd_tree_dim(d)  %結點中包含分割域,如如[4 5 1],最後一位1代表分割域,目的是為了方便搜尋

%計算兩個維度上的資料方差,然後比較兩個維度的方差,確定分割的維度,1代表x軸,2代表y軸

dimension=1;

if var(d(:,1))<=var(d(:,2))

dimension=2;

end%取出分割域

col=sort(d(:,dimension));

index=ceil(length(col)/2);

%確定**點

split=col(index,1);

%對資料分組

node=; %結點

left_data=; %左枝資料集

right_data=;%右枝資料集

for i=1:size(d,1)

if (d(i,dimension)split)

right_data=cat(1,right_data,d(i,:));

else

node=d(i,:);

end

end%向下遍歷左結點

if isempty(left_data)

left_node=;

elseif size(left_data,1)==1

left_node=left_data;

else

left_node=createkd_tree_dim(left_data);

end%向下遍歷右結點

if isempty(right_data)

right_node=;

elseif size(right_data,1)==1

right_node=right_data;

else

right_node=createkd_tree_dim(right_data);

end%增加分割域

node=cat(2,node,dimension);

%將左右結點的結果加入樹中

kdtree=;

鄰近點搜尋函式 kd_tree_search:

%針對二維資料的搜尋近鄰點,所構造的樹需要具有分割域

function nearest=kd_tree_search(kdtree,point)

%取出結點

node=kdtree;

%判定從左右枝搜尋,預設為從左枝

leaf=kdtree;

%判斷是分割域,1為x軸,2為y軸

if node(1,3)==1

if node(1,1)測試資料如下,請讀者賦值儲存為txt:

2 35 49 6

4 78 1

7 2

kd樹的構造與搜尋

根據knn每次需要 乙個點時,我們都需要計算訓練資料集裡每個點到這個點的距離,然後選出距離最近的k個點進行投票。當資料集很大時,這個計算成本非常高,針對n個樣本,d個特徵的資料集,其演算法複雜度為o dn2 kd樹 為了避免每次都重新計算一遍距離,演算法會把距離資訊儲存在一棵樹裡,這樣在計算之前從樹...

搜尋二維矩陣

寫出乙個高效的演算法來搜尋 m n矩陣中的值。這個矩陣具有以下特性 每行中的整數從左到右是排序的。每行的第乙個數大於上一行的最後乙個整數。樣例 考慮下列矩陣 1,3,5,7 10,11,16,20 23,30,34,50 給出 target 3,返回 true 思路一 最容易想到的一種解法就是兩層f...

搜尋二維矩陣

寫出乙個高效的演算法來搜尋 m n矩陣中的值。這個矩陣具有以下特性 樣例 考慮下列矩陣 1,3,5,7 10,11,16,20 23,30,34,50 給出target 3,返回true 解題思路 可以把這個矩陣,看成是乙個大的一維陣列,1,3,5,7,10,11,16,20,23,34,50。然後...