You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何我的K-dimensional树渲染异常?Python anytree技术问询

问题描述

使用Python的anytree包创建并展示K-dimensional树,但树无法正常渲染。预期[4 7]与[17 16]节点处于同一层级,但实际渲染结果不符合预期。

节点类源码

import numpy as np
from anytree import NodeMixin


class KdData:
    def __init__(self) -> None:
        self.key = None


class KdNode(KdData, NodeMixin):
    def __init__(self, parent=None, children=None, axis: int = 0) -> None:
        super().__init__()
        self.axis = axis
        self.parent = parent
        if children:
            self.children = children

    def set_key(self, key):
        self.key = np.array(key)
        if self.key is not None:
            self.children = [
                KdNode(axis=(self.axis + 1) % self.key.shape[0]),
                KdNode(axis=(self.axis + 1) % self.key.shape[0])
            ]

    def get_left_node(self):
        if self.key is None:
            return None
        return self.children[0]

    def get_right_node(self):
        if self.key is None:
            return None
        return self.children[1]

    def insert(self, key):
        if self.key is None:
            self.set_key(key)
        elif key[self.axis] < self.key[self.axis]:
            self.get_left_node().insert(key)
        else:
            self.get_right_node().insert(key)

    # Other functions are omitted because it's not relavant to the question

树创建代码

tree = KdNode()
tree.set_key(np.array([5,6]))
tree.insert([4,7])
tree.insert([17,16])
tree.insert([7,8])
tree.insert([1,4])
tree.insert([9,13])

导出器代码

def node_attribute(node):
    att = ""
    att += "shape=plaintext"
    return att

def edge_att(source, target):
    att = ""
    if target.key is None:
        att += "style=invis"
    return att

from anytree.exporter.dotexporter import DotExporter, UniqueDotExporter

dot_obj = UniqueDotExporter(tree,
    nodenamefunc=lambda node: node.key if node.key is not None else "",
    nodeattrfunc=lambda node: node_attribute(node),
    edgeattrfunc=lambda src, tgt: edge_att(src, tgt))

原因与解决方案

核心问题

  1. 节点名格式错误:numpy数组的字符串表示(如[5 6])包含空格和方括号,在Dot语言中这类带特殊字符的节点名必须用引号包裹,否则会被解析器错误识别,导致树结构渲染混乱。
  2. 空节点未完全隐藏:当前仅隐藏了指向空节点的边,但空节点本身仍会显示为空白节点,干扰树的视觉层级判断。

修改后的导出器代码

def node_attribute(node):
    att = "shape=plaintext"
    # 完全隐藏空节点
    if node.key is None:
        att += ", style=invis"
    return att

def edge_att(source, target):
    att = ""
    if target.key is None:
        att += "style=invis"
    return att

from anytree.exporter.dotexporter import UniqueDotExporter

dot_obj = UniqueDotExporter(tree,
    # 给节点名添加引号,避免特殊字符解析错误
    nodenamefunc=lambda node: f'"{node.key}"' if node.key is not None else '""',
    nodeattrfunc=lambda node: node_attribute(node),
    edgeattrfunc=lambda src, tgt: edge_att(src, tgt))

验证

修改后,Dot解析器能正确识别每个节点的名称,空节点也会被完全隐藏,渲染出的树结构中[4 7]与[17 16]会处于同一层级,符合Kd树的插入逻辑。


内容的提问来源于stack exchange,提问作者Nguyễn Tiến Đạt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 02:50:58