2008-09-02 88 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使它們可執行。這需要一些範例機會來編程,但我發現它非常有效。