まず、クライアントに関するすべての座標系:
ダイヤモンドは、李Leidaが表示されるゲームの座標であるクライアントが使用する単位格子です。クライアントのアイソメトリック視点は、3Dシーン・マップの平面の効果をシミュレートすることができますダイヤモンドグリッドを使用して、採用します。赤い長方形は、クライアントとサーバユーティリティグリッド座標です。
寻路方法入口:BOOL StartFindPath(CPOSベクトル<Cvector2f>・パス、CPOSを終了、開始、INT IgnoreSteps、INT N比、BOOL bAnyDir、INT nMaxStep)
(ここでは説明し、次の特定の経路探索を達成するための知識とA *経路探索アルゴリズムダイクストラに関連する最短時間は詳細にこれらの両方を行うことはありません。)
起動して、すべての画素を開始点と終了点を経路探索終了。参照パラメータの経路、経路探索結果を記憶します。仕上げから少数の細胞を停止することができます仕上げからの細胞の数を、無視するIgnoreSteps。A *アルゴリズムのタイムアウト時間の経路探索の使用を制限するために、ステップの最大数であるの経路探索nMaxSteps。
正常な戻りは真経路探索「の行変曲セットは」(すなわち、隣接する点の間の直線にはコミュニケーションの障壁ではない、任意の非隣接2点を直線通信ない)パスに格納されています。それ以外の場合はfalseを返します。
StartFindPathの経路探索プロセス:
始点と終点が直線LinePathと通信することができるかどうかをまず()試験:
(1)LinePathシーンにおける始点ことを確認する必要があり、エンドポイントパラメータを直接開始は、屋外シーンの座標返します。
(2)次に、一般的に高い障壁(典型的には地形高い障壁、文字とモンスターが存在するかどうかを決定する所有開始から終了まで(すなわち、前記ダイヤモンド格子上)トラバーサルを最小単位の開始点とフォーカス方向座標から直線を描きます低障壁)、真の成功リターン、それ以外の場合は、最初の障害に遭遇グリッドを返します。
2.直線は、シーンを超えていない場合は、入力パラメータの開始点と終了点をチェックし、成功せずにその方法を見つけた場合。
3. Aを入力します*経路探索アルゴリズムFindPath():
(1)直接同じ開始点と終了点かどうかを確認-1。
(2)は、出発点におけるオープンリストに追加されます。
まで、(3)ループの動作が実行されるオープンリストが空であるか、エンドノードに移動 又は経路探索ステップの最大数を超えています。
オープンリスト中の総コスト= G + H(ノードの最小の総コスト値をI.見つけて除去し; Gは、ノードに始点から費やされ; Hは、その点からコストが.Hで使用の終了点と推定されますエンドポイントへのノードから「マンハッタン距離」推定コスト、差分値の水平および垂直座標の式:H = ABS(start.x-end.x)+ ABS(start.y-end.y))。
。II隣接する8つの処理ノードトラバーサルの方向に、新しいノードが格納されているオープンリストを介して到達可能でない場合に直接添加し、それ以外の場合、プロセスか否かをチェックノードが小さい場合、Gは、小さいへの新しいノードそれはノードのフロントを更新するのにかかると、オープンリストの順序を再調整します。
A *アルゴリズムのプロセスの三つの重要なデータ構造を実現します:
(1)XPS_Node:ノード位置、コンテンツコストG、H、およびノードなどに到着費やさプレノードを含むノードの記憶場所の構造。
(2)XPS_Node ** m_pOpenList:最小スタックと重みを行うための総コストを比較するために実装アレイ。
(3)XPS_Node * m_aBacket:追加ハッシュテーブルXPS_Nodeを記録するためのオープンリストを、ハッシュ値は、x、y座標値によって計算され、解決ハッシュ衝突は、同一のハッシュ値がXPS_Nodeにリスト構造に格納されています同じ配列の添字に。
4. A *経路探索が成功しなかった場合は、次のダイクストラの最短経路アルゴリズムを入力します。
(両方のファイルは、各ウェルの頂点のマップ座標と隣接する頂点間の距離に予め設定された)地図データディレクトリ(1)負荷に対応するpathlink.csv roadPoint.csv、ダイクストラ法は、図を必要と構築。
(2)頂点に最も近い開始と終了から距離を見つけ、線形通信それが可能です。ダイクストラのような2つの頂点が開始し、図で終わります。
(3)N回以下ループ。
I.は、最小コストのノードのノードを見つけるために到着し、次の無視を探すときのポイントをマーク。
II。すべてのノードをチェックし、隣接頂点ノードをノードに対してその隣接ノードに到達するのに要するより少ない(コスト[ノード] +リンク[ノード] [I] <コスト[i])と、更新がある場合でありますそれは、そのコストとその前身のノードセットのノードに到達しました。
5.ダイクストラ経路探索は、(このステップは、時間がかかり、非常に深刻な選手が重要になりますしばしばある経路探索*失敗した(無csvファイルまたは開始/終了に直接接続された頂点などを見つけることができません)Aの広い範囲を行って、その後、場合経路探索遅延)。
(破線で示さする頂点通信を見つけるために出発点として、直線であってもよい。ダイクストラ青色実線経路を得るために)
行うには、コードを最適化するための方法を見つけるには:
1.ダイクストラアルゴリズムは、ヒープの使用を最適化するには:
元の実装では、すべてのノードがトラバースすることによって得られると、最小のコストを探して各ノード工程。O(logN個)まで、各ノードはO(N)の複雑さにより、最小コストを見つけるために、ストレージノードに到達するために最小ヒープを取ることができます。(私は最小ヒープがキューPRIORITY_QUEUE STD優先順位を直接使用することである達成するためにここにいます)。
ダイクストラのアルゴリズムを使用して経路探索する場合2.最初のステップは、図面内のすべての頂点を横断している頂点は、ラインの開始、終了位置と通信することができる見つけること。必要性を直線的に、この条件、それはおそらく失敗しているグリッドに多くの障害の周りに存在するので、開始/終了点を伝えているので、非常に時間がかかり、以下の経路探索Aの広い範囲*に。したがって、これらのステップに:線形通信が失敗し、(より小さな範囲内のステップの数タイムアウト限界)直線距離A *アルゴリズムの複数の最も近い頂点の開始/終了点を使用して見つける、図ダイクストラの開始と終了を決定しました。
いくつかのテストの結果について:ここでは巨大**バレーマップ(Dまたはその上の地図カバーの特定名)は、次のとおりです。
出発点 |
終了 |
元の時間がかかります |
最適化した後、 |
(79,42) |
(570,1097) |
151ms |
26MS |
(17,1104) |
(538,13) |
114ms |
32ms |
(246,47) |
(625,688) |
97ms |
23ms |
(577,808) |
(295,584) |
31ms |
29ms |
(36,105) |
(419,910) |
39ms |
39ms |
(625,373) |
(6,203) |
28ms |
27ms |
上述优化有些限制,就是需要寻路地图要要有相应的csv地图,并且有数量可观的结点,否则起不到较好的优化效果。而且第一步的Dijkstra算法的堆优化的实际作用并不大,毕竟数据量有限。