Upgrade to Pro — share decks privately, control downloads, hide ads and more …

11. artisocレシピブック_A-star探索アルゴリズムを使って、通れなくなった道路を迂回しよう

250494d00b2f0fdc10fb4a02f01fc7e5?s=47 Masaki Tamada
November 30, 2020

11. artisocレシピブック_A-star探索アルゴリズムを使って、通れなくなった道路を迂回しよう

■最短経路を探索しよう

避難中に道路が通れなかったり、避難所が満杯で入れず、別の避難所へ避難することがあります。
A*探索アルゴリズムは、高速に経路探索できるためおすすめです。

歩行モデルの拡張
 ①「02. artisocレシピブック」のおさらい
 ② A*探索アルゴリズムとは?
 ③ 歩行モデルの定義
 ④ Universeで計算ライブラリを初期化
 ⑤ シミュレーション実行中に道路ネットワークを切断
 ⑥ 複数の歩行者を生成し、目的地までの経路を設定
 ⑦ 歩行者の行動ルールを定義
 ⑧ 道路の拡張

250494d00b2f0fdc10fb4a02f01fc7e5?s=128

Masaki Tamada

November 30, 2020
Tweet

Transcript

  1. http://www.kke.co.jp 株式会社 構造計画研究所 〒164-0012 東京都中野区本町 4-38-13 創造工学部 TEL:03-5342-1125 FAX:03-5342-1225 Copyright

    © KOZO KEIKAKU ENGINEERING Inc. All Rights Reserved. 10. artisocレシピブック A*探索アルゴリズムを使って、通れなくなった道路を回避しよう 本ドキュメントについてのご質問、『複雑系勉強会』の お問合せは、下記までご連絡ください。 (株)構造計画研究所 次世代事業開発部 MAS社会デザイン室 玉田 E-mail: tamada@kke.co.jp
  2. http://www.kke.co.jp Copyright © KOZO KEIKAKU ENGINEERING Inc. All Rights Reserved.

    2 最短経路を探索しよう ◼避難中に道路が通れなかったり、避難所が満杯で入れず、別の避難所へ避難 することがあります。 ◼A*探索アルゴリズムは、高速に経路探索できるためおすすめです。 ・歩行モデルの拡張 ① 「02. artisocレシピブック」のおさらい ② A*探索アルゴリズムとは? ③ 歩行モデルの定義 ④ Universeで計算ライブラリを初期化 ⑤ シミュレーション実行中に道路ネットワークを切断 ⑥ 複数の歩行者を生成し、目的地までの経路を設定 ⑦ 歩行者の行動ルールを定義 ⑧ 道路の拡張
  3. http://www.kke.co.jp Copyright © KOZO KEIKAKU ENGINEERING Inc. All Rights Reserved.

    3 ① 「02. artisocレシピブック」のおさらい ◼「02. artisocレシピブック」で作成した道路に沿って歩くモデル ⚫描画ツールで道路を作成していく方法、歩くモデルの動作原理について学びました。 ◼「02. artisocレシピブック」で作成した歩くモデルの問題点と解決策 ⚫道路ネットワークが単純なときは手作業で経路を指定できますが、複雑になると大変面倒です。 ⚫そこでA*探索アルゴリズムを使って、最短経路を自動的に探索するモデルを作成します。 【Step1】 モデルの定義 • PointエージェントとLinkエージェントを定 義して、描画ツールの前準備をします。 • Personエージェントを定義して、指定し た経路で移動するアルゴリズムを定義し ます。 【Step2】 描画ツールで道路を定義 • 背景画像の道路に沿ってマウスクリックし て、ネットワークを定義します。 【Step3】 動きを確認 • 指定した順番にPointを通ってゴールにた どり着くことを確認します。
  4. http://www.kke.co.jp Copyright © KOZO KEIKAKU ENGINEERING Inc. All Rights Reserved.

    4 ② A*探索アルゴリズムとは? ◼ダイクストラ法とA*探索アルゴリズムの違い ⚫ダイクストラ法: スタートノードから全てのノードへの最短経路を求めます。 ⚫A*探索: ゴールまでの推定値(直線距離など)を元にして、スタートから ゴールに近いと思われる点から順次探索していきます。 ◼A*探索アルゴリズムの手順 ① スタートノードから順次経路を探索していく際に、推定距離を用いてゴー ルまでの距離が短くできそうなノードから優先的に探索していきます。 ② 具体的には、ノードnについて、スタートからノードnまでの距離g(n)と、ノー ドnからゴールまでの推定距離h(n)を計算し、その和であるf(n)を随時更 新していきます。 f(n) = g(n) + h(n) ③ f(n)が近いノードから優先的にその先への探索を実行していきます。 ④ h(n)には直線距離などが用いられます。 ⑤ 最短経路を求めるには、h(n)が、f(n)の更新に用いられる真のリンク間移 動コストと比べて、必ず同じか短くなるよう設定する必要があります(幹 線道路考慮時などはこの点に要注意)。 ⚫A*探索アルゴリズムの詳細については、Wikipediaで調べてみましょう。 s g n g(n) h(n)
  5. http://www.kke.co.jp Copyright © KOZO KEIKAKU ENGINEERING Inc. All Rights Reserved.

    5 ③ 歩行モデルの定義 ◼「Point」「Person」「Link」を右図の通りに追加します。 ⚫「Point」に次の変数を追加します。 変数名: NearAgtSet :エージェント集合型 接続しているPointを格納します。 変数名: ParentPointAgt:エージェント型 親のPointを一時的に格納します。 変数名: g :実数型 gの値を一時的に格納します。 変数名: f :実数型 fの値を一時的に格納します。 ⚫「Person」に次の変数を追加します。 変数名: RouteArray :文字列型 歩行経路を格納(カンマ区切りのPointのID配列) 変数名: RouteCount :整数型 次の目的地の配列数(1以上) 変数名: f :実数型 fの値を一時的に格納します。
  6. http://www.kke.co.jp Copyright © KOZO KEIKAKU ENGINEERING Inc. All Rights Reserved.

    6 ④ Universeで計算ライブラリを初期化 ◼A*探索アルゴリズム計算ライブラリ「a_star.inc」を利用します。 ⚫ツリーの「Universe」を右クリックして、「ルールエディタ」を選択します。 ⚫「Univ_Init」で計算ライブラリを初期化します。 include “a_star.inc” Univ_Init{ ClearConsoleScreen() @set_reverse_link() @set_near_point() } ・・・計算ライブラリを読み込む ・・・コンソール画面をクリアする ・・・リンクを片方向だけ定義している場合、逆方向を設定する ・・・リンクするPointを格納する 【A*探索アルゴリズム計算ライブラリの使い方】 • 「a_star.inc」は、ダイクストラ法で最短経路を探索するための計算ライブラリです。 • 計算ライブラリを利用するためには、Universeの先頭に「include “a_star.inc”」と記述します • リンクを片方向だけ定義している場合、逆方向のリンクを設定するため、「Univ_Init」で、関数 「@set_reverse_link()」を実行してください。 • 「Univ_Init」で、リンクするPointを格納するための関数「@set_near_point()」を実行してください。 • 最短経路を取得するためには、「@a_star_id ([始点のPointID], [目的地のPointID])」の形式で指定しま す。 ※「 a_star.inc 」で定義している関数を呼び出すときは、先頭に「@」をつけます。
  7. http://www.kke.co.jp Copyright © KOZO KEIKAKU ENGINEERING Inc. All Rights Reserved.

    7 ⑤ シミュレーション実行中に道路ネットワークを切断 ◼道路ネットワークを切断します。 ⚫ツリーの「Universe」を右クリックして、「ルールエディタ」を選択します。 Univ_Step_Begin{ If GetCountStep () == 40 Then @cut_link_id(3,26) End If } ・・・40ステップ目でPoint ID=3 と 26 の間のリンクを切断する
  8. http://www.kke.co.jp Copyright © KOZO KEIKAKU ENGINEERING Inc. All Rights Reserved.

    8 ⑥ 複数の歩行者を生成し、目的地までの経路を設定 ◼目的地を目指して、最短経路に沿って進みます。 ⚫ツリーの「Point」を右クリックして、「ルールエディタ」を選択します。 Agt_Step{ Dim startPointID As Integer, goalPointID As Integer Dim personAgt As Agt startPointID = 0 goalPointID = 23 If (My.ID == startPointID And GetCountStep() Mod 10 == 1) And GetCountStep() < 50 Then personAgt = CreateAgt(Universe.Map.Person) personAgt.X = My.X personAgt.Y = My.Y personAgt.RouteArray = @a_star_id(My.ID, goalPointID) personAgt.RouteCount = 1 End If } ・・・出発地のPoint IDを設定する ・・・目的地のPoint IDを設定する ・・・goalPoinIDへの最短経路を取得する
  9. http://www.kke.co.jp Copyright © KOZO KEIKAKU ENGINEERING Inc. All Rights Reserved.

    9 ⑦-1 歩行者の行動ルールを定義 ◼経路に沿って進み、各Pointに到着すると、リンクの接続を確認します。 ⚫ツリーの「Person」を右クリックして、「ルールエディタ」を選択します。 Agt_Step { Dim startPointID As Integer, startPointAgt As Agt Dim targetPointID As Integer, targetPointAgt As Agt Dim distance As Double If My.RouteCount < CountToken(My.RouteArray) Then Do While(True) targetPointID = CInt(GetToken(My.RouteArray, My.RouteCount)) targetPointAgt = Universe.Map.Point(targetPointID) distance = Pursue(targetPointAgt, 1) ・・・経路に沿って進む
  10. http://www.kke.co.jp Copyright © KOZO KEIKAKU ENGINEERING Inc. All Rights Reserved.

    10 ⑦-2 歩行者の行動ルールを定義 If distance > 0 Then My.RouteCount = My.RouteCount + 1 If CountToken(My.RouteArray) > My.RouteCount Then startPointID = CInt(GetToken(My.RouteArray, My.RouteCount - 1)) targetPointID = CInt(GetToken(My.RouteArray, My.RouteCount)) If @check_link_id(startPointID, targetPointID) == False Then add_new_route() Else Break End If Else PrintLn("ゴールに到着!") Break End If Else Break End If Loop End If } ・・・Pointに到着したとき ・・・リンクの接続を確認する ・・・リンクが接続していない場 合は、新しい経路を探索する
  11. http://www.kke.co.jp Copyright © KOZO KEIKAKU ENGINEERING Inc. All Rights Reserved.

    11 ⑦-3 歩行者の行動ルールを定義 Sub add_new_route() { Dim startPointID As Integer, goalPointID As Integer Dim lastRoute As String, newRoute As String Dim i As Integer lastRoute = "" newRoute = "" For i=0 To My.RouteCount - 2 lastRoute = lastRoute & GetToken(My.RouteArray, i) & "," Next i lastRoute = Left(lastRoute, Len(lastRoute) - 1) ・・・これまでにたどった経路を取得する
  12. http://www.kke.co.jp Copyright © KOZO KEIKAKU ENGINEERING Inc. All Rights Reserved.

    12 ⑦-4 歩行者の行動ルールを定義 startPointID = CInt(GetToken(My.RouteArray, My.RouteCount - 1)) goalPointID = CInt(GetToken(My.RouteArray, CountToken(My.RouteArray)-1)) If startPointID <> goalPointID Then newRoute = @a_star_id(startPointID, goalPointID) If CountToken(newRoute) == 0 Then PrintLn("目的地へ到達するルートがありません") End If End If If Len(newRoute) > 0 Then My.RouteArray = lastRoute & "," & newRoute Else My.RouteArray = lastRoute End If } ・・・新しい経路を取得する ・・・どの経路をたどってもゴール に到達できない場合はメッセー ジ表示する ・・・これまで辿った経路と新し い経路をを連結する
  13. http://www.kke.co.jp Copyright © KOZO KEIKAKU ENGINEERING Inc. All Rights Reserved.

    13 ⑧ 道路の拡張 ◼道路を拡張します。 ⚫ツリーの「Map」を右クリックして「初期値設定」を選択し、描画ツールを表示します。 ⚫道路ネットワークを自由に拡張してください。 11.model