MASのレシピブック06を参考に、セルフうどん店内での歩行モデルを作成しています。
人エージェントが、入口→レジ→お湯→トッピング→冷水機→椅子(空いている椅子の中からランダムに1つ)→返却口→出口の順に行動していくことを到達目標としています。
"Floor"の値設定は、<0:歩行可能エリア、1:壁、2:天ぷら棚、3:注文・受け取り口、4:レジ、5:トッピング、6:お湯、7:冷水機、8:椅子、9:テーブル、10:返却口、11:入口、12:出口> のように設定しています。
以下4つが直面している問題です。
① 「他のお客さまが存在するセルは歩行可能エリアから除外する」の部分を記述しているが、人エージェント同士が重なってしまう。
② 1人の人エージェントに対して1つの空いている椅子に到達するように設定したいが、椅子周辺で複数のエージェントが固まってしまう。
③ 入口から入ってきたエージェントの中に、目的場所に向かわずにひたすら直進するエージェント(実行後真上に行動し、エージェントにぶつかって静止している人エージェント)が存在する。
④ 行動順の中で一部のエージェントが冷水機(マップの右側、縦方向真ん中部分)と椅子の順序が入れ替わる
改良を重ねる過程で二点、解消方法が分からない問題がでてきたので伺いたいです。
① 空席への移動
<目標>
エージェントが空席に行き座る。目的の椅子に他エージェントが座っていた場合には別の空席を探して座る。
<現状>
空席にのみエージェントが座る動作はできていますが、目的となる椅子に他エージェントが座っているとき、ほかに空席があるにもかかわらず、座っているエージェントが席から離れるまで席の横で待機してしまいます。
② レジでの待ち行列の作成
<目標>
レジで精算しているエージェントがいるとき、その後ろにエージェントが並んで待機し、列を形成するようにしたい。
<現状>
シミュレーション上での左上に周ってからレジへ向かってしまいます。
幅が1セルの通路にすればできるとは思うのですが、通路の広さによっての回転効率の比較を行いたいと考えているため、幅が1セルより広い状況でも行列を形成するようにしたいですが、方法はありますでしょうか。
ありがとうございます!
⑤は
If Universe.Shop.Floor(My.X,My.Y,0) == 9 Then
Forward(-2 * My.Speed)
End If
で乗りあがった場合に2歩もどることにして解決いたしました。
①の人エージェント同士が重なってしまう問題ですが、「他のCustomerが存在するセルは歩行可能エリアから除外する」コードをコメントアウトしている書き方以外にもいくつか試しましたが、いずれもinit_potential()内に書き入れると、エージェントが予期していないところでたまってしまいます。
この解決策はありますでしょうか。
追記です。
MakeAgtSet(personAgtSet, Universe.Shop.Customer)
For Each oneAgt In personAgtSet
If My.ID <> oneAgt.ID Then
Universe.Shop.Potential(CInt(oneAgt.X),CInt(oneAgt.Y), 0) = -1
End If
Next oneAgt
の部分をコメントアウトすると③は解決しましたが、エージェントの重なりは解決しません。
また、
// 空間上の座標をチェック 歩行可能エリアならPotentialの値を0に0以外なら-1に初期化
For i=0 To GetWidthSpace(Universe.Shop) - 1
For j=0 To GetHeightSpace(Universe.Shop) -1
If Universe.Shop.Floor(i,j,0) == 0 Then
Universe.Shop.Potential(i,j,0) = 0
Else
Universe.Shop.Potential(i,j,0) = -1
End If
Next j
Next i
のように、Potentialの値が0になる歩行可能エリアから椅子を除外した場合、②は解決しました。
また、椅子の上側にテーブルがある席に人エージェントが来た場合、テーブル側に一歩下がってその後動かなくなってしまいます。
椅子の下側や右側にテーブルがある席に人エージェントが来た場合は問題なく、返却口→出口へと向かってくれます。