使用Python设计状态机[快速指南]

3,236 阅读7分钟

大家好!在这篇文章中,我们将学习计算机科学的一些基本知识。当然,不是整个课程!只是计算理论的一部分。这个主题是关于有限自动机的设计。我们将在下一部分中讨论所有的术语。那么,让我们开始吧。

什么是 Python 中的状态机?

状态机是一种行为模型,它定义了一个对象对事件的反应方式。在 Python 中,一个状态机通常被实现为一个有限状态机 (FSM)。FSM 是一种计算的数学模型,可以用来设计数字逻辑电路和计算机程序。它由一组状态、这些状态之间的转换以及发生转换时执行的动作组成。

有限状态机(FSM)是一种计算的数学模型,可用于设计数字逻辑电路和计算机程序。它由一组状态、这些状态之间的转换以及转换发生时执行的动作组成。一个FSM可以表示为一个有向图,状态表示为节点,转换表示为边。边上标有触发转换的事件,动作与边相关联。

什么是TOC和自动机?

自动机理论和TOC都被用来研究机器的行为,但它们采取的方法不同。自动机理论关注的是抽象机器本身,而TOC关注的是使用该机器可以解决的问题。

自动机理论是对抽象机器和自动机的研究,以及使用它们可以解决的计算问题。自动机理论也与形式语言理论密切相关,因为自动机经常被用作形式语言的计算模型。计算理论(TOC)是数学的一个分支,涉及到对算法及其效率的研究。它关注算法的设计和分析,数据结构和复杂性理论。

计算理论是一个课题,在这个课题中,我们设计一些虚拟机器,在基本的输入和输出上工作。从最根本的层面来看,工作是从接受一定长度的字符串开始的。这些机器的基本命名法是自动机。

有两种类型的自动机:

  1. 确定性有限自动机(DFA)。
  2. 非确定性有限自动机(NDFA)。

对确定型有限自动机(DFA)的理解

确定性有限自动机(DFA)是一种特殊类型的有限状态机,根据确定的算法接受或拒绝一串符号,称为输入字符串。DFA可以表示为一个有向图,其中状态表示为节点,转换表示为边。边上标有触发转换的事件,行动与边相关联。

了解非确定性有限自动机(NDFA)

非确定性有限自动机(NDFA)是一种特殊类型的有限状态机,它可以根据非确定性算法接受或拒绝一个输入字符串。NDFA可以表示为一个有向图,其中状态表示为节点,转换表示为边。边上标有触发转换的事件,动作与边相关联。

一个基本的自动机是一个由五个单元组成的元组。

Automata = (Q, F, δ, q0, Σ)

  1. Q = 所有状态的集合。
  2. F = 所有最终状态的集合。
  3. δ = 过渡函数或映射函数,用每个输入映射状态的运动。
  4. q0 = 初始状态。
  5. Σ = 一组有限的输入符号。

基本DFA的图示

Automata Diagram

自动机示意图

这个机器接受字符串 "aa"。 这里的图是DFA的最简单的表示。让我们来理解它的参数:

  1. 这里Q={q0, q1, q2}。一组最终状态。
  2. q0是初始状态。
  3. q2是最终状态
  4. Σ = {a}是所有输入符号的集合。

这个机器由三个状态组成--q0、q1和q2。最初,当我们给一个状态输入时,它就会过渡/移动到另一个状态。过渡函数**(δ**)记录了所有这些活动。当所需的字符串到达一个特定的状态时,我们将其定义为该机器的最终状态

自动机的应用

自动机理论是对抽象机器和可以用它们解决的计算问题的研究。自动机被用于各种应用中,包括验证、模型检查、调度和数据库更新。以下是自动机的3个应用

  1. 游戏开发
  2. 人工智能
  3. 编译器设计

现在让我们跳到使用Python的statemachine库来构建一个状态机。

使用Python建立一个状态机

我们将使用Python对我们自己的状态机进行编程。这将与在纸上画出它一样。此外,我们还将使用一些特殊的操作来检查转换过程。

1.安装statemachine库

打开你的命令提示符,输入pip 命令

pip install python-statemachine

Installing Python Statemachine

安装Python Statemachine

工具和技术

  1. Python版本: 3.8.x或以上。
  2. 支持性的库: python-statemachine
  3. 一个好的IDE: VSCode, Spyder等。

代码:

from statemachine import StateMachine, State

class LightBulb(StateMachine):

    # creating states
    offState = State("off", initial = True)
    onState = State("on")
     
    # transitions of the state
    switchOn = offState.to(onState)
    switchOff = onState.to(offState)
    
        
bulb = LightBulb()
print(bulb.current_state)


输出:

State('off', identifier='offState', value='offState', initial=True)

解释:

  1. 我们首先导入state machine 模块以及 State class.
  2. 我们首先创建一个LightBulb类。然后,为了继承属性,在括号内给出StateMachine
  3. 我们创建两个状态:
    1. offState:表示最初,灯泡是关闭的。将初始参数设置为True。
    2. onState:表示打开灯泡。
  4. 然后,创建两个转换:
    1. switchOn。从offState过渡到onState。
    2. switchOff:从onState转到offState。
  5. 创建一个我们的类的实例,即bulb
  6. 然后,为了检查当前的状态,我们简单地调用bulb对象的current_state 属性。
  7. 我们看到,灯泡的当前状态是**"关闭"。**

状态机的动态属性

当我们创建一个状态机时,模块为该机器中的每个状态创建了一组特殊的属性。我们可以使用实例和属性来检查该属性是否对该状态有效。在上面的代码中,我们有两个这样的状态。所以,创建的属性也是

检查属性的代码:

bulb.is_offState # returns True
bulb.is_onState # returns False

检查状态和转换的数量

让我们来看看我们如何从一个状态类中提取过渡和所有的状态。当我们的类只有两个状态时,这可能看起来没什么用。但是考虑到有多种可能状态的类,这时这些技术就会很方便。

检查状态数量的代码

在自动机中,我们需要保持所有当前状态的记录。为了做到这一点,我们使用下面的列表理解法

a = [s.identifier for s in bulb.states]
print(a)

输出

['offState', 'onState']

解释

  1. 我们使用列表理解法将所有的状态存储在一个列表中。
  2. 然后使用 "标识符 "属性,运行一个for循环。
  3. 使用states 属性来获取每个状态。我们需要使用灯泡 对象来调用它,灯泡 对象是我们LightBulb类的实例。
  4. 把这个列表分配给一个变量 "a"。
  5. 然后打印它。我们得到所有的状态。

检查转换的代码

自动机总是从一个状态过渡到另一个状态。简单地说,我们称之为转换。所以,为了记录它们,我们的StateMachine有,我们有转换 属性。

b = [s.identifier for s in bulb.transitions]
print(b)

输出:

['switchOff', 'switchOn']

解释:

所有的代码都与状态的代码相同。我们只是在灯泡 对象中使用了 "transitions "关键字。

总结

所以,通过这种方式,我们可以用Python建立一个简单的状态机。当我们在设计人工智能算法或游戏时,这些机器是需要研究的重要概念之一。对于逻辑构建来说,状态机也是很好的页面主题。所以,我们在这里结束这个话题。