Atitit. 有限状态机 fsm 状态模式

Atitit. 有限状态机 fsm 状态模式

 

1. 有限状态机 1

2. “状态表”和“状态轮换表” 1

3. 有限状态机概念(状态(State)事件(Event)转换(Transition) 动作(Action) 2

4. 状态机的应用场景 2

4.1. ,“有限状态机”在游戏的人工智能方面是很有用处的。 2

4.2. 用状态机模式消除复杂的 if else 逻辑 2

4.3. 源码文本处理状态机 2

4.4. 正则表达式(regexp),判断字符串格式和解析字符串内容基本全靠她。 3

4.5. 游戏编程AI的材料,感觉游戏中的AI,第一要说的就是有限状态机来实现精灵的AI, 3

4.6. 词法分析 3

5. FSM的实现方式 3

5.1. : 1) switch/case或者if/else 3

5.2.  2) 状态表 4

5.3.  3) 使用State Pattern 4

5.4. 使用宏定义描述状态机 4

6. 设计模式之状态机模式   5

 

1. 有限状态机

是一种十分重要的时序逻辑电路模块。它对数字系统的设计具有十分重要的作用。有限状态机是指输出取决于过去输入部分和当前输入部分的时序逻辑电路。一般来说,除了输入部分和输出部分外,有限状态机还含有一组具有“记忆”功能的寄存器,这些寄存器的功能是记忆有限状态机的内部状态,它们常被称为状态寄存器。在有限状态机中,状态寄存器的的下一个状态不仅与输入信号有关,而且还与该寄存器的当前状态有关,因此有限状态机又可以认为是组合逻辑和寄存器逻辑的一种组合。其中,寄存器逻辑的功能是存储有限状态机的内部状态;而组合逻辑又可以分为次态逻辑和输出逻辑两部分,次态逻辑的功能是确定有限状态机的下一个状态,输出逻辑的功能是确定有限状态机的输出。

状态机原本不是软件和程序中的术语,在数字逻辑中有限状态机是指输出取决于过去输入部分和当前输入部分的时序逻辑电路。这 里甚至无需强调有限状态机,可以简单理解状态机为一个黑箱子,向其中投入指令后即可进行操作和装换状态,它有一个最终状态,当到达最终状态时,即可完成任 务。

 

不要把状态机局限于软件,事实上,硬件上才是真正大量使用状态机的地方。
时序电路就是状态机的体现

作者:: 老哇的爪子 Attilax 艾龙,  EMAIL:1466519819@qq.com

转载请注明来源: http://blog.csdn.net/attilax

 

2. “状态表状态轮换表

 

3. 有限状态机概念(状态(State)事件(Event)转换(Transition) 动作(Action)

图1 控制城门的状态机

在描述有限状态机时,状态、事件、转换和动作是经常会碰到的几个基本概念。

状态(State)指的是对象在其生命周期中的一种状况,处于某个特定状态中的对象必然会满足某些条件、执行某些动作或者是等待某些事件。 

事件(Event)指的是在时间和空间上占有一定位置,并且对状态机来讲是有意义的那些事情。事件通常会引起状态的变迁,促使状态机从一种状态切换到另一种状态。 

转换(Transition)指的是两个状态之间的一种关系,表明对象将在第一个状态中执行一定的动作,并将在某个事件发生同时某个特定条件满足时进入第二个状态。 

   动作(Action)指的是状态机中可以执行的那些原子操作,所谓原子操作指的是它们在运行的过程中不能被其他消息所中断,必须一直执行下去。

 

4. 状态机的应用场景

实在是太广泛了,例如各种存储器的控制,AD的控制外部器件的控制,也包括内部电路的控制,

 

4.1. ,“有限状态机”在游戏的人工智能方面是很有用处的。

4.2. 用状态机模式消除复杂的 if else 逻辑

 

4.3. 源码文本处理状态机

在其它常见文本处理问题中,输入文件是极具“状态”的。 每一块数据的含义取决于它前面的字符串(也许是它后面的字符串)。报告、大型机数据输入、可读文本、编程源文件和其它种类的文本文件都是有状态的。

一个简单例子是可能出现在 Python 源文件中的一行代码:

myObject = SomeClass(this, that, other)

这行表示,如果恰好有以下几行围绕着这一行,则有部分内容不同:

"""How to use SomeClass:myObject = SomeClass(this, that, other)"""

我们应知道我们处于块引用” 状态 以确定这行代码是一部分注释而不是 Python 操作。 

 

4.4. 正则表达式(regexp),判断字符串格式和解析字符串内容基本全靠她。

其实正则表达式就是有限状态机。只是表达形式不同。正则表达式写好后可以通过程序“编译”成状态转换表,就是大家常见到的那种状态转换图

解释器模式在js中有两个最典型的应用json和正则表达式

4.5. 游戏编程AI的材料,感觉游戏中的AI,第一要说的就是有限状态机来实现精灵的AI,

游戏中的NPC,不考虑人工智能的前提下,NPC只能根据预设好的条件和用户的反馈做出回应,也就是可以这样说,NPC有n个状态,用回每回应一次就是一 个“上升沿”(一次触发),NPC根据用户的选择从当前第k个状态跳转至第m个状态,当然状态跳转的范围是在n以内。开发人员要做的就是在某个状态让玩家 去做相应的事比如:获得宝物、触发任务、升级等等。而实现这种结构的基本框架可能是switch...case...

4.6. 词法分析(例如正斜杠转义的实现)

词法分析有限状态机任务很简单,从输入字符流中读入一个一个的字符,当辨认出输入的字符能构成一个独立的语法单元(token)时,便将这个token放入待分析的词句流中。

正斜杠转义的实现。通常字符串转义都是以反斜杠\实现的,假如有一个字符串,现在我们要把正斜杠用作转义符以做一些特殊用途,其他字符原样放置。那么正斜杠/和它后面的字符必须被看成一个整体,其它每个字符都是一个整体。

这个状态机只有两个状态 第一个状态是读入普通字符状态 第二个状态是读入正斜杠以后的状态 状态图如下

 

 

5. FSM的实现方式

5.1. :
1) switch/case或者if/else

 


这无意是最直观的方式,使用一堆条件判断,会编程的人都可以做到,对简单小巧的状态机来说最合适,但是毫无疑问,这样的方式比较原始,对庞大的状态机难以维护。

但checkStateChange()和performStateChange()这两个函数本身依然会在面对很复杂的状态机时,内部逻辑变得异常臃肿,甚至可能是难以实现。

在很长一段时期内,使用switch语 句一直是实现有限状态机的唯一方法,甚至像编译器这样复杂的软件系统,大部分也都直接采用这种实现方式。但之后随着状态机应用的逐渐深入,构造出来的状态 机越来越复杂,这种方法也开始面临各种严峻的考验,其中最令人头痛的是如果状态机中的状态非常多,或者状态之间的转换关系异常复杂,那么简单地使用switch语句构造出来的状态机将是不可维护的。

 

5.2. 
2) 状态表

 


维护一个二维状态表,横坐标表示当前状态,纵坐标表示输入,表中一个元素存储下一个状态和对应的操作。这一招易于维护,但是运行时间和存储空间的代价较大。

5.3. 
3) 使用State Pattern


使 用State Pattern使得代码的维护比switch/case方式稍好,性能上也不会有很多的影响,但是也不是100%完美。不过Robert C. Martin做了两个自动产生FSM代码的工具,for java和for C++各一个,在http://www.objectmentor.com/resources/index上有免费下载,这个工具的输入是纯文本的状态 机描述,自动产生符合State Pattern的代码,这样developer的工作只需要维护状态机的文本描述,每必要冒引入bug的风险去维护code。

4)

5.4.  使用宏定义描述状态机


一般来说,C++编程中应该避免使用#define,但是这主要是因为如果用宏来定义函数的话,很容易产生这样那样的问题,但是巧妙的使用,还是能够产生奇妙的效果。MFC就是使用宏定义来实现大的架构的。
在实现FSM的时候,可以把一些繁琐无比的if/else还有花括号的组合放在宏中,这样,在代码中可以3)中状态机描述文本一样写,通过编译器的预编译处理产生1)一样的效果,我见过产生C代码的宏,如果要产生C++代码,己软MFC可以,那么理论上也是可行

6. 设计模式之状态机模式  

 

 

参考

可爱的 Python:使用状态机.htm

 

用状态机模式消除复杂的 if else 逻辑 技术频道 _ IT168.htm

状态机 - xgbing - 博客频道 - CSDN.NET.htm

词法分析·状态机的实现_安生犹梦_新浪博客.htm

词法分析·状态机的实现_安生犹梦_新浪博客.htm

posted @ 2014-11-29 11:00  attilaxAti  阅读(378)  评论(0编辑  收藏  举报