http://www.boost.org/doc/libs/1_37_0/libs/graph/example/astar-cities.cppにある例から始めて、ブーストA *アルゴリズムで遊んでいます。
そのヒューリスティックとビジターをオーバーライドして、ある種のカスタム調整を行うことができることがわかりましたが、学習例として、次のようなことの概念はまだよくわかりません。アルゴリズムに移動時間 (エッジの重み) が X より大きい場合 (たとえば 100 分) は、エッジ都市 - 都市を選択しないでください。(可能であれば、他のパスが見つからない場合は、パスが見つからない代わりにその都市を選択する必要があります)
その都市を選択しないように「だます」ために、実際よりも長い時間を返すカスタムのヒューリスティック クラスを試しましたが、問題は、このトリックを使用すると、罰せられた都市が破棄され、その後のやり取りでも破棄されることです。(次の例で説明します: B->D はより良いパスが見つかったために破棄されますが、都市 D は破棄されません (次の繰り返しで選択されていることがわかります)
そこで、問題をさらに単純化しました。
enum nodes {
A, B, C, D, E, N
};
const char *name[] = {
"A", "B", "C", "D", "E", "F"
};
edge edge_array[] = {
edge(A,B), edge(B,C),
edge(C,D), edge(D,E),
edge(B,D) // B to D is the problem here, it should be excluded
};
cost weights[] = { // estimated travel time (mins)
// 107, 174, 283, 71, 436
35, 58, 94, 23, 145
};
この例 (元のコードをベースとして使用) では、次のルートが得られます。
開始頂点: A
ゴール頂点:E
A から E への最短経路: A -> B -> D -> E
総移動時間: 204.5
問題は、B -> D パスです。これは非常に長い距離です (たとえば、しきい値が 100 であると仮定すると、A -> B -> C -> D -> E のようなパスが望ましいでしょう)。 、2 つの都市間の距離が 100 を超えていない (もちろん、可能な場合のみ、他にパスがない場合は、いずれかを選択する必要があります)
私はそれを次善の方法で解決しました:カスタム関数は、エッジを追加すると(または手動で重みを設定します)return travelTime > 100 ? travelTime * 2 : travelTime
、次の方法でテストできます:
cost weights[] = { // estimated travel time (mins)
// 107, 174, 283, 71, 436
(35 > 100) ? 35*2 : 35, (58 > 100) ? 58*2 : 58, (94>100) ? 94*2 : 94, 23, (145 > 100) ? 145*2 : 145
}; // The comparisons are not needed, just there to better explain what the custom add_edge function will do.
この方法で目的A -> B -> C -> D -> E
の が得られますが、この方法は問題のハック/回避策であり、内部で入力データを変更するものであり、最善の解決策ではないと思います。
距離/移動時間を手動で変更せずにこれを達成するためのより良い方法はありますか?