0

我正在拼命寻找一种解决方案来创建一个漂亮的二叉树图。不完整的节点具有可区分的边缘(如果有的话)至关重要。

我无法使用 .dot 产生所需的结果,因为我不知道如何对节点进行排序。我不介意,将文件导入 yEd 或其他编辑器。但是,我希望能够用很少的语法非常轻松地生成数据。

我的目标是一种工具,它可以从极简数据(例如(A(B1 C1 C2)B2))生成例如.graphml 格式,其中A 是根标签,B1 是根的左孩子和另外两个孩子。与 .dot 或 .tgf 类似的复杂性当然是可以容忍的,但我想避免自己编写编译器来生成 .graphml。

任何想法表示赞赏。

马库斯·R。

4

1 回答 1

1

您提供的数据或多或少是一个s-expression。鉴于这是您要摄取的格式,pyparsing(一个 Python 模块)有一个s-expression parser

您还需要一个图形库。我的大部分工作都使用networkx 。使用 pyparsing s-expression 解析器和 networkx,以下代码获取数据并创建树作为有向图:

import networkx as nx

def build(g, X):
    if isinstance(X, list):
        parent = X[0]
        g.add_node(parent)
        for branch in X[1:]:
            child = build(g, branch)
            g.add_edge(parent, child)

        return parent

    if isinstance(X, basestring):
        g.add_node(X)
        return X

#-- The sexp parser is constructed by the code example at...
#-- http://http://pyparsing.wikispaces.com/file/view/sexpParser.py
sexpr = sexp.parseString("(A (B1 C1 C2) B2)", parseAll = True)

#-- Get the parsing results as a list of component lists.
nested = sexpr.asList( )

#-- Construct an empty digraph.
dig = nx.DiGraph( )

#-- build the tree
for component in nested:
    build(dig, component)

#-- Write out the tree as a graphml file.
nx.write_graphml(dig, 'tree.graphml', prettyprint = True)

为了测试这一点,我还将树编写为 .dot 文件并使用 graphviz 创建以下图像:

(树的graphviz输出)

networkx 是一个很好的图形库,如果需要,您可以编写额外的代码遍历树以使用额外的元数据标记边缘或节点。

于 2012-05-09T18:44:08.040 回答