有限状态机(Finite-state machine, FSM),又称有限状态自动机,简称状态机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。FSM是一种算法思想,简单而言,有限状态机由一组状态、一个初始状态、输入和根据输入及现有状态转换为下一个状态的转换函数组成。现实世界中存在大量具有有限个状态的系统:钟表系统、电梯系统、交通信号灯系统、通信协议系统、正则表达式、硬件电路系统设计、软件工程,编译器等,有限状态机的概念就是来自于现实世界中的这些有限系统。

有限状态机(Python)

  一般可以用状态图来对一个状态机进行精确地描述。大家请看这个可乐机的状态图 。

有限状态机(Python)

  从图中就可以清楚地看到可乐机的运行过程,图中直观地表现了可乐机投入不同金额硬币时的情况以及几个处理步骤的各个状态和它们之间的转换关系,根据投入硬币的不同面值,对总金额进行计算,并对各种操作进行响应以完成一次购买。 状态机的动态结构使得其在通讯系统,数字协议处理系统,控制系统,用户界面等领域得到了广泛地应用。

  • 有限状态机模型

有限状态机是一个五元组$M=\left(Q,\Sigma ,\delta ,q_0,F\right)$,其中:

$Q=\left\{q_0,q_1,\text{...},q_n\right\}$是有限状态集合。在任一确定的时刻,有限状态机只能处于一个确定的状态$q_i$;

$\Sigma =\left\{\sigma _1,\sigma _{2,\text{...},}\sigma _n\right\}$是有限输入字符集合。在任一确定的时刻,有限状态机只能接收一个确定的输入$\sigma_j$;

$\delta :Q\times \Sigma \rightarrow Q$是状态转移函数,在某一状态下,给定输入后有限状态机将转入状态迁移函数决定的一个新状态;

$q_0\in Q$是初始状态,有限状态机由此状态开始接收输入;

$F\subseteq Q$是最终状态集合,有限状态机在达到终态后不再接收输入。

  • 有限状态机的实现

  有限状态机有多种实现方式:

  1switch-case或if-else

  游戏引擎是有限状态机最为成功的应用领域之一,由于设计良好的状态机能够被用来取代部分的人工智能算法,因此游戏中的每个角色或者器件都有可能内嵌一个状态机。考虑RPG游戏中城门这样一个简单的对象,它具有打开(Opened)、关闭(Closed)、上锁(Locked)、解锁(Unlocked)四种状态。当玩家到达一个处于状态Locked的门时,如果此时他已经找到了用来开门的钥匙,那么他就可以利用它将门的当前状态转变为Unlocked,进一步还可以通过旋转门上的把手将其状态转变为Opened,从而成功地进入城内。

有限状态机(Python)

switch (state)  {
  // 处理状态Opened的分支
  case (Opened): {
    // 执行动作Open
    open();
    // 检查是否有CloseDoor事件
    if (closeDoor()) { 
      // 当前状态转换为Closed
      changeState(Closed)
    }
    break;
  } 
  // 处理状态Closed的分支
  case (Closed): {
    // 执行动作Close
    close();
    // 检查是否有OpenDoor事件
    if (openDoor()) {
      // 当前状态转换为Opened
      changeState(Opened);
    }
    // 检查是否有LockDoor事件
    if (lockDoor()) {
      // 当前状态转换为Locked
      changeState(Locked);
    }
    break;
  }
 
  // 处理状态Locked的分支
  case (Locked): {
    // 执行动作Lock
    lock();
    // 检查是否有UnlockDoor事件
    if (unlockDoor()) {
      // 当前状态转换为Unlocked
      changeState(Unlocked);
    }
    break;
  }
 
  // 处理状态Unlocked的分支
  case (Unlocked): {
    // 执行动作Unlock
    unlock();
    // 检查是否有LockDoor事件
    if (lockDoor()) {
      // 当前状态转换为Locked    
      changeState(Locked)
    }
    // 检查是否有OpenDoor事件    
    if (openDoor()) {
      // 当前状态转换为Opened
      changeSate(Opened);
    }
    break;
  } 
}
View Code

相关文章: