2008-09-02 44 views
14

状态机最适合哪种编程问题?状态机有什么好处?

我已经阅读过有关使用状态机实现的解析器,但希望了解有关作为状态机实现的尖叫问题。

回答

13

最简单的答案可能是它们几乎适用于任何问题。不要忘记,电脑本身也是一台状态机。

无论如何,状态机通常用于存在某些输入流的问题,并且需要在给定时刻完成的活动取决于该流在该点处看到的最后一个元素。此流的输入的

例子:在解析的情况下,一些文本文件,正则表达式的字符串,事件如player entered room游戏AI等活动

例子:准备读一些(在一个计算器的解析器输入中出现另一个数字后跟一个+),转身(在玩家接近然后打喷嚏之后),执行跳跃踢(在玩家按左,左,右,上,上之后)。

2

有状态的协议,如TCP通常表示为状态机。然而,你很少想要将任何东西作为一个状态机来实现。通常情况下,您将使用一种腐败,即在一种状态下执行重复操作,在数据转换时记录数据或在保持一种状态时交换数据。

1

工作流程(请参阅.net 3.0中的WF)

1

它们有很多用途,解析器是一个值得注意的解析器。我亲自使用简化的状态机在应用程序中实现复杂的多步任务对话框。

1

解析器示例。我最近写了一个解析器,它从另一个程序获取二进制流。解析的当前元素的含义表示下一个元素的大小/含义。有(小)有限数量的元素可能。因此一个状态机。

1

它们非常适合对状态进行更改的事物进行建模,并且具有触发每次转换的逻辑。例如,我会使用有限状态机通过邮件跟踪包,或者在注册过程中跟踪用户的不同状态。

随着可能状态值的数量增加,转换的数量会爆炸。在这种情况下,状态机帮助很多。浮现在脑海

0

事情是:

  • 机器人/机械操作......在工厂的机器人手臂
  • 模拟游戏(模拟城市,赛车游戏等)

推广:当你有一串输入时,与任何人进行交互,需要了解以前的输入或换句话说,当处理任何单一输入放置需要先前输入的知识。 (也就是说,它需要有“状态”)

但我知道的并不多,但并不能归结为解析问题。

1

AI在游戏中通常使用状态机来实现。 有助于创建更易于构建和测试的离散逻辑。

1

游戏中的对象通常表示为状态机。 AI角色可能是:

  • 积极
  • 巡逻
  • 睡着

所以,你可以看到这些可能模型的一些简单而有效的状态。当然,你可以制作更复杂的连续系统。

另一个例子是一个过程,例如在Google Checkout上进行购买。谷歌提供了多个财务和订单状态,然后通知您转账,如信用卡结算或被拒绝,并允许您通知该订单已发货。

+1

另请参见heirarchical状态机:http://www.valvesoftware.com/publications/2009/ai_systems_of_l4d_mike_booth.pdf在Left4Dead的ai中有一个很好的解释。 – 2010-01-26 07:23:44

1

正则表达式匹配,解析,复杂系统中的流量控制。

正则表达式是一种简单形式的状态机,特别是有限自动机。尽管可以使用相互递归函数来实现它们,但它们本身就具有自然表现形式。

状态机实施得很好,效率很高。

如果你想创建一个可读状态机,那么对于许多目标语言来说,就有一个很好的状态机编译器。

http://research.cs.queensu.ca/~thurston/ragel/

它也可以让你避免可怕的 '转到'。

0

正如一个侧面说明,你可以实现状态机与适当的尾部调用,就像我在tail recursion问题中解释的。

在这个例子中,游戏中的每个房间都被认为是一个状态。此外,使用VHDL(以及其他逻辑综合语言)的硬件设计使用各地的状态机来描述硬件。

9

一个很好的资源是这个免费的State Machine EBook。我自己的快速答案如下。

当您的逻辑必须包含有关上次运行时发生的情况的信息时,它必须包含状态。

所以状态机就是任何能记住(或作用于)只能通过理解以前发生的事情才能获得的信息的代码。

例如,我有一个我的程序必须使用的蜂窝调制解调器。它必须按顺序执行以下步骤:

  1. 复位调制解调器
  2. 发起通信与调制解调器
  3. 等待信号强度指示与塔
  4. ...
  5. 良好的连接

现在我可以阻止主程序,只需按顺序执行所有这些步骤,等待每个程序运行,但我想给我的用户反馈并同时执行其他操作。所以我把它作为一个函数内部的状态机来实现,并且每秒运行这个函数100次。

enum states{reset,initsend, initresponse, waitonsignal,dial,ppp,...} 
modemfunction() 
{ 
    static currentstate 

    switch(currentstate) 
    { 
    case reset: 
    Do reset 
    if reset was successful, nextstate=init else nextstate = reset 
    break 
    case initsend 
    send "ATD" 
    nextstate = initresponse 
    break 
    ... 
    } 
currentstate=nextstate 
} 

更复杂的状态机实现协议。例如我使用的ECU诊断协议只能发送8字节的数据包,但有时我需要发送更大的数据包。 ECU速度很慢,所以我需要等待响应。理想情况下,当我发送消息时,我使用一个函数,然后我不在乎发生了什么,但是在某个地方,我的程序必须监视线路并发送并回复这些消息,将它们拆分为更小的块并将收到的消息重新组合最后的消息。

0

如果您需要一个简单的随机过程,您可以使用一个马尔可夫链,它可以表示为一个状态机(给定当前状态,下一步链将处于状态X,具有一定的概率)。

0

任何工作流应用程序,尤其是异步活动。工作流中有一个项目处于某种状态,并且状态机通过将项目置于不同的状态来知道如何对外部事件做出反应,此时会发生其他一些活动。

0

状态的概念对于应用程序“记住”系统的当前上下文非常有用,并在新信息到达时作出正确反应。任何非平凡的应用程序都通过变量和条件嵌入代码中。

因此,如果您的应用程序每次因收到上下文而收到新信息时都有不同反应,则可以使用状态机为您的系统建模。一个例子就是如何解释计算器上的密钥,这取决于你在那个时间点正在处理的内容。相反,如果你的计算不依赖于上下文,而只依赖于输入(就像添加两个数字的函数一样),你将不需要状态机(或者更好地说,你将拥有一台状态机零状态)

有些人在状态机方面设计了整个应用程序,因为他们捕获了项目中必须记住的重要事项,然后使用一些过程或autocoders使它们可执行。这需要一些范例机会来编程,但我发现它非常有效。