Python 转换:如何将 FSM 的所有可能转换映射到图形
Python Transitions: how to map all possible transitions of an FSM to a graph
我无法在我的 Windows 10 系统上安装 pygraphviz,因此作为解决方法,我尝试将 FSM 的状态和转换存储在单独的图形中。例如:
from transitions import Machine
from graphviz import Digraph
class Matter(object):
pass
# The states
states=['hungry', 'satisfied', 'full', 'sick']
# And some transitions between states.
transitions = [
{ 'trigger': 'eat', 'source': 'hungry', 'dest': 'satisfied' },
{ 'trigger': 'eat', 'source': 'satisfied', 'dest': 'full' },
{ 'trigger': 'eat', 'source': 'full', 'dest': 'sick' },
{ 'trigger': 'rest', 'source': ['satisfied', 'full', 'sick'], 'dest':
'hungry' }]
# Initialize
machine = Matter()
fsm = Machine(machine, states=states, transitions=transitions, initial=states[0])
dot = Digraph(comment='FSM')
src = machine.state
for event in transitions:
machine.trigger(event['trigger'])
dst = machine.state
dot.edge(src,dst,event['trigger'])
src = dst
print (dot)
这里我的图表不包括所有可能的转换,只包括顺序转换。
输出:
digraph {
hungry -> satisfied [label=eat]
satisfied -> full [label=eat]
full -> sick [label=eat]
sick -> hungry [label=rest]
}
如您所见,图中不存在多个状态转换。有没有一种方法可以触发所有转换并将其存储在图形中,或者我是否必须编写自定义代码才能使所有这些都起作用。
transitions
组织事件转换。 Event
可能包含多个转换,同样组织在字典中。要实现您的愿望,首先遍历事件字典(键是触发器名称,值是 Event
本身)以获取事件。然后,遍历 Event.transitions
(键是源状态,值是适用的 Transition
对象的列表)以获得转换列表。现在,迭代此列表以获取每个转换的源和目标。如果您愿意,可以使用触发器名称作为标签:
from transitions import Machine
from graphviz import Digraph
class Matter(object):
pass
# The states
states = ['hungry', 'satisfied', 'full', 'sick']
# And some transitions between states.
transitions = [{'trigger': 'eat', 'source': 'hungry', 'dest': 'satisfied'},
{'trigger': 'eat', 'source': 'satisfied', 'dest': 'full'},
{'trigger': 'eat', 'source': 'full', 'dest': 'sick'},
{'trigger': 'rest', 'source': ['satisfied', 'full', 'sick'],
'dest': 'hungry'}]
# Initialize
machine = Matter()
fsm = Machine(machine, states=states, transitions=transitions, initial=states[0],
auto_transitions=False)
dot = Digraph(comment='FSM')
for label, event in fsm.events.items():
for event_transitions in event.transitions.values():
for transition in event_transitions:
dot.edge(transition.source, transition.dest, label)
print(dot)
输出:
// FSM
digraph {
hungry -> satisfied [label=eat]
satisfied -> full [label=eat]
full -> sick [label=eat]
satisfied -> hungry [label=rest]
full -> hungry [label=rest]
sick -> hungry [label=rest]
}
我还添加了 auto_transitions=False
到你的 Machine
。这样 transitions
将不会生成自动转换 (to_<state_name>
),否则会使您的图形混乱。当然,您可以修改 auto_transitions=True
或尝试从图中过滤自动转换,如 transitions
' diagrams extension.
中所做的那样
我无法在我的 Windows 10 系统上安装 pygraphviz,因此作为解决方法,我尝试将 FSM 的状态和转换存储在单独的图形中。例如:
from transitions import Machine
from graphviz import Digraph
class Matter(object):
pass
# The states
states=['hungry', 'satisfied', 'full', 'sick']
# And some transitions between states.
transitions = [
{ 'trigger': 'eat', 'source': 'hungry', 'dest': 'satisfied' },
{ 'trigger': 'eat', 'source': 'satisfied', 'dest': 'full' },
{ 'trigger': 'eat', 'source': 'full', 'dest': 'sick' },
{ 'trigger': 'rest', 'source': ['satisfied', 'full', 'sick'], 'dest':
'hungry' }]
# Initialize
machine = Matter()
fsm = Machine(machine, states=states, transitions=transitions, initial=states[0])
dot = Digraph(comment='FSM')
src = machine.state
for event in transitions:
machine.trigger(event['trigger'])
dst = machine.state
dot.edge(src,dst,event['trigger'])
src = dst
print (dot)
这里我的图表不包括所有可能的转换,只包括顺序转换。
输出:
digraph {
hungry -> satisfied [label=eat]
satisfied -> full [label=eat]
full -> sick [label=eat]
sick -> hungry [label=rest]
}
如您所见,图中不存在多个状态转换。有没有一种方法可以触发所有转换并将其存储在图形中,或者我是否必须编写自定义代码才能使所有这些都起作用。
transitions
组织事件转换。 Event
可能包含多个转换,同样组织在字典中。要实现您的愿望,首先遍历事件字典(键是触发器名称,值是 Event
本身)以获取事件。然后,遍历 Event.transitions
(键是源状态,值是适用的 Transition
对象的列表)以获得转换列表。现在,迭代此列表以获取每个转换的源和目标。如果您愿意,可以使用触发器名称作为标签:
from transitions import Machine
from graphviz import Digraph
class Matter(object):
pass
# The states
states = ['hungry', 'satisfied', 'full', 'sick']
# And some transitions between states.
transitions = [{'trigger': 'eat', 'source': 'hungry', 'dest': 'satisfied'},
{'trigger': 'eat', 'source': 'satisfied', 'dest': 'full'},
{'trigger': 'eat', 'source': 'full', 'dest': 'sick'},
{'trigger': 'rest', 'source': ['satisfied', 'full', 'sick'],
'dest': 'hungry'}]
# Initialize
machine = Matter()
fsm = Machine(machine, states=states, transitions=transitions, initial=states[0],
auto_transitions=False)
dot = Digraph(comment='FSM')
for label, event in fsm.events.items():
for event_transitions in event.transitions.values():
for transition in event_transitions:
dot.edge(transition.source, transition.dest, label)
print(dot)
输出:
// FSM
digraph {
hungry -> satisfied [label=eat]
satisfied -> full [label=eat]
full -> sick [label=eat]
satisfied -> hungry [label=rest]
full -> hungry [label=rest]
sick -> hungry [label=rest]
}
我还添加了 auto_transitions=False
到你的 Machine
。这样 transitions
将不会生成自动转换 (to_<state_name>
),否则会使您的图形混乱。当然,您可以修改 auto_transitions=True
或尝试从图中过滤自动转换,如 transitions
' diagrams extension.