【问题标题】:HierarchicalGraphMachine hiding nested statesHierarchicalGraphMachine 隐藏嵌套状态
【发布时间】:2021-05-20 01:59:30
【问题描述】:

我一直在尝试使用 HierarchicalGraphMachine 类来帮助在我编辑机器结构时对其进行可视化。

from transitions.extensions import HierarchicalGraphMachine as Machine

count_states = ['1', '2', '3', 'done']
count_trans = [
    ['increase', '1', '2'],
    ['increase', '2', '3'],
    ['decrease', '3', '2'],
    ['decrease', '2', '1'],
    ['done', '3', 'done'],
    ['reset', '*', '1']
]
counter = Machine(states=count_states, transitions=count_trans, initial='1')

states = ['waiting', 'collecting', {'name': 'counting', 'children': counter, 'initial': '1'}]

transitions = [
    ['collect', '*', 'collecting'],
    ['wait', '*', 'waiting'],
    ['count', 'collecting', 'counting']
]

collector = Machine(states=states, transitions=transitions, initial='waiting')
collector.get_graph(show_roi=False).draw('count1.png', prog='dot')

这会生成预期的图形,完整地显示父状态和嵌套状态(我尚未获得上传图形的授权)。 有没有办法在不扩展嵌套状态的情况下生成完整的父状态机图形?例如将嵌套状态减少到一个空框。

我试过“show_roi=True”,但这只会显示当前的转换事件,并删除所有其他状态。

【问题讨论】:

    标签: pytransitions


    【解决方案1】:

    根据您是使用pygraphviz(0.8.8 及之前的默认版本)还是graphviz 后端,get_graph 可能会返回pygraphiv.AGraph 对象或自定义transitions.GraphAGraph 更容易操作,而第二个基本上是点中的纯图形符号。但是,您可以根据需要对两者进行操作。例如,您可以过滤 AGraph 中的边和节点并重建它的“平面”版本:

    # your code here ...
    
    collector.collect()
    
    graph = collector.get_graph()
    
    # iterate over all edges; We know that parent and child states are connected
    # with an underscore. We just collect the root element of each source
    # and target element of each edge. Furthermore, we collect the edge color,
    # and the label which is stored either in 'label', 'taillabel' or 'headlabel' 
    new_edges = [(edge[0].split('_')[0],
                  edge[1].split('_')[0],
                  edge.attr['color'],
                  edge.attr['label']
                  or edge.attr['taillabel']
                  or edge.attr['headlabel']) for edge in graph.edges()]
    
    # States with children are noted as subgraphs. We collect their name and their
    # current color.
    new_nodes = [(sgraph.graph_attr['label'], sgraph.graph_attr['color'])
                 for sgraph in graph.subgraphs()]
    # We add all states that have no children and also do not contain an
    # underscore in their name. An underscore would suggest that this node/state
    # is a child/substate.
    new_nodes += [(node.name, node.attr['color'])
                  for node in graph.nodes() if '_' not in node.name]
    
    # remove everything from the graph obeject
    graph.clear()
    
    # and add nodes and edges again
    for name, color in new_nodes:
        graph.add_node(name, color=color)
    
    for start, target, color, label in new_edges:
        if label:
            graph.add_edge(start, target, color=color, label=label)
    
    graph.draw('agraph.png', prog='dot')
    

    结果如下图:

    您会看到,我还收集了边缘和节点颜色以可视化最后的过渡,但 graph.clear() 删除了所有“默认”样式属性。 它们也可以被复制和恢复,或者我们只能删除节点、边和子图。这取决于你愿意与 (py)graphviz 混淆多少。

    【讨论】:

      猜你喜欢
      • 2011-04-29
      • 1970-01-01
      • 2014-10-30
      • 2014-05-03
      • 2017-03-20
      • 2013-11-12
      相关资源
      最近更新 更多