KD树算法

学习了KD树算法,用来进行最近邻匹配,其伪代码如下:

# KD树算法的伪代码

# 节点结构:
# node{
#     node_data   # 节点数据
#     node_left   # 左子树
#     node_right  # 右子树
#     node_parrent# 父节点
#     node_s      # 维度序号
# }

# 建立KD树:
# 输入:点集list
# 输出:KD树根节点
def build_tree(list):
    if list is None:
        return None
    # 计算所有点在每一维的方差并排序,从方差最大的维度vi维开始建树
    # 提取点集在vi维的中间点,该点为根节点tree_node
    for point in other_points:
        if point[vi] < tree_node[vi]:
            left_points.append(point)
        else:
            right_points.append(point)
    build_tree(left_points)
    # 设置点集 left_points 根节点的父节点为 tree_node
    build_tree(right_points)
    # 设置点集 right_points 根节点的父节点为 tree_node

# 查找最近邻:
# 输入:KD树根节点kd, 目标点target
# 输出:与 target 最近点 min_node, 最近距离 min_dis
def find_nn(kd, target):
    if kd is None:
        return 'kdTree is None'
    while kd is not None:       # 步骤1:二叉树搜索
        search_path.append(kd)  # search_path 是一个堆栈,存储节点的搜索路径
        min_node = kd
        if target[s] < kd[s]:
            kd = kd.left
        else:
            kd = kd.right
    min_dis = distans(kd.data, target)

    while kd is not None:       # 步骤2:回溯
        back_point = search_path.pop()
        if distans(back_point[s], target[s]) < min_dis: # 如果圆与超平面相交,需要检索另一个子树
            if target[s] < back_point[s]:   # 如果当前为左子树,则检索右子树
                kd = back_point.right
            else:                   # 如果当前为右子树,则检索左子树
                kd = back_point.left
            search_path.push(kd)    # 节点压入堆栈

        if distans(kd.data, target) < min_dis:   # 如果左子树或右子树存在距离更小的点,更新最近距离和最近点
            min_dis = distans(kd.data, target)
            min_node = kd
    return min_node.data, min_dis

参考:

http://acm.hdu.edu.cn/showproblem.php?pid=2966

https://blog.csdn.net/v_july_v/article/details/8203674

https://blog.csdn.net/acdreamers/article/details/44664645

https://www.cnblogs.com/eyeszjwang/articles/2429382.html

http://blog.51cto.com/underthehood/687160

https://blog.csdn.net/lhanchao/article/details/52535694


你可能感兴趣的:(笔记)