ステートマシンにはどのようなプログラミング上の問題が最適ですか?ステートマシンにはどんな種類の問題がありますか?
ステートマシンを使用して実装されているパーサーについては読んだことがありますが、ステートマシンとして実装するために叫ぶ問題については知りたいと思います。
ステートマシンにはどのようなプログラミング上の問題が最適ですか?ステートマシンにはどんな種類の問題がありますか?
ステートマシンを使用して実装されているパーサーについては読んだことがありますが、ステートマシンとして実装するために叫ぶ問題については知りたいと思います。
最も簡単な答えは、実際にはどのような問題にも適していると考えられます。コンピュータ自体も状態マシンであることを忘れないでください。
それにかかわらず、ステートマシンは、通常、何らかの入力ストリームがあり、ある時点で実行する必要のあるアクティビティが、その時点でそのストリームに表示されている最後の要素に依存する問題で使用されます。入力のこのストリームの
例:構文解析の場合のいくつかのテキストファイル、正規表現の文字列を、このようなゲームAIのためのplayer entered room
などのイベントなどの活動の
例:番号を読み取るする準備ができて(プレイヤーが近づいてからくしゃみをした後に回る)、ジャンプキックをする(プレーヤーが左、右、上、上に押された後に)、数字の後に+
が入力された後に電卓の入力に表示されます。
TCPなどのステートフルプロトコルは、多くの場合、状態マシンとして表されます。しかし、状態機械として何かを実装する必要があることはまれです。通常は1つの破損を使用します。つまり、1つの状態になっている間に繰り返しアクションを実行したり、移行中にデータを記録したり、1つの状態のままデータを交換したりします。
ワークフローパーサは注目に値する一つである、彼らは多くの用途を有する
を(.NET 3.0でWFを参照してください)。私は、アプリケーションで複雑なマルチステップタスクダイアログを実装するために、単純化された状態マシンを個人的に使用しました。
パーサーの例。私は最近、別のプログラムからバイナリストリームを受け取るパーサを書いています。解析される現在の要素の意味は、次の要素のサイズ/意味を示します。可能な要素の数は(小さな)有限です。したがって、状態機械。
ステータスを変えるものをモデリングし、各トランジションでトリガするロジックを持つのに最適です。
私は、パッケージをメールで追跡したり、登録プロセス中にユーザーのさまざまなスタータを追跡するために有限状態マシンを使用します。
可能なステータス値の数が増えるにつれて、トランジションの数が爆発的に増加します。そのような場合には、ステートマシンが大いに役立ちます。頭に浮かぶ
物事は以下のとおりです。
- ロボット/機械操作工場で...これらのロボットアーム
- シミュレーションゲーム、(シムシティ、レーシングゲーム等。)
一般化:誰かとやりとりするときに入力文字列があるときは、以前の入力の知識が必要です。つまり、 putは以前の入力の知識が必要です。 (つまり、 "状態"が必要です)
私が知っていることはあまりありませんが、解析の問題には還元できません。
ゲームのAIは、ステートマシンを使用して実装されることがよくあります。 ビルドとテストがはるかに簡単な個別ロジックを作成できます。
ゲームのオブジェクトは、しばしば状態マシンとして表されます。 AIの文字は次のようになります。
をPatroling
もう1つの例は、Google Checkoutでの購入などのプロセスです。 Googleは財務および注文のためにいくつかの州を提供し、クレジットカードの清算や拒否などの取引を通知し、注文が出荷されたことを通知することができます。
複雑なシステムでの正規表現一致、解析、フロー制御。
正規表現は、状態マシンの簡単な形式、特に有限オートマトンです。相互再帰関数を使用してそれらを実装することは可能ですが、それらは自然な表現をそのまま持ちます。
ステートマシンがうまく実装されると、非常に効率的になります。
可読なステートマシンを作成する場合は、多くのターゲット言語用の優れたステートマシンコンパイラがあります。
http://research.cs.queensu.ca/~thurston/ragel/
また恐ろしい '後藤' を避けるためにことができます。
ちょうど副次的なものとして、tail recursion質問で説明したように、適切なテールコールで状態マシンを実装できます。
この例では、ゲームの各部屋は1つの状態と見なされます。
また、VHDL(および他のロジック合成言語)を使用したハードウェア設計では、ステートマシンを使用してハードウェアを記述しています。
このリソースは無料ですState Machine EBook。私自身の簡単な答えは以下の通りです。
ロジックに最後に実行されたことに関する情報が含まれている必要がある場合は、状態が含まれている必要があります。
ステートマシンは、以前に何が起こったかを理解することによってのみ得られる情報を覚えている(または動作する)コードです。
例えば、自分のプログラムで使用するセルラーモデムがあります。
メインプログラムをブロックして、これらのステップを順番に実行して、それぞれが実行されるのを待つことができますが、ユーザーからのフィードバックを得て、同時に他の操作を実行したいと思います。だから、私はこれを関数内の状態機械として実装し、この関数を1秒に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が遅いので、私は応答を待つ必要があります。理想的には私がメッセージを送るときに私は一つの関数を使って何が起こっても気にしませんが、私のプログラムは行を監視してこれらのメッセージを送信して応答しなければなりません。最終的なメッセージ
単純な確率過程が必要な場合は、状態マシンとして表現できるマルコフ連鎖を使用することができます(次のステップでは、連鎖はある確率で状態Xになります)。
特に非同期アクティビティを使用するワークフローアプリケーション。特定の状態のワークフロー内にアイテムがあり、状態マシンはアイテムを別の状態に置くことで外部イベントに対処する方法を知っています。その時点で他のアクティビティが発生します。
stateの概念は、システムの現在のコンテキストを「記憶」し、新しい情報が到着したときに適切に反応するアプリケーションにとって非常に便利です。非自明なアプリケーションでは、変数と条件文を介してコードにその概念が埋め込まれています。
あなたのアプリケーションが、あなたがいるコンテキストのために新しい情報を受け取るたびに異なった反応をしなければならない場合は、ステートマシンを使ってシステムをモデル化することができます。たとえば、電卓のキーを解釈する方法があります。これは、その時点でどのような処理が行われているかによって異なります。
逆に、計算が文脈に依存するのではなく、入力にのみ依存する場合(2つの数字を追加する関数のように)、ステートマシンは必要ありません。
一部の人は、アプリケーションでは、プロジェクトで重要なことを覚えてから、いくつかの手順や自動コードを使用して実行可能にするため、アプリケーション全体をステートマシンで設計します。このようにプログラムするにはいくつかのパラダイムチャンスが必要ですが、それは非常に効果的だとわかりました。
説明をよくするために、Left4Deadのaiの階層構造マシン(http://www.valvesoftware.com/publications/2009/ai_systems_of_l4d_mike_booth.pdf)も参照してください。 –