Más contenido relacionado
La actualidad más candente (6)
Similar a 08. artisocレシピブック ダイクストラ法を高速化しよう (20)
Más de Masaki Tamada (10)
08. artisocレシピブック ダイクストラ法を高速化しよう
- 1. http://www.kke.co.jp
株式会社 構造計画研究所
〒164-0012 東京都中野区本町 4-38-13 創造工学部 TEL:03-5342-1125 FAX:03-5342-1225
Copyright © 2015 KOZO KEIKAKU ENGINEERING Inc. All Rights Reserved.
08. artisocレシピブック
ダイクストラ法を高速化しよう
本ドキュメントについてのご質問、『複雑系勉強会』の
お問合せは、下記までご連絡ください。
(株)構造計画研究所
社会デザイン・マーケティング部
artisocマーケティング担当 玉田
Tel: 052-222-8461
E-mail: tamada@kke.co.jp
- 2. http://www.kke.co.jpCopyright © 2004 KOZO KEIKAKU ENGINEERING Inc. All Rights Reserved.
2
ダイクストラ法を高速化しよう
道路網が大きく複雑なとき、最短経路を探索するには時間がかかります。
前もって全経路を計算しておくことで、シミュレーション時間を短縮することができ
ます。
・歩行モデルの拡張
① 「03. artisocレシピブック」のおさらい
② 歩行モデルの拡張
③ 全経路探索の処理を追加
④ 全探索ファイルの入出力
⑤ 最短経路の取得方法を変更
⑥ 道路を追加したとき
- 3. http://www.kke.co.jpCopyright © 2004 KOZO KEIKAKU ENGINEERING Inc. All Rights Reserved.
3
① 「03. artisocレシピブック」のおさらい
「03. artisocレシピブック」で作成した道路に沿って歩くモデル
ダイクストラ法を使って、最短経路を探索する方法について学びました。
「03. artisocレシピブック」で作成した歩くモデルの問題点と解決策
GISデータ等から道路網を作成すると細かい分岐が多く、最短経路を探索するには時間がかか
ります。
全ての道路について事前にダイクストラ法を使って最短経路を探索してファイル保存します。
次回のシミュレーションでは、計算済ファイルを読み込むことで、シミュレーションを高速化します。
• 描画ツールを使って設定した道路
を最短経路を通って移動します。
- 4. http://www.kke.co.jpCopyright © 2004 KOZO KEIKAKU ENGINEERING Inc. All Rights Reserved.
4
② 歩行モデルの拡張
「PathDijkstra」を追加します。
「Universe」に次の変数を追加します。
変数名: PathDijkstra :文字列型
次元数: 2
1次元目の配列数: 100
2次元目の配列数: 100
最短経路を格納します。
- 5. http://www.kke.co.jpCopyright © 2004 KOZO KEIKAKU ENGINEERING Inc. All Rights Reserved.
5
③ 全経路探索の処理を追加(1)
全経路探索の計算有無をチェックします。
ツリーの「Universe」を右クリックして、「ルールエディタ」を選択します。
「Univ_Init」で計算有無をチェックし、存在しない場合は、ライブラリ「dijkstra.inc」の関数を実行
して、「Universe.PathDijkstra」に探索結果を保持します。
Univ_Init{
initialize_dijkstra()
check_path_dijkstra()
}
・・・計算ライブラリを初期化する
・・・全経路探索の計算有無をチェックする
Sub check_path_dijkstra()
{
If (OpenFile("path_dijkstra.csv",0,FILE_READ)) Then
file_read_path_dijkstra()
CloseFile(0)
Else
all_path_dijkstra()
file_write_path_dijkstra()
End If
}
・・・全経路ファイルの存在を確認する
・・・存在するときはファイルを読み込む
・・・ファイルをクローズする
・・・存在しないときは計算する
・・・全経路ファイルを書き出す
- 6. http://www.kke.co.jpCopyright © 2004 KOZO KEIKAKU ENGINEERING Inc. All Rights Reserved.
6
③ 全経路探索の処理を追加(2)
Sub all_path_dijkstra()
{
Dim i As Integer
Dim j As Integer
For i=0 To CountAgt(Universe.Map.Point) - 1
For j=i To CountAgt(Universe.Map.Point) - 1
If i <> j Then
Universe.PathDijkstra(i, j) = @dijkstra(i, CStr(j))
Universe.PathDijkstra(j, i) = reverse_array(Universe.PathDijkstra(i, j))
Else
Universe.PathDijkstra(i, j) = ""
End If
Next j
Next i
}
・・・ライブラリの関数「dijkstra」で計算する
・・・逆順路の場合は
経路を逆にたどる
・・・始点と終点が同じときは経路なし
- 7. http://www.kke.co.jpCopyright © 2004 KOZO KEIKAKU ENGINEERING Inc. All Rights Reserved.
7
③ 全経路探索の処理を追加(3)
Function reverse_array(tokenArray As String) As String
{
Dim reverseArray As String
Dim i As Integer
reverseArray = ""
If CountToken(tokenArray) > 0 Then
For i=0 To CountToken(tokenArray) - 1
reverseArray = GetToken(tokenArray, i) & "," & reverseArray
Next i
reverseArray = Left(reverseArray, Len(reverseArray) - 1)
End If
Return(reverseArray)
}
・・・カンマ区切りの文字列を
逆順に並べて返す
- 8. http://www.kke.co.jpCopyright © 2004 KOZO KEIKAKU ENGINEERING Inc. All Rights Reserved.
8
④ 全経路ファイルの入出力(1)
全経路ファイルを入出力します。
ツリーの「Universe」を右クリックして、「ルールエディタ」を選択します。
Sub file_write_path_dijkstra()
{
Dim outString As String
Dim i As Integer
Dim j As Integer
If (OpenFile("path_dijkstra.csv",10,FILE_WRITE)) Then
For i=0 To CountAgt(Universe.Map.Point) - 1
For j=0 To CountAgt(Universe.Map.Point) - 1
outString = CStr(i) & "," & CStr(j) & "," & Replace(Universe.PathDijkstra(i, j), ",", " ")
WriteLnFile(10, outString)
Next j
Next i
Else
Println(GetLastErrorMsg())
ExitSimulation()
End If
CloseFile(10)
}
・・・ファイルをオープンする
・・・i, j, (I,j)の最短経路を出力する
・・・エラーの時はメッセージを表示して
シミュレータを終了する
・・・ファイルをクローズする
- 9. http://www.kke.co.jpCopyright © 2004 KOZO KEIKAKU ENGINEERING Inc. All Rights Reserved.
9
④ 全経路ファイルの入出力(2)
Sub file_read_path_dijkstra()
{
Dim inData As String
Dim i As Integer
Dim j As Integer
If (OpenFile("path_dijkstra.csv",1,FILE_READ)) Then
Do Until(IsEofFile(1) == True)
inData = ReadFile(1)
i = CInt(GetToken(inData, 0))
j = CInt(GetToken(inData, 1))
Universe.PathDijkstra(i,j) = Replace(GetToken(inData, 2), " ", ",")
Loop
CloseFile(1)
Else
Println(GetLastErrorMsg())
End If
}
・・・ファイルをオープンする
・・・1行読み込む
・・・0番めのトークンを取得し、iとする
・・・1番めのトークンを取得し、jとする
・・・2番めのトークンを配列番号(I,j)の
位置に格納する
- 10. http://www.kke.co.jpCopyright © 2004 KOZO KEIKAKU ENGINEERING Inc. All Rights Reserved.
10
⑤ 最短経路の取得方法を変更(1)
「Universe.PathDijkstra」から最短経路を取得します。
ツリーの「Point」を右クリックして、「ルールエディタ」を選択します。
Agt_Init{
Dim personAgt As Agt
Dim nearPointAgt As Agt
If My.ID == 0 And GetCountStep() < 5 Then
personAgt = CreateAgt(Universe.Map.Person)
personAgt.X = My.X
personAgt.Y = My.Y
If CountAgtSet(My.NearAgtSet) > 0 Then
nearPointAgt = GetAgt(My.NearAgtSet, Cint(Rnd() * CountAgtSet(My.NearAgtSet)))
personAgt.RouteArray = Universe.PathDijkstra(My.ID,nearPointAgt.ID)
personAgt.RouteCount = 1
Else
personAgt.RouteArray = CStr(My.ID)
personAgt.RouteCount = 0
End If
End If
}
・・・配列変数から最短
経路を取得する
- 11. http://www.kke.co.jpCopyright © 2004 KOZO KEIKAKU ENGINEERING Inc. All Rights Reserved.
11
⑤ 最短経路の取得方法を変更(2)
「Universe.PathDijkstra」から最短経路を取得します。
ツリーの「Person」を右クリックして、「ルールエディタ」を選択します。
Sub add_new_route(targetPointAgt As Agt)
{
Dim newTargetPointAgt As Agt
Dim newRoute As String
newRoute = “”
newTargetPointAgt = Universe.Map.Point(CInt(Rnd() * CountAgt(Universe.Map.Point)))
If ((targetPointAgt.ID <> newTargetPointAgt.ID) Then
newRoute = Universe.PathDijkstra(targetPointAgt.ID, newTargetPointAgt.ID)
End If
If Len(newRoute) > 0 Then
My.RouteArray = My.RouteArray & "," & newRoute
End If
}
・・・配列変数から最短
経路を取得する
- 12. http://www.kke.co.jpCopyright © 2004 KOZO KEIKAKU ENGINEERING Inc. All Rights Reserved.
12
⑥ 道路を変更したとき
モデルを実行すると、1回目は全経路探索するため、初期化に時間がかかります。
モデルと同じフォルダに「path_dijkstra.csv」が保存されます。
2回目にモデルを実行したときは、ファイルを読み込むだけなので、高速にシミュレーションが
実行できます。
歩行者エージェントの数が多いときも、再探索の度に計算を行わないため、高速化されます。
もし、道路情報を変更した場合は、「path_dijkstra.csv」を削除して、実行してください。
08.model