00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef LEMON_SUURBALLE_H
00018 #define LEMON_SUURBALLE_H
00019
00023
00024
00025 #include <lemon/maps.h>
00026 #include <vector>
00027 #include <lemon/min_cost_flow.h>
00028
00029 namespace lemon {
00030
00033
00057 template <typename Graph, typename LengthMap>
00058 class Suurballe{
00059
00060
00061 typedef typename LengthMap::Value Length;
00062
00063 typedef typename Graph::Node Node;
00064 typedef typename Graph::NodeIt NodeIt;
00065 typedef typename Graph::Edge Edge;
00066 typedef typename Graph::OutEdgeIt OutEdgeIt;
00067 typedef typename Graph::template EdgeMap<int> EdgeIntMap;
00068
00069 typedef ConstMap<Edge,int> ConstMap;
00070
00071 const Graph& G;
00072
00073 Node s;
00074 Node t;
00075
00076
00077
00078 ConstMap const1map;
00079
00080 MinCostFlow<Graph, LengthMap, ConstMap> min_cost_flow;
00081
00082
00083 std::vector< std::vector<Edge> > paths;
00084
00085 public :
00086
00087
00095 Suurballe(Graph& _G, LengthMap& _length, Node _s, Node _t) :
00096 G(_G), s(_s), t(_t), const1map(1),
00097 min_cost_flow(_G, _length, const1map, _s, _t) { }
00098
00100
00108 int run(int k) {
00109 int i = min_cost_flow.run(k);
00110
00111
00112
00113
00114
00115
00116
00117
00118 EdgeIntMap reversed(G);
00119
00120 for(typename Graph::EdgeIt e(G); e!=INVALID; ++e)
00121 reversed[e] = min_cost_flow.getFlow()[e];
00122
00123 paths.clear();
00124 paths.resize(k);
00125 for (int j=0; j<i; ++j){
00126 Node n=s;
00127
00128 while (n!=t){
00129
00130 OutEdgeIt e(G, n);
00131
00132 while (!reversed[e]){
00133 ++e;
00134 }
00135 n = G.target(e);
00136 paths[j].push_back(e);
00137 reversed[e] = 1-reversed[e];
00138 }
00139
00140 }
00141 return i;
00142 }
00143
00144
00146
00148 Length totalLength(){
00149 return min_cost_flow.totalLength();
00150 }
00151
00153
00155 const EdgeIntMap &getFlow() const { return min_cost_flow.flow;}
00156
00158
00161 const EdgeIntMap &getPotential() const { return min_cost_flow.potential;}
00162
00164
00169 bool checkComplementarySlackness(){
00170 return min_cost_flow.checkComplementarySlackness();
00171 }
00172
00174
00185 template<typename Path>
00186 void getPath(Path& p, size_t j){
00187
00188 p.clear();
00189 if (j>paths.size()-1){
00190 return;
00191 }
00192 typename Path::Builder B(p);
00193 for(typename std::vector<Edge>::iterator i=paths[j].begin();
00194 i!=paths[j].end(); ++i ){
00195 B.pushBack(*i);
00196 }
00197
00198 B.commit();
00199 }
00200
00201 };
00202
00204
00205 }
00206
00207 #endif //LEMON_SUURBALLE_H