获取可以包含重复节点的嵌套列表元素的DOT graphviz

时间:2016-08-08 20:53:03

标签: python graphviz decision-tree dot pygraphviz

我有一组嵌套列表,可以分为三组:

  • A(子元素是分离的,线条颜色为绿色),例如

    listA = {
    ‘a1’: ['b1', 'a2'],
    ‘a2’: ['c1', 'c2']
     }
    
  • B(子元素有序连接,线条颜色ORANGE),例如。

    listB = {
    ‘b1’: ['c4', 'c5', 'c7'],
    ‘b2’:['c3', 'b1']
     }
    
  • C(最终元素 - 叶节点)

函数combinations遍历嵌套列表并返回所有可能的组合(最后只包含C类元素,因此叶子节点)。函数write_nodes有助于用彩色线条编写节点。调用write_nodes('task', inputlist)用于创建init节点:

def write_nodes(node, subnotes):
    for k in subnotes:
        if node in type_a:
            text_file.write("{} -> {} [color=\"green\"]\n".format(node, k)) 
        elif (node in type_b) or (node is 'task'):
            text_file.write("{} -> {} [color=\"orange\"]\n".format(node, k))

write_nodes('task', inputlist)

def combinations(actions):
    if len(actions)==1:
        action= actions[0]
        if action not in type_c:
            root = action
        try:
            actions= type_a[action]
            write_nodes(root, actions)
        except KeyError:
            try:
                actions= type_b[action]
                write_nodes(root, actions)
            except KeyError:
                #action is of type C, the only possible combination is itself
                yield actions
            else:
                #action is of type B (conjunction), combine all the actions
                for combination in combinations(actions):
                    yield combination
        else:
            #action is of type A (disjunction), generate combinations for each action
            for action in actions:
                for combination in combinations([action]):
                    yield combination
    else:
        #generate combinations for the first action in the list
        #and combine them with the combinations for the rest of the list
        action= actions[0]
        for combination in combinations(actions[1:]):
            for combo in combinations([action]):
                yield combo + combination

示例输入(有序连接):

['a1', 'b2', 'c6']

示例结果:

['c4', 'c5', 'c7', 'c3', 'c4', 'c5', 'c7', 'c6']
['c1', 'c3', 'c4', 'c5', 'c7', 'c6']
['c2', 'c3', 'c4', 'c5', 'c7', 'c6']

我从代码中得到的结果: enter image description here 相应的点文件:

task -> a1 [color="orange"]
task -> b2 [color="orange"]
task -> c6 [color="orange"]
b2 -> c3 [color="orange"]
b2 -> b1 [color="orange"]
b1 -> c4 [color="orange"]
b1 -> c5 [color="orange"]
b1 -> c7 [color="orange"]
a1 -> b1 [color="green"]
a1 -> a2 [color="green"]
b1 -> c4 [color="orange"]
b1 -> c5 [color="orange"]
b1 -> c7 [color="orange"]
a2 -> c1 [color="green"]
a2 -> c2 [color="green"]

我想要的结果(颜色不是先前的颜色): enter image description here

问题:

如何处理这个事实,有一些重复的节点可以获得所提到的结果?

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

重复节点问题

要避免重复节点问题,您应该使用唯一名称命名每个节点,并使用label作为显示的名称。例如更改:

b2 -> b1 [color="orange"]
b1 -> c4 [color="orange"]
b1 -> c5 [color="orange"]
b1 -> c7 [color="orange"]
a1 -> b1 [color="green"]
b1 -> c4 [color="orange"]
b1 -> c5 [color="orange"]
b1 -> c7 [color="orange"]

为:

b21 [label="b2"]
b11 [label="b1"]
b21 -> b11 [color="orange"]
c41 [label="c4"]
b11 -> c41 [color="orange"]
c51 [label="c5"]
b11 -> c51 [color="orange"]
c71 [label="c7"]
b11 -> c71 [color="orange"]
a11 [label="a2"]
b12 [label="b1"]
a11 -> b12 [color="green"]
c42 [label="c4"]
b12 -> c42 [color="orange"]
c52 [label="c5"]
b12 -> c52 [color="orange"]
c72 [label="c7"]
b12 -> c72 [color="orange"]

哪种产品: res

避免try/except流量

最好使用if/else而不是try/except来进行正常的程序流程。例如,而不是:

    try:
        actions= type_a[action]
        write_nodes(root, actions)
    except KeyError:
        #do whatever you do

使用:

    actions = type_a.get(action, None) #if the key doesn't exists assign None
    if actions:
        write_nodes(root, actions)
    else:
        #do whatever you do

Graphviz python包

您可以使用graphviz python package而不是自己编写点文件。