一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - C# - C#通過KD樹進行距離最近點的查找

C#通過KD樹進行距離最近點的查找

2022-01-22 21:06帆帆帆 C#

這篇文章主要為大家詳細介紹了C#通過KD樹進行距離最近點的查找,具有一定的參考價值,感興趣的小伙伴們可以參考一下

本文首先介紹Kd-Tree的構造方法,然后介紹Kd-Tree的搜索流程及代碼實現,最后給出本人利用C#語言實現的二維KD樹代碼。這也是我自己動手實現的第一個樹形的數據結構。理解上難免會有偏差,敬請各位多多斧正。

1. KD樹介紹

Kd-Tree(KD樹),即K-dimensional tree,是一種高維索引樹形數據結構,常用于在大規模的高維數據空間進行最鄰近查找和近似最鄰近查找。我實現的KD樹是二維的Kd - tree。目的是在點集中尋找最近點。參考資料是Kd-Tree的百度百科。并且根據百度百科的邏輯組織了代碼。

2. KD樹的數學解釋

3. KD樹的構造方法

這里是用的二維點集進行構造Kd-tree。三維的與此類似。
樹中每個節點的數據類型:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class KDTreeNode
  {
    /// <summary>
    /// 分裂點
    /// </summary>
    public Point DivisionPoint { get; set; }
 
    /// <summary>
    /// 分裂類型
    /// </summary>
    public EnumDivisionType DivisionType { get; set; }
 
    /// <summary>
    /// 左子節點
    /// </summary>
    public KDTreeNode LeftChild { get; set; }
 
    /// <summary>
    /// 右子節點
    /// </summary>
    public KDTreeNode RightChild { get; set; }
  }

3.1 KD樹構造邏輯流程

  • 將所有的點放入集合a中
  • 對集合所有點的X坐標求得方差xv,Y坐標求得方差yv
  • 如果xv > yv,則對集合a根據X坐標進行排序。如果 yv > xv,則對集合a根據y坐標進行排序。
  • 得到排序后a集合的中位數m。則以m為斷點,將[0,m-2]索引的點放到a1集合中。將[m,a.count]索引的點放到a2的集合中(m點的索引為m-1)。
  • 構建節點,節點的值為a[m-1],如果操作集合中節點的個數大于1,則左節點對[0,m-2]重復2-5步,右節點為對[m,a.count]重復2-5步;反之,則該節點為葉子節點。

3.2 代碼實現

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
private KDTreeNode CreateTreeNode(List<Point> pointList)
{
  if (pointList.Count > 0)
  {
    // 計算方差
    double xObtainVariance = ObtainVariance(CreateXList(pointList));
    double yObtainVariance = ObtainVariance(CreateYList(pointList));
 
    // 根據方差確定分裂維度
    EnumDivisionType divisionType = SortListByXOrYVariances(xObtainVariance,    yObtainVariance, ref pointList);
 
    // 獲得中位數
    Point medianPoint = ObtainMedian(pointList);
    int medianIndex = pointList.Count / 2;
 
    // 構建節點
    KDTreeNode treeNode = new KDTreeNode()
    {
      DivisionPoint = medianPoint,
      DivisionType = divisionType,
      LeftChild = CreateTreeNode(pointList.Take(medianIndex).ToList()),
      RightChild = CreateTreeNode(pointList.Skip(medianIndex + 1).ToList())
    };
    return treeNode;
  }
  else
  {
    return null;
  }
}

4. KD樹搜索方法

Kd-Tree的總體搜索流程先根據普通的查找找到一個最近的葉子節點。但是這個葉子節點不一定是最近的點。再進行回溯的操作找到最近點。

4.1 KD樹搜索邏輯流程

  • 對于根據點集構建的樹t,以及查找點p.將根節點作為節點t進行如下的操作
  • 如果t為葉子節點。則得到最近點n的值為t的分裂點的值,跳到第5步;如果t不是葉子節點,進行第3步
  • 則確定t的分裂方式,如果是按照x軸進行分裂,則用p的x值與節點的分裂點的x值進行比較,反之則進行Y坐標的比較
  • 如果p的比較值小于t的比較值,則將t指定為t的左孩子節點。反之將t指定為t的右孩子節點,執行第2步
  • 定義檢索點m,將m設置為n
  • 計算m與p的距離d1,n與m的距離d2。
  • 如果d1 >= d2且有父節點,則將m的父節點作為m的值執行5步,若沒有父節點,則得到真正的最近點TN; 如果d1 < d2就表示n點不是最近點,執行第8步
  • 若n有兄弟節點,則 n = n的兄弟節點;若n沒有兄弟節點,則 n = n的父節點。刪除原來的n節點。將m的值設置為新的n節點;執行第6步。

4.2 代碼實現

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
public Point FindNearest(Point searchPoint)
{
  // 按照查找方式尋找最近點
  Point nearestPoint = DFSSearch(this.rootNode, searchPoint);
  
  // 進行回溯
  return BacktrcakSearch(searchPoint, nearestPoint);
}
 
 
private Point DFSSearch(KDTreeNode node,Point searchPoint,bool pushStack = true)
{
  if(pushStack == true)
  {
    // 利用堆棧記錄查詢的路徑,由于樹節點中沒有記載父節點的原因
    backtrackStack.Push(node);
  }
  if (node.DivisionType == EnumDivisionType.X)
  {
    return DFSXsearch(node,searchPoint);
  }
  else
  {
    return DFSYsearch(node, searchPoint);
  }
}
 
private Point BacktrcakSearch(Point searchPoint,Point nearestPoint)
{
  // 如果記錄路徑的堆棧為空則表示已經回溯到根節點,則查到的最近點就是真正的最近點
  if (backtrackStack.IsEmpty())
  {
    return nearestPoint;
  }
  else
  {
    KDTreeNode trackNode = backtrackStack.Pop();
    
    // 分別求回溯點與最近點距查找點的距離
    double backtrackDistance = ObtainDistanFromTwoPoint(searchPoint,     trackNode.DivisionPoint);
    double nearestPointDistance = ObtainDistanFromTwoPoint(searchPoint, nearestPoint);
    
    if (backtrackDistance < nearestPointDistance)
    {
      // 深拷貝節點的目的是為了避免損壞樹
      KDTreeNode searchNode = new KDTreeNode()
      {
        DivisionPoint = trackNode.DivisionPoint,
        DivisionType = trackNode.DivisionType,
        LeftChild = trackNode.LeftChild,
        RightChild = trackNode.RightChild
      };
      nearestPoint = DFSBackTrackingSearch(searchNode, searchPoint);
   }
   // 遞歸到根節點
   return BacktrcakSearch(searchPoint, nearestPoint);
  }
}

5. 源碼交流

https://github.com/CreamMilk/C-Kd-Tree

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:http://www.cnblogs.com/MaFeng0213/archive/2017/09/26/7598886.html

延伸 · 閱讀

精彩推薦
  • C#Unity3D實現虛擬按鈕控制人物移動效果

    Unity3D實現虛擬按鈕控制人物移動效果

    這篇文章主要為大家詳細介紹了Unity3D實現虛擬按鈕控制人物移動效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一...

    shenqingyu060520232410972022-03-11
  • C#C#通過KD樹進行距離最近點的查找

    C#通過KD樹進行距離最近點的查找

    這篇文章主要為大家詳細介紹了C#通過KD樹進行距離最近點的查找,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    帆帆帆6112022-01-22
  • C#C# 實現對PPT文檔加密、解密及重置密碼的操作方法

    C# 實現對PPT文檔加密、解密及重置密碼的操作方法

    這篇文章主要介紹了C# 實現對PPT文檔加密、解密及重置密碼的操作方法,非常不錯,具有參考借鑒價值,需要的朋友可以參考下...

    E-iceblue5012022-02-12
  • C#C#裁剪,縮放,清晰度,水印處理操作示例

    C#裁剪,縮放,清晰度,水印處理操作示例

    這篇文章主要為大家詳細介紹了C#裁剪,縮放,清晰度,水印處理操作示例,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    吳 劍8332021-12-08
  • C#深入解析C#中的交錯數組與隱式類型的數組

    深入解析C#中的交錯數組與隱式類型的數組

    這篇文章主要介紹了深入解析C#中的交錯數組與隱式類型的數組,隱式類型的數組通常與匿名類型以及對象初始值設定項和集合初始值設定項一起使用,需要的...

    C#教程網6172021-11-09
  • C#C#實現XML文件讀取

    C#實現XML文件讀取

    這篇文章主要為大家詳細介紹了C#實現XML文件讀取的相關代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    Just_for_Myself6702022-02-22
  • C#C#設計模式之Visitor訪問者模式解決長隆歡樂世界問題實例

    C#設計模式之Visitor訪問者模式解決長隆歡樂世界問題實例

    這篇文章主要介紹了C#設計模式之Visitor訪問者模式解決長隆歡樂世界問題,簡單描述了訪問者模式的定義并結合具體實例形式分析了C#使用訪問者模式解決長...

    GhostRider9502022-01-21
  • C#WPF 自定義雷達圖開發實例教程

    WPF 自定義雷達圖開發實例教程

    這篇文章主要介紹了WPF 自定義雷達圖開發實例教程,本文介紹的非常詳細,具有參考借鑒價值,需要的朋友可以參考下...

    WinterFish13112021-12-06
主站蜘蛛池模板: 2021麻豆剧果冻传媒入口永久 | 免费看a片毛片 | 日韩一品在线播放视频一品免费 | 国产一级视频久久 | 日本无遮挡亲吻膜下面免费 | 亚欧视频在线观看 | 小辣椒精品福利视频导航 | 日产乱码卡1卡2卡三免费 | 国产一区二区在线观看视频 | 特黄特色一级aa毛片免费观看 | 国产一区二区免费福利片 | 日韩在线一区二区 | 精品一区二区三区免费视频 | 4438成人网| 大乳一级一区二区三区 | 高跟翘臀老师后进式视频 | 青青色在线观看 | 亚洲AVAV天堂AV在线网爱情 | 嗯啊好大好爽 | hd最新国产人妖ts视频 | 日本 视频 在线 | 国产精品久久久久a影院 | 日本人泡妞xxxxxx69 | 午夜在线观看免费完整直播网 | 国产日产精品久久久久快鸭 | 暖暖影院日本版 | 毛片免费视频观看 | 国产精品国产三级在线专区 | 日韩精品成人 | 特级淫片大乳女子高清视频 | jzz大全部 | 成人精品一区二区三区 | 日本人妖在线 | yjsp妖精视频在线观看免费 | 扒开腿开嫩苞 | 国产九九视频在线观看 | 欧美高清在线精品一区二区不卡 | 国产在线98福利播放视频免费 | 紧身裙女教师miad711在线 | 男人在线影院 | 日本男女视频 |