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::ValueType 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
00072
const Graph& G;
00073
00074
00075
00076
ConstMap const1map;
00077
00078
MinCostFlow<Graph, LengthMap, ConstMap> mincost_flow;
00079
00080
00081 std::vector< std::vector<Edge> > paths;
00082
00083
public :
00084
00085
00087
00090 Suurballe(Graph& _G, LengthMap& _length) : G(_G),
00091 const1map(1), mincost_flow(_G, _length, const1map){}
00092
00094
00103 int run(Node s, Node t,
int k) {
00104
00105
int i = mincost_flow.
run(s,t,k);
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115 EdgeIntMap reversed(G);
00116
00117
for(
typename Graph::EdgeIt e(G); e!=
INVALID; ++e)
00118 reversed[e] = mincost_flow.
getFlow()[e];
00119
00120 paths.clear();
00121
00122 paths.resize(k);
00123
for (
int j=0; j<i; ++j){
00124 Node n=s;
00125 OutEdgeIt e;
00126
00127
while (n!=t){
00128
00129
00130 G.first(e,n);
00131
00132
while (!reversed[e]){
00133 ++e;
00134 }
00135 n = G.head(e);
00136 paths[j].push_back(e);
00137
00138 reversed[e] = 1-reversed[e];
00139 }
00140
00141 }
00142
return i;
00143 }
00144
00145
00147
00151 Length
totalLength(){
00152
return mincost_flow.
totalLength();
00153 }
00154
00156
00160 const EdgeIntMap &
getFlow()
const {
return mincost_flow.
flow;}
00161
00163
00167 const EdgeIntMap &
getPotential()
const {
return mincost_flow.
potential;}
00168
00170
00177 bool checkComplementarySlackness(){
00178
return mincost_flow.
checkComplementarySlackness();
00179 }
00180
00182
00193
template<
typename Path>
00194 void getPath(Path& p, size_t j){
00195
00196 p.clear();
00197
if (j>paths.size()-1){
00198
return;
00199 }
00200
typename Path::Builder B(p);
00201
for(
typename std::vector<Edge>::iterator i=paths[j].begin();
00202 i!=paths[j].end(); ++i ){
00203 B.pushBack(*i);
00204 }
00205
00206 B.commit();
00207 }
00208
00209 };
00210
00212
00213 }
00214
00215
#endif //LEMON_SUURBALLE_H