我正在基于transitions构建状态机,但可能是一个通用的状态机问题。我正在努力建立一个简单的决策树。
简化的状态机应该看起来像
[state:new] --- generateXYZ ---> [state:generation_successful]
---> [state:generation_failed]
我知道我可以创建两个过渡并对其进行保护,但这并不是理想的解决方案-也许您在那个过渡上纠正了我。
理想情况下,我想运行一些代码,它要么返回true(=成功),要么返回false(= failed)。
期待任何建议,也许我是从错误的角度来看待这个问题。谢谢!
答案 0 :(得分:0)
欢迎堆栈溢出!
建立一个简单的决策树。
我认为您对generating
状态不感兴趣。如果生成可能要花一些时间,那么在状态为“忙”的情况下,添加这种状态可能有助于调整模型/机器的行为。
我知道我可以创建两个过渡并对其进行保护
我猜最终两个不同的目的地必须导致两次转换。但是,使用transitions
时,您可以在过渡定义中使用conditions
,还可以包装过渡创建内容,以提供更多便利。我用GraphMachine
来说明结果:
from transitions.extensions.diagrams import GraphMachine as Machine
import random
class Model:
def __init__(self):
self.machine = Machine(self, states=['A', 'B', 'C', 'D', 'AF', 'BF', 'F'], initial='A', show_conditions=True)
# decision trees are easier to read top to bottom
# configure graphviz accordingly
self.machine.machine_attributes['rankdir'] = 'TB'
self._generated = False
def add_decision(self, trigger, source, execute, check, on_success, on_fail):
# this transition will be evaluated first, when execute returns true it will be used
self.machine.add_transition(trigger, source, on_success, prepare=execute, conditions=check)
# if this transition is evaluated, we know that a) execute has been called and b) it returned False
# thus, we could omit 'unless'
self.machine.add_transition(trigger, source, on_fail, unless=check)
def generate(self):
self._generated = bool(random.getrandbits(1)) # returns True of False randomly
def generated(self):
return self._generated
model = Model()
model.add_decision('execute', 'A', execute='generate', check='generated', on_success='B', on_fail='AF')
model.add_decision('execute', 'B', execute='generate', check='generated', on_success='C', on_fail='BF')
model.add_decision('execute', 'AF', execute='generate', check='generated', on_success='C', on_fail='F')
model.add_decision('execute', 'C', execute='generate', check='generated', on_success='D', on_fail='F')
# call execute twice
model.execute()
model.execute()
# let's see where we ended up
model.get_graph().draw('graph.png', prog='dot')
这将导致如下结果:
就我而言,生成在第一次运行中成功,而在第二次运行中失败。您可以通过以下方式精简此代码:a)不使用GraphMachine
,b)使generate
返回False
或True
并将其直接传递给条件:
# ... Model.add_decision
self.machine.add_transition(trigger, source, on_success, conditions=execute)
self.machine.add_transition(trigger, source, on_fail)
# ...
def generate(self):
return bool(random.getrandbits(1)) # returns True of False randomly
# ...
model.add_decision('execute', 'A', execute='generate', on_success='B', on_fail='AF')
代码和图形的易懂性可能会受到影响。