// 名前付きパラメータバージョン template <class EdgeListGraph, class Size, class P, class T, class R> bool bellman_ford_shortest_paths(EdgeListGraph& g, Size N, const bgl_named_params<P, T, R>& params = all defaults) // 名前無しパラメータバージョン template <class EdgeListGraph, class Size, class WeightMap, class PredecessorMap, class DistanceMap, class BinaryFunction, class BinaryPredicate, class BellmanFordVisitor> bool bellman_ford_shortest_paths(EdgeListGraph& g, Size N, WeightMap weight, PredecessorMap pred, DistanceMap distance, BinaryFunction combine, BinaryPredicate compare, BellmanFordVisitor v)
Bellman-Ford アルゴリズム [4,11,20,8] は、正と負の両方の辺の重みを持つ グラフの単一始点の最短経路問題を解く。最短経路問題の定義のために、 章 Shortest-Paths Algorithms を見なさい。 もし正の辺の重みを持つ最短経路問題を解く必要があるだけなら、Dijkstra の アルゴリズムがより効率的な代替手段を提供する。もし全ての辺の重みが 1 に 等しいなら幅優先探索がより一層効率的な代替手段を提供する。
bellman_ford_shortest_paths() 関数を呼ぶ前に、ユーザは始点に 0 の 距離を割り当て、他の全ての頂点に無限大の距離を割り当てなければならない。 Bellman-Ford アルゴリズムはグラフ中の全ての辺を通してループし、各辺に リラックス操作 (減らす操作) を適用する事によって進められる。下記の擬似コード中で、 v は u の隣接頂点で、w は辺にそれらの重みをマップし、 d は今の所見られる各辺への最短経路の長さを記録する距離マップ である。p は各辺の親を記録する先行点マップで、それは結局最短経路木中 で親となるであろう。
RELAX(u, v, w, d, p) if (w(u,v) + d[u] < d[v]) d[v] := w(u,v) + d[u] p[v] := u else ... |
辺をリラックスする (減らす) (u,v) 辺 (u,v) は リラックスされていない (減らされていない) |
アルゴリズムはグラフ中に負の閉路が存在しないならば、各辺への距離が 可能な限り最小に減らされた事が保証された後にこのループを |V| 回 繰り返す。もし負の閉路が存在するならば、グラフ中に適当に最小化されない 辺が存在する事になるだろう。つまり、w(u,v) + d[u] < d[v] であるような 辺 (u,v) が存在することになるだろう。 アルゴリズムは全ての辺が最小化されたかどうか最後に一回調べる ためにグラフ中の辺をループし、もしよければ true を返し、そうでなければ false を返す。
BELLMAN-FORD(G) for each vertex u in V d[u] := infinity p[u] := u end for for i := 1 to |V|-1 for each edge (u,v) in E RELAX(u, v, w, d, p) end for end for for each edge (u,v) in E if (w(u,v) + d[u] < d[v]) return (false, , ) else ... end for return (true, p, d) |
頂点 u の初期化 辺 (u,v) の調査 辺 (u,v) は最小化されていない 辺 (u,v) は最小化されている |
型が Edge List Graph のモデルの 有向グラフまたは無向グラフでなければならない。IN: Size N
グラフ中の頂点の数。型 Size は汎整数型でなければならない。
グラフ中の各辺の重み (そして“長さ”もしくは“コスト”として知られる)。 WeightMap の型は Readable Property Map のモデルでなければならない。このプロパティ・マップのキー型は グラフの辺記述子でなければならない。重みマップの値型は距離マップの値型を伴った Addable でなければならない。OUT: predecessor_map(PredecessorMap p_map)
デフォルト: get(edge_weight, g)
先行点マップ (predecessor map) は最小全域木中に辺を記録する。 アルゴリズムの完了時に、V 中の全ての u のための辺 (p[u],u) は最小全域木中にある。もし p[u] = u なら u は始点かまたは始点 から到達不能な頂点である。 PredecessorMap の型はキーと頂点の型がグラフの頂点記述子型と同じ Read/Write Property Map でなければならない。IN/OUT: distance_map(DistanceMap d)
デフォルト: dummy_property_map
グラフ g 中の始点から各頂点への最短経路の重みは、このプロパティ・マップ 中に記録される。DistanceMap の型は Read/Write Property Map のモデルでなければならない。プロパティ・マップのキー型は グラフの頂点記述子型でなければならず、距離マップの値型は Less Than Comparable でなければならない。IN: visitor(BellmanFordVisitor v)
デフォルト: get(vertex_distance, g)
ビジタ・オブジェクトで、その型は Bellman-Ford Visitor のモデルで なければならない。ビジタ・オブジェクトは値渡しされる [1]。IN: distance_combine(BinaryFunction combine)
デフォルト: bellman_visitor<null_visitor>
この関数オブジェクトはリラックス (減少) 段階中で、加算の役割を置き換える。 第一引数の型は距離マップの値型に一致していなければならず、 第二引数の型は重みマップの値型に一致していなければならない。 結果型は距離マップの値型と同じでなければならない。IN: distance_compare(BinaryPredicate compare)
デフォルト:std::plus<D> ここに D=typename property_traits<DistanceMap>::value_type.
この関数オブジェクトはリラックス (減少) 段階中で、距離を比較する less-than (<) 演算子の役割を置き換える。引数の型は距離マップの値型に一致して いなければならない。
デフォルト: std::less<D> ここに D=typename property_traits<DistanceMap>::value_type.
時間複雑性は O(V E) である。
Bellman-Ford のアルゴリズムを用いた例が examples/bellman-example.cpp 中にある。
[1]
ビジタのパラメータは値渡しされるので、もしビジタが状態を持っているなら、
アルゴリズムの間のいかなる状態の変更も、送ったビジタ・オブジェクトには行われず
ビジタ・オブジェクトのコピーに対して行われる。それゆえポインタまたは
リファレンスによってこの状態をビジタに保持させる事を望むかもしれない。
Copyright © 2000 | Jeremy Siek, Indiana University (jsiek@osl.iu.edu) |
Japanese Translation Copyright © 2003 Takashi Itou
オリジナルの、及びこの著作権表示が全ての複製の中に現れる限り、この文書の複製、利用、変更、販売そして配布を認める。このドキュメントは「あるがまま」に提供されており、いかなる明示的、暗黙的保証も行わない。また、いかなる目的に対しても、その利用が適していることを関知しない。
このドキュメントの対象: Boost Version 1.29.0
最新版ドキュメント (英語)