如何在状态机中做出决定
How to take decision in a state-machine
我正在构建一个基于 transitions 的状态机,但可能是一个通用的状态机问题。我正在努力构建一个简单的决策树。
简化的状态机应该是这样的
[state:new] --- generateXYZ ---> [state:generation_successful]
---> [state:generation_failed]
我知道我可以创建两个转换并保护它们,但这并不是理想的解决方案 - 也许你会纠正我的那个。
理想情况下,我想 运行 一些代码,它返回真(=成功)或假(=失败)。
期待任何建议,也许我从错误的角度看待这个问题。谢谢!
欢迎来到 Stack Overflow!
build a simple decision tree.
我假设您对 generating
状态不感兴趣。如果生成可能需要一段时间,添加这样的状态可能有助于调整 model/machine 行为,以防它是 'busy'.
I understand that I could create two transitions and guard them
我猜最终两个不同的目的地必须导致两个转换。但是,使用 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
return 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')
代码和图形的可理解性可能会受到影响。
我正在构建一个基于 transitions 的状态机,但可能是一个通用的状态机问题。我正在努力构建一个简单的决策树。
简化的状态机应该是这样的
[state:new] --- generateXYZ ---> [state:generation_successful]
---> [state:generation_failed]
我知道我可以创建两个转换并保护它们,但这并不是理想的解决方案 - 也许你会纠正我的那个。
理想情况下,我想 运行 一些代码,它返回真(=成功)或假(=失败)。
期待任何建议,也许我从错误的角度看待这个问题。谢谢!
欢迎来到 Stack Overflow!
build a simple decision tree.
我假设您对 generating
状态不感兴趣。如果生成可能需要一段时间,添加这样的状态可能有助于调整 model/machine 行为,以防它是 'busy'.
I understand that I could create two transitions and guard them
我猜最终两个不同的目的地必须导致两个转换。但是,使用 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
return 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')
代码和图形的可理解性可能会受到影响。