2017-11-07 6 views
1

필자는 Windows 10 시스템에 pygraphviz를 설치할 수 없었습니다. 임시 해결책으로 FSM의 상태와 전환을 별도의 그래프에 저장하려고합니다. 예 :파이썬 전환 : 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] 
} 

당신은 여러 상태 전이 그래프에 존재하지 않는 볼 수 있듯이. 모든 전환을 트리거하여 그래프에 저장할 수있는 방법이 있습니까? 아니면이 모든 작업을 수행 할 수있는 사용자 지정 코드를 작성해야합니까?

답변

1

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) 

출력 :

나는 또한 당신의 Machineauto_transitions=False을 추가
// 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] 
} 

. 이렇게하면 transitions은 자동 전환 (to_<state_name>)을 생성하지 않으므로 그래프가 혼란 스럽습니다. 물론 auto_transitions=True을 사용하거나 transitionsdiagrams extension 에서처럼 그래프에서 자동 전환을 걸러 낼 수 있습니다.

관련 문제