状态机有哪些问题?

时间:2008-09-02 20:44:36

标签: algorithm state

状态机最适合哪种编程问题?

我已经阅读了有关使用状态机实现的解析器的信息,但是想了解一下尖叫出来作为状态机实现的问题。

15 个答案:

答案 0 :(得分:13)

最简单的答案可能是他们几乎适合任何问题。不要忘记计算机本身也是状态机。

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

此输入流的示例:解析时的某个文本文件,正则表达式的字符串,游戏AI的player entered room等事件等。

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

答案 1 :(得分: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很慢,所以我需要等待响应。理想情况下,当我发送消息时,我使用一个函数然后我不关心会发生什么,但在某个地方,我的程序必须监视该行并发送和响应这些消息,将它们分成更小的部分并将接收到的消息重新组合成最后的消息。

答案 2 :(得分:2)

TCP等有状态协议通常表示为状态机。但是,您很少想要将任何东西作为状态机实现。通常你会使用一个腐败,即让它在一个状态下执行重复操作,在转换时记录数据,或者在保持一个状态时交换数据。

答案 3 :(得分:1)

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

答案 4 :(得分:1)

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

答案 5 :(得分:1)

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

答案 6 :(得分:1)

它们非常适合对改变状态的事物进行建模,并且具有在每次转换时触发的逻辑。

我使用有限状态机来通过邮件跟踪包,或者在注册过程中跟踪用户的不同stata,例如。

随着可能状态值的数量增加,转换次数会爆炸。在这种情况下,状态机可以提供很多帮助。

答案 7 :(得分:1)

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

答案 8 :(得分:1)

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

  • 护卫
  • 攻击
  • 巡逻
  • 睡着

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

另一个例子是在Google Checkout上进行购买等流程。 Google为财务和订单提供了多个州,然后通知您信用卡清算或被拒绝等转换,并允许您通知订单已发货。

答案 9 :(得分:1)

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

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

状态机运行良好时,效率会非常高。

如果你想制作一个可读的状态机,有很多目标语言的优秀状态机编译器。

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

它还可以让你避免可怕的'goto'。

答案 10 :(得分:0)

想到的事情是:

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

概括:如果您有一串输入,当与其中任何一个进行交互时,需要了解先前的输入,或者换句话说,当处理任何单个输入时需要了解先前的输入。 (也就是说,它需要有“状态”)

尽管如此,我所知道的并不是可以简化为解析问题。

答案 11 :(得分:0)

正如旁注,您可以使用我在tail recursion问题中解释的正确尾调用来实现状态机。

在这个例子中,游戏中的每个房间都被认为是一个州。

此外,使用VHDL(和其他逻辑综合语言)的硬件设计在任何地方使用状态机来描述硬件。

答案 12 :(得分:0)

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

答案 13 :(得分:0)

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

答案 14 :(得分:0)

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

因此,如果您的应用程序因为您所处的上下文而每次收到新信息时都必须做出不同的反应,您可以使用状态机对系统进行建模。一个例子是如何解释计算器上的键,这取决于您在那个时间点处理的内容。

相反,如果你的计算不依赖于上下文而只依赖于输入(比如添加两个数字的函数),你将不需要状态机(或者更好的说,你将拥有一个零状态机状态)的

有些人根据状态机设计整个应用程序,因为它们捕获了项目中要记住的基本内容,然后使用一些过程或自动编码器使它们可执行。以这种方式编程需要一些范式,但我发现它非常有效。