| 1 | // -*- c++ -*- | 
|---|
| 2 | #ifndef HUGO_GRAPH_WRAPPER_H | 
|---|
| 3 | #define HUGO_GRAPH_WRAPPER_H | 
|---|
| 4 |  | 
|---|
| 5 | ///\ingroup gwrappers | 
|---|
| 6 | ///\file | 
|---|
| 7 | ///\brief Several graph wrappers. | 
|---|
| 8 | /// | 
|---|
| 9 | ///This file contains several useful graph wrapper functions. | 
|---|
| 10 | /// | 
|---|
| 11 | ///\author Marton Makai | 
|---|
| 12 |  | 
|---|
| 13 | #include <hugo/invalid.h> | 
|---|
| 14 | #include <hugo/maps.h> | 
|---|
| 15 | #include <iostream> | 
|---|
| 16 |  | 
|---|
| 17 | namespace hugo { | 
|---|
| 18 |  | 
|---|
| 19 |   // Graph wrappers | 
|---|
| 20 |  | 
|---|
| 21 |   /// \addtogroup gwrappers | 
|---|
| 22 |   /// A main parts of HUGOlib are the different graph structures,  | 
|---|
| 23 |   /// generic graph algorithms, graph concepts which couple these, and  | 
|---|
| 24 |   /// graph wrappers. While the previous ones are more or less clear, the  | 
|---|
| 25 |   /// latter notion needs further explanation. | 
|---|
| 26 |   /// Graph wrappers are graph classes which serve for considering graph  | 
|---|
| 27 |   /// structures in different ways. A short example makes the notion much  | 
|---|
| 28 |   /// clearer.  | 
|---|
| 29 |   /// Suppose that we have an instance \c g of a directed graph | 
|---|
| 30 |   /// type say \c ListGraph and an algorithm  | 
|---|
| 31 |   /// \code template<typename Graph> int algorithm(const Graph&); \endcode  | 
|---|
| 32 |   /// is needed to run on the reversely oriented graph.  | 
|---|
| 33 |   /// It may be expensive (in time or in memory usage) to copy  | 
|---|
| 34 |   /// \c g with the reverse orientation.  | 
|---|
| 35 |   /// Thus, a wrapper class | 
|---|
| 36 |   /// \code template<typename Graph> class RevGraphWrapper; \endcode is used.  | 
|---|
| 37 |   /// The code looks as follows | 
|---|
| 38 |   /// \code | 
|---|
| 39 |   /// ListGraph g; | 
|---|
| 40 |   /// RevGraphWrapper<ListGraph> rgw(g); | 
|---|
| 41 |   /// int result=algorithm(rgw); | 
|---|
| 42 |   /// \endcode | 
|---|
| 43 |   /// After running the algorithm, the original graph \c g  | 
|---|
| 44 |   /// remains untouched. Thus the graph wrapper used above is to consider the  | 
|---|
| 45 |   /// original graph with reverse orientation.  | 
|---|
| 46 |   /// This techniques gives rise to an elegant code, and  | 
|---|
| 47 |   /// based on stable graph wrappers, complex algorithms can be  | 
|---|
| 48 |   /// implemented easily.  | 
|---|
| 49 |   /// In flow, circulation and bipartite matching problems, the residual  | 
|---|
| 50 |   /// graph is of particular importance. Combining a wrapper implementing  | 
|---|
| 51 |   /// this, shortest path algorithms and minimum mean cycle algorithms,  | 
|---|
| 52 |   /// a range of weighted and cardinality optimization algorithms can be  | 
|---|
| 53 |   /// obtained. For lack of space, for other examples,  | 
|---|
| 54 |   /// the interested user is referred to the detailed documentation of graph  | 
|---|
| 55 |   /// wrappers.  | 
|---|
| 56 |   /// The behavior of graph wrappers can be very different. Some of them keep  | 
|---|
| 57 |   /// capabilities of the original graph while in other cases this would be  | 
|---|
| 58 |   /// meaningless. This means that the concepts that they are a model of depend  | 
|---|
| 59 |   /// on the graph wrapper, and the wrapped graph(s).  | 
|---|
| 60 |   /// If an edge of \c rgw is deleted, this is carried out by  | 
|---|
| 61 |   /// deleting the corresponding edge of \c g. But for a residual  | 
|---|
| 62 |   /// graph, this operation has no sense.  | 
|---|
| 63 |   /// Let we stand one more example here to simplify your work.  | 
|---|
| 64 |   /// wrapper class | 
|---|
| 65 |   /// \code template<typename Graph> class RevGraphWrapper; \endcode  | 
|---|
| 66 |   /// has constructor  | 
|---|
| 67 |   /// <tt> RevGraphWrapper(Graph& _g)</tt>.  | 
|---|
| 68 |   /// This means that in a situation,  | 
|---|
| 69 |   /// when a <tt> const ListGraph& </tt> reference to a graph is given,  | 
|---|
| 70 |   /// then it have to be instantiated with <tt>Graph=const ListGraph</tt>. | 
|---|
| 71 |   /// \code | 
|---|
| 72 |   /// int algorithm1(const ListGraph& g) { | 
|---|
| 73 |   ///   RevGraphWrapper<const ListGraph> rgw(g); | 
|---|
| 74 |   ///   return algorithm2(rgw); | 
|---|
| 75 |   /// } | 
|---|
| 76 |   /// \endcode | 
|---|
| 77 |  | 
|---|
| 78 |   /// \addtogroup gwrappers | 
|---|
| 79 |   /// @{ | 
|---|
| 80 |  | 
|---|
| 81 |   ///Base type for the Graph Wrappers | 
|---|
| 82 |  | 
|---|
| 83 |   ///\warning Graph wrappers are in even more experimental state than the other | 
|---|
| 84 |   ///parts of the lib. Use them at you own risk. | 
|---|
| 85 |   /// | 
|---|
| 86 |   ///This is the base type for the Graph Wrappers. | 
|---|
| 87 |   ///\todo Some more docs...  | 
|---|
| 88 |   /// | 
|---|
| 89 |   ///\author Marton Makai  | 
|---|
| 90 |   template<typename Graph> | 
|---|
| 91 |   class GraphWrapper { | 
|---|
| 92 |   protected: | 
|---|
| 93 |     Graph* graph; | 
|---|
| 94 |     GraphWrapper() : graph(0) { } | 
|---|
| 95 |     void setGraph(Graph& _graph) { graph=&_graph; } | 
|---|
| 96 |  | 
|---|
| 97 |   public: | 
|---|
| 98 |     typedef Graph BaseGraph; | 
|---|
| 99 |     typedef Graph ParentGraph; | 
|---|
| 100 |  | 
|---|
| 101 |     GraphWrapper(Graph& _graph) : graph(&_graph) { } | 
|---|
| 102 |     GraphWrapper(const GraphWrapper<Graph>& gw) : graph(gw.graph) { } | 
|---|
| 103 |   | 
|---|
| 104 |     typedef typename Graph::Node Node; | 
|---|
| 105 |     class NodeIt : public Node {  | 
|---|
| 106 |       const GraphWrapper<Graph>* gw; | 
|---|
| 107 |       friend class GraphWrapper<Graph>; | 
|---|
| 108 |      public: | 
|---|
| 109 |       NodeIt() { } | 
|---|
| 110 |       NodeIt(Invalid i) : Node(i) { } | 
|---|
| 111 |       NodeIt(const GraphWrapper<Graph>& _gw) :  | 
|---|
| 112 |         Node(typename Graph::NodeIt(*(_gw.graph))), gw(&_gw) { } | 
|---|
| 113 |       NodeIt(const GraphWrapper<Graph>& _gw, const Node& n) :  | 
|---|
| 114 |         Node(n), gw(&_gw) { } | 
|---|
| 115 |       NodeIt& operator++() {  | 
|---|
| 116 |         *(static_cast<Node*>(this))= | 
|---|
| 117 |           ++(typename Graph::NodeIt(*(gw->graph), *this)); | 
|---|
| 118 |         return *this;  | 
|---|
| 119 |       } | 
|---|
| 120 |     }; | 
|---|
| 121 |     typedef typename Graph::Edge Edge; | 
|---|
| 122 |     class OutEdgeIt : public Edge {  | 
|---|
| 123 |       const GraphWrapper<Graph>* gw; | 
|---|
| 124 |       friend class GraphWrapper<Graph>; | 
|---|
| 125 |      public: | 
|---|
| 126 |       OutEdgeIt() { } | 
|---|
| 127 |       OutEdgeIt(Invalid i) : Edge(i) { } | 
|---|
| 128 |       OutEdgeIt(const GraphWrapper<Graph>& _gw, const Node& n) :  | 
|---|
| 129 |         Edge(typename Graph::OutEdgeIt(*(_gw.graph), n)), gw(&_gw) { } | 
|---|
| 130 |       OutEdgeIt(const GraphWrapper<Graph>& _gw, const Edge& e) :  | 
|---|
| 131 |         Edge(e), gw(&_gw) { } | 
|---|
| 132 |       OutEdgeIt& operator++() {  | 
|---|
| 133 |         *(static_cast<Edge*>(this))= | 
|---|
| 134 |           ++(typename Graph::OutEdgeIt(*(gw->graph), *this)); | 
|---|
| 135 |         return *this;  | 
|---|
| 136 |       } | 
|---|
| 137 |     }; | 
|---|
| 138 |     class InEdgeIt : public Edge {  | 
|---|
| 139 |       const GraphWrapper<Graph>* gw; | 
|---|
| 140 |       friend class GraphWrapper<Graph>; | 
|---|
| 141 |      public: | 
|---|
| 142 |       InEdgeIt() { } | 
|---|
| 143 |       InEdgeIt(Invalid i) : Edge(i) { } | 
|---|
| 144 |       InEdgeIt(const GraphWrapper<Graph>& _gw, const Node& n) :  | 
|---|
| 145 |         Edge(typename Graph::InEdgeIt(*(_gw.graph), n)), gw(&_gw) { } | 
|---|
| 146 |       InEdgeIt(const GraphWrapper<Graph>& _gw, const Edge& e) :  | 
|---|
| 147 |         Edge(e), gw(&_gw) { } | 
|---|
| 148 |       InEdgeIt& operator++() {  | 
|---|
| 149 |         *(static_cast<Edge*>(this))= | 
|---|
| 150 |           ++(typename Graph::InEdgeIt(*(gw->graph), *this)); | 
|---|
| 151 |         return *this;  | 
|---|
| 152 |       } | 
|---|
| 153 |     }; | 
|---|
| 154 |     class EdgeIt : public Edge {  | 
|---|
| 155 |       const GraphWrapper<Graph>* gw; | 
|---|
| 156 |       friend class GraphWrapper<Graph>; | 
|---|
| 157 |      public: | 
|---|
| 158 |       EdgeIt() { } | 
|---|
| 159 |       EdgeIt(Invalid i) : Edge(i) { } | 
|---|
| 160 |       EdgeIt(const GraphWrapper<Graph>& _gw) :  | 
|---|
| 161 |         Edge(typename Graph::EdgeIt(*(_gw.graph))), gw(&_gw) { } | 
|---|
| 162 |       EdgeIt(const GraphWrapper<Graph>& _gw, const Edge& e) :  | 
|---|
| 163 |         Edge(e), gw(&_gw) { } | 
|---|
| 164 |       EdgeIt& operator++() {  | 
|---|
| 165 |         *(static_cast<Edge*>(this))= | 
|---|
| 166 |           ++(typename Graph::EdgeIt(*(gw->graph), *this)); | 
|---|
| 167 |         return *this;  | 
|---|
| 168 |       } | 
|---|
| 169 |     }; | 
|---|
| 170 |     | 
|---|
| 171 |     NodeIt& first(NodeIt& i) const {  | 
|---|
| 172 |       i=NodeIt(*this); return i; | 
|---|
| 173 |     } | 
|---|
| 174 |     OutEdgeIt& first(OutEdgeIt& i, const Node& p) const {  | 
|---|
| 175 |       i=OutEdgeIt(*this, p); return i; | 
|---|
| 176 |     } | 
|---|
| 177 |     InEdgeIt& first(InEdgeIt& i, const Node& p) const {  | 
|---|
| 178 |       i=InEdgeIt(*this, p); return i; | 
|---|
| 179 |     } | 
|---|
| 180 |     EdgeIt& first(EdgeIt& i) const {  | 
|---|
| 181 |       i=EdgeIt(*this); return i; | 
|---|
| 182 |     } | 
|---|
| 183 |  | 
|---|
| 184 |     Node tail(const Edge& e) const {  | 
|---|
| 185 |       return Node(graph->tail(static_cast<typename Graph::Edge>(e))); } | 
|---|
| 186 |     Node head(const Edge& e) const {  | 
|---|
| 187 |       return Node(graph->head(static_cast<typename Graph::Edge>(e))); } | 
|---|
| 188 |  | 
|---|
| 189 |     int nodeNum() const { return graph->nodeNum(); } | 
|---|
| 190 |     int edgeNum() const { return graph->edgeNum(); } | 
|---|
| 191 |    | 
|---|
| 192 |     Node addNode() const { return Node(graph->addNode()); } | 
|---|
| 193 |     Edge addEdge(const Node& tail, const Node& head) const {  | 
|---|
| 194 |       return Edge(graph->addEdge(tail, head)); } | 
|---|
| 195 |  | 
|---|
| 196 |     void erase(const Node& i) const { graph->erase(i); } | 
|---|
| 197 |     void erase(const Edge& i) const { graph->erase(i); } | 
|---|
| 198 |    | 
|---|
| 199 |     void clear() const { graph->clear(); } | 
|---|
| 200 |      | 
|---|
| 201 |     bool forward(const Edge& e) const { return graph->forward(e); } | 
|---|
| 202 |     bool backward(const Edge& e) const { return graph->backward(e); } | 
|---|
| 203 |  | 
|---|
| 204 |     int id(const Node& v) const { return graph->id(v); } | 
|---|
| 205 |     int id(const Edge& e) const { return graph->id(e); } | 
|---|
| 206 |      | 
|---|
| 207 |     Edge opposite(const Edge& e) const { return Edge(graph->opposite(e)); } | 
|---|
| 208 |  | 
|---|
| 209 |  | 
|---|
| 210 |     IMPORT_NODE_MAP(Graph, *(gw.graph), GraphWrapper, gw);     | 
|---|
| 211 |     IMPORT_EDGE_MAP(Graph, *(gw.graph), GraphWrapper, gw); | 
|---|
| 212 |      | 
|---|
| 213 |  | 
|---|
| 214 |   }; | 
|---|
| 215 |  | 
|---|
| 216 |  | 
|---|
| 217 |  | 
|---|
| 218 |   /// A graph wrapper which reverses the orientation of the edges. | 
|---|
| 219 |  | 
|---|
| 220 |   ///\warning Graph wrappers are in even more experimental state than the other | 
|---|
| 221 |   ///parts of the lib. Use them at you own risk. | 
|---|
| 222 |   /// | 
|---|
| 223 |   /// A graph wrapper which reverses the orientation of the edges. | 
|---|
| 224 |   /// Thus \c Graph have to be a directed graph type. | 
|---|
| 225 |   /// | 
|---|
| 226 |   ///\author Marton Makai | 
|---|
| 227 |   template<typename Graph> | 
|---|
| 228 |   class RevGraphWrapper : public GraphWrapper<Graph> { | 
|---|
| 229 |   public: | 
|---|
| 230 |     typedef GraphWrapper<Graph> Parent;  | 
|---|
| 231 |   protected: | 
|---|
| 232 |     RevGraphWrapper() : GraphWrapper<Graph>() { } | 
|---|
| 233 |   public: | 
|---|
| 234 |     RevGraphWrapper(Graph& _graph) : GraphWrapper<Graph>(_graph) { }   | 
|---|
| 235 |     RevGraphWrapper(const RevGraphWrapper<Graph>& gw) : Parent(gw) { } | 
|---|
| 236 |  | 
|---|
| 237 |     typedef typename GraphWrapper<Graph>::Node Node; | 
|---|
| 238 |     typedef typename GraphWrapper<Graph>::Edge Edge; | 
|---|
| 239 |     //remark: OutEdgeIt and InEdgeIt cannot be typedef-ed to each other | 
|---|
| 240 |     //because this does not work is some of them are not defined in the  | 
|---|
| 241 |     //original graph. The problem with this is that typedef-ed stuff  | 
|---|
| 242 |     //are instantiated in c++. | 
|---|
| 243 |     class OutEdgeIt : public Edge {  | 
|---|
| 244 |       const RevGraphWrapper<Graph>* gw; | 
|---|
| 245 |       friend class GraphWrapper<Graph>; | 
|---|
| 246 |      public: | 
|---|
| 247 |       OutEdgeIt() { } | 
|---|
| 248 |       OutEdgeIt(Invalid i) : Edge(i) { } | 
|---|
| 249 |       OutEdgeIt(const RevGraphWrapper<Graph>& _gw, const Node& n) :  | 
|---|
| 250 |         Edge(typename Graph::InEdgeIt(*(_gw.graph), n)), gw(&_gw) { } | 
|---|
| 251 |       OutEdgeIt(const RevGraphWrapper<Graph>& _gw, const Edge& e) :  | 
|---|
| 252 |         Edge(e), gw(&_gw) { } | 
|---|
| 253 |       OutEdgeIt& operator++() {  | 
|---|
| 254 |         *(static_cast<Edge*>(this))= | 
|---|
| 255 |           ++(typename Graph::InEdgeIt(*(gw->graph), *this)); | 
|---|
| 256 |         return *this;  | 
|---|
| 257 |       } | 
|---|
| 258 |     }; | 
|---|
| 259 |     class InEdgeIt : public Edge {  | 
|---|
| 260 |       const RevGraphWrapper<Graph>* gw; | 
|---|
| 261 |       friend class GraphWrapper<Graph>; | 
|---|
| 262 |      public: | 
|---|
| 263 |       InEdgeIt() { } | 
|---|
| 264 |       InEdgeIt(Invalid i) : Edge(i) { } | 
|---|
| 265 |       InEdgeIt(const RevGraphWrapper<Graph>& _gw, const Node& n) :  | 
|---|
| 266 |         Edge(typename Graph::OutEdgeIt(*(_gw.graph), n)), gw(&_gw) { } | 
|---|
| 267 |       InEdgeIt(const RevGraphWrapper<Graph>& _gw, const Edge& e) :  | 
|---|
| 268 |         Edge(e), gw(&_gw) { } | 
|---|
| 269 |       InEdgeIt& operator++() {  | 
|---|
| 270 |         *(static_cast<Edge*>(this))= | 
|---|
| 271 |           ++(typename Graph::OutEdgeIt(*(gw->graph), *this)); | 
|---|
| 272 |         return *this;  | 
|---|
| 273 |       } | 
|---|
| 274 |     }; | 
|---|
| 275 |  | 
|---|
| 276 |     using GraphWrapper<Graph>::first; | 
|---|
| 277 |     OutEdgeIt& first(OutEdgeIt& i, const Node& p) const {  | 
|---|
| 278 |       i=OutEdgeIt(*this, p); return i; | 
|---|
| 279 |     } | 
|---|
| 280 |     InEdgeIt& first(InEdgeIt& i, const Node& p) const {  | 
|---|
| 281 |       i=InEdgeIt(*this, p); return i; | 
|---|
| 282 |     } | 
|---|
| 283 |  | 
|---|
| 284 |     Node tail(const Edge& e) const {  | 
|---|
| 285 |       return GraphWrapper<Graph>::head(e); } | 
|---|
| 286 |     Node head(const Edge& e) const {  | 
|---|
| 287 |       return GraphWrapper<Graph>::tail(e); } | 
|---|
| 288 |  | 
|---|
| 289 |     KEEP_MAPS(Parent, RevGraphWrapper); | 
|---|
| 290 |  | 
|---|
| 291 |   }; | 
|---|
| 292 |  | 
|---|
| 293 |  | 
|---|
| 294 |  | 
|---|
| 295 |   /// A graph wrapper for hiding nodes and edges from a graph. | 
|---|
| 296 |    | 
|---|
| 297 |   ///\warning Graph wrappers are in even more experimental state than the other | 
|---|
| 298 |   ///parts of the lib. Use them at you own risk. | 
|---|
| 299 |   /// | 
|---|
| 300 |   /// This wrapper shows a graph with filtered node-set and  | 
|---|
| 301 |   /// edge-set. Given a bool-valued map on the node-set and one on  | 
|---|
| 302 |   /// the edge-set of the graphs, the iterators shows only the objects  | 
|---|
| 303 |   /// having true value.  | 
|---|
| 304 |   /// The quick brown fox iterators jump over  | 
|---|
| 305 |   /// the lazy dog nodes or edges if their values for are false in the  | 
|---|
| 306 |   /// corresponding bool maps.  | 
|---|
| 307 |   /// | 
|---|
| 308 |   ///\author Marton Makai | 
|---|
| 309 |   template<typename Graph, typename NodeFilterMap,  | 
|---|
| 310 |            typename EdgeFilterMap> | 
|---|
| 311 |   class SubGraphWrapper : public GraphWrapper<Graph> { | 
|---|
| 312 |   public: | 
|---|
| 313 |     typedef GraphWrapper<Graph> Parent; | 
|---|
| 314 |   protected: | 
|---|
| 315 |     NodeFilterMap* node_filter_map; | 
|---|
| 316 |     EdgeFilterMap* edge_filter_map; | 
|---|
| 317 |  | 
|---|
| 318 |     SubGraphWrapper() : GraphWrapper<Graph>(),  | 
|---|
| 319 |                         node_filter_map(0), edge_filter_map(0) { } | 
|---|
| 320 |     void setNodeFilterMap(NodeFilterMap& _node_filter_map) { | 
|---|
| 321 |       node_filter_map=&_node_filter_map; | 
|---|
| 322 |     } | 
|---|
| 323 |     void setEdgeFilterMap(EdgeFilterMap& _edge_filter_map) { | 
|---|
| 324 |       edge_filter_map=&_edge_filter_map; | 
|---|
| 325 |     } | 
|---|
| 326 |      | 
|---|
| 327 |   public: | 
|---|
| 328 |     SubGraphWrapper(Graph& _graph, NodeFilterMap& _node_filter_map,  | 
|---|
| 329 |                     EdgeFilterMap& _edge_filter_map) :  | 
|---|
| 330 |       GraphWrapper<Graph>(_graph), node_filter_map(&_node_filter_map),  | 
|---|
| 331 |       edge_filter_map(&_edge_filter_map) { }   | 
|---|
| 332 |  | 
|---|
| 333 |     typedef typename GraphWrapper<Graph>::Node Node; | 
|---|
| 334 |     class NodeIt : public Node {  | 
|---|
| 335 |       const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>* gw; | 
|---|
| 336 |       friend class SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>; | 
|---|
| 337 |     public: | 
|---|
| 338 |       NodeIt() { } | 
|---|
| 339 |       NodeIt(Invalid i) : Node(i) { } | 
|---|
| 340 |       NodeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _gw) :  | 
|---|
| 341 |         Node(typename Graph::NodeIt(*(_gw.graph))), gw(&_gw) {  | 
|---|
| 342 |         while (*static_cast<Node*>(this)!=INVALID &&  | 
|---|
| 343 |                !(*(gw->node_filter_map))[*this])  | 
|---|
| 344 |           *(static_cast<Node*>(this))= | 
|---|
| 345 |             ++(typename Graph::NodeIt(*(gw->graph), *this)); | 
|---|
| 346 |       } | 
|---|
| 347 |       NodeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _gw,  | 
|---|
| 348 |              const Node& n) :  | 
|---|
| 349 |         Node(n), gw(&_gw) { } | 
|---|
| 350 |       NodeIt& operator++() {  | 
|---|
| 351 |         *(static_cast<Node*>(this))= | 
|---|
| 352 |           ++(typename Graph::NodeIt(*(gw->graph), *this)); | 
|---|
| 353 |         while (*static_cast<Node*>(this)!=INVALID &&  | 
|---|
| 354 |                !(*(gw->node_filter_map))[*this])  | 
|---|
| 355 |           *(static_cast<Node*>(this))= | 
|---|
| 356 |             ++(typename Graph::NodeIt(*(gw->graph), *this)); | 
|---|
| 357 |         return *this;  | 
|---|
| 358 |       } | 
|---|
| 359 |     }; | 
|---|
| 360 |     typedef typename GraphWrapper<Graph>::Edge Edge; | 
|---|
| 361 |     class OutEdgeIt : public Edge {  | 
|---|
| 362 |       const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>* gw; | 
|---|
| 363 |       friend class SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>; | 
|---|
| 364 |     public: | 
|---|
| 365 |       OutEdgeIt() { } | 
|---|
| 366 |       OutEdgeIt(Invalid i) : Edge(i) { } | 
|---|
| 367 |       OutEdgeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _gw, const Node& n) :  | 
|---|
| 368 |         Edge(typename Graph::OutEdgeIt(*(_gw.graph), n)), gw(&_gw) {  | 
|---|
| 369 |         while (*static_cast<Edge*>(this)!=INVALID &&  | 
|---|
| 370 |                !(*(gw->edge_filter_map))[*this])  | 
|---|
| 371 |           *(static_cast<Edge*>(this))= | 
|---|
| 372 |             ++(typename Graph::OutEdgeIt(*(gw->graph), *this)); | 
|---|
| 373 |       } | 
|---|
| 374 |       OutEdgeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _gw,  | 
|---|
| 375 |              const Edge& e) :  | 
|---|
| 376 |         Edge(e), gw(&_gw) { } | 
|---|
| 377 |       OutEdgeIt& operator++() {  | 
|---|
| 378 |         *(static_cast<Edge*>(this))= | 
|---|
| 379 |           ++(typename Graph::OutEdgeIt(*(gw->graph), *this)); | 
|---|
| 380 |         while (*static_cast<Edge*>(this)!=INVALID &&  | 
|---|
| 381 |                !(*(gw->edge_filter_map))[*this])  | 
|---|
| 382 |           *(static_cast<Edge*>(this))= | 
|---|
| 383 |             ++(typename Graph::OutEdgeIt(*(gw->graph), *this)); | 
|---|
| 384 |         return *this;  | 
|---|
| 385 |       } | 
|---|
| 386 |     }; | 
|---|
| 387 |     class InEdgeIt : public Edge {  | 
|---|
| 388 |       const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>* gw; | 
|---|
| 389 |       friend class SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>; | 
|---|
| 390 |     public: | 
|---|
| 391 |       InEdgeIt() { } | 
|---|
| 392 |       //      InEdgeIt(const InEdgeIt& e) : Edge(e), gw(e.gw) { } | 
|---|
| 393 |       InEdgeIt(Invalid i) : Edge(i) { } | 
|---|
| 394 |       InEdgeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _gw, const Node& n) :  | 
|---|
| 395 |         Edge(typename Graph::InEdgeIt(*(_gw.graph), n)), gw(&_gw) {  | 
|---|
| 396 |         while (*static_cast<Edge*>(this)!=INVALID &&  | 
|---|
| 397 |                !(*(gw->edge_filter_map))[*this])  | 
|---|
| 398 |           *(static_cast<Edge*>(this))= | 
|---|
| 399 |             ++(typename Graph::InEdgeIt(*(gw->graph), *this)); | 
|---|
| 400 |       } | 
|---|
| 401 |       InEdgeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _gw,  | 
|---|
| 402 |              const Edge& e) :  | 
|---|
| 403 |         Edge(e), gw(&_gw) { } | 
|---|
| 404 |       InEdgeIt& operator++() {  | 
|---|
| 405 |         *(static_cast<Edge*>(this))= | 
|---|
| 406 |           ++(typename Graph::InEdgeIt(*(gw->graph), *this)); | 
|---|
| 407 |         while (*static_cast<Edge*>(this)!=INVALID &&  | 
|---|
| 408 |                !(*(gw->edge_filter_map))[*this])  | 
|---|
| 409 |           *(static_cast<Edge*>(this))= | 
|---|
| 410 |             ++(typename Graph::InEdgeIt(*(gw->graph), *this)); | 
|---|
| 411 |         return *this;  | 
|---|
| 412 |       } | 
|---|
| 413 |     }; | 
|---|
| 414 |     class EdgeIt : public Edge {  | 
|---|
| 415 |       const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>* gw; | 
|---|
| 416 |       friend class SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>; | 
|---|
| 417 |     public: | 
|---|
| 418 |       EdgeIt() { } | 
|---|
| 419 |       EdgeIt(Invalid i) : Edge(i) { } | 
|---|
| 420 |       EdgeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _gw) :  | 
|---|
| 421 |         Edge(typename Graph::EdgeIt(*(_gw.graph))), gw(&_gw) {  | 
|---|
| 422 |         while (*static_cast<Edge*>(this)!=INVALID &&  | 
|---|
| 423 |                !(*(gw->edge_filter_map))[*this])  | 
|---|
| 424 |           *(static_cast<Edge*>(this))= | 
|---|
| 425 |             ++(typename Graph::EdgeIt(*(gw->graph), *this)); | 
|---|
| 426 |       } | 
|---|
| 427 |       EdgeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _gw,  | 
|---|
| 428 |              const Edge& e) :  | 
|---|
| 429 |         Edge(e), gw(&_gw) { } | 
|---|
| 430 |       EdgeIt& operator++() {  | 
|---|
| 431 |         *(static_cast<Edge*>(this))= | 
|---|
| 432 |           ++(typename Graph::EdgeIt(*(gw->graph), *this)); | 
|---|
| 433 |         while (*static_cast<Edge*>(this)!=INVALID &&  | 
|---|
| 434 |                !(*(gw->edge_filter_map))[*this])  | 
|---|
| 435 |           *(static_cast<Edge*>(this))= | 
|---|
| 436 |             ++(typename Graph::EdgeIt(*(gw->graph), *this)); | 
|---|
| 437 |         return *this;  | 
|---|
| 438 |       } | 
|---|
| 439 |     }; | 
|---|
| 440 |  | 
|---|
| 441 |     NodeIt& first(NodeIt& i) const {  | 
|---|
| 442 |       i=NodeIt(*this); return i; | 
|---|
| 443 |     } | 
|---|
| 444 |     OutEdgeIt& first(OutEdgeIt& i, const Node& p) const {  | 
|---|
| 445 |       i=OutEdgeIt(*this, p); return i; | 
|---|
| 446 |     } | 
|---|
| 447 |     InEdgeIt& first(InEdgeIt& i, const Node& p) const {  | 
|---|
| 448 |       i=InEdgeIt(*this, p); return i; | 
|---|
| 449 |     } | 
|---|
| 450 |     EdgeIt& first(EdgeIt& i) const {  | 
|---|
| 451 |       i=EdgeIt(*this); return i; | 
|---|
| 452 |     } | 
|---|
| 453 |      | 
|---|
| 454 |     /// This function hides \c n in the graph, i.e. the iteration  | 
|---|
| 455 |     /// jumps over it. This is done by simply setting the value of \c n   | 
|---|
| 456 |     /// to be false in the corresponding node-map. | 
|---|
| 457 |     void hide(const Node& n) const { node_filter_map->set(n, false); } | 
|---|
| 458 |  | 
|---|
| 459 |     /// This function hides \c e in the graph, i.e. the iteration  | 
|---|
| 460 |     /// jumps over it. This is done by simply setting the value of \c e   | 
|---|
| 461 |     /// to be false in the corresponding edge-map. | 
|---|
| 462 |     void hide(const Edge& e) const { edge_filter_map->set(e, false); } | 
|---|
| 463 |  | 
|---|
| 464 |     /// The value of \c n is set to be true in the node-map which stores  | 
|---|
| 465 |     /// hide information. If \c n was hidden previuosly, then it is shown  | 
|---|
| 466 |     /// again | 
|---|
| 467 |      void unHide(const Node& n) const { node_filter_map->set(n, true); } | 
|---|
| 468 |  | 
|---|
| 469 |     /// The value of \c e is set to be true in the edge-map which stores  | 
|---|
| 470 |     /// hide information. If \c e was hidden previuosly, then it is shown  | 
|---|
| 471 |     /// again | 
|---|
| 472 |     void unHide(const Edge& e) const { edge_filter_map->set(e, true); } | 
|---|
| 473 |  | 
|---|
| 474 |     /// Returns true if \c n is hidden. | 
|---|
| 475 |     bool hidden(const Node& n) const { return !(*node_filter_map)[n]; } | 
|---|
| 476 |  | 
|---|
| 477 |     /// Returns true if \c n is hidden. | 
|---|
| 478 |     bool hidden(const Edge& e) const { return !(*edge_filter_map)[e]; } | 
|---|
| 479 |  | 
|---|
| 480 |     /// \warning This is a linear time operation and works only if  | 
|---|
| 481 |     /// \c Graph::NodeIt is defined. | 
|---|
| 482 |     int nodeNum() const {  | 
|---|
| 483 |       int i=0; | 
|---|
| 484 |       for (NodeIt n(*this); n!=INVALID; ++n) ++i; | 
|---|
| 485 |       return i;  | 
|---|
| 486 |     } | 
|---|
| 487 |  | 
|---|
| 488 |     /// \warning This is a linear time operation and works only if  | 
|---|
| 489 |     /// \c Graph::EdgeIt is defined. | 
|---|
| 490 |     int edgeNum() const {  | 
|---|
| 491 |       int i=0; | 
|---|
| 492 |       for (EdgeIt e(*this); e!=INVALID; ++e) ++i; | 
|---|
| 493 |       return i;  | 
|---|
| 494 |     } | 
|---|
| 495 |  | 
|---|
| 496 |     KEEP_MAPS(Parent, SubGraphWrapper); | 
|---|
| 497 |   }; | 
|---|
| 498 |  | 
|---|
| 499 |  | 
|---|
| 500 |  | 
|---|
| 501 |   template<typename Graph> | 
|---|
| 502 |   class UndirGraphWrapper : public GraphWrapper<Graph> { | 
|---|
| 503 |   public: | 
|---|
| 504 |     typedef GraphWrapper<Graph> Parent;  | 
|---|
| 505 |   protected: | 
|---|
| 506 |     UndirGraphWrapper() : GraphWrapper<Graph>() { } | 
|---|
| 507 |      | 
|---|
| 508 |   public: | 
|---|
| 509 |     typedef typename GraphWrapper<Graph>::Node Node; | 
|---|
| 510 |     typedef typename GraphWrapper<Graph>::NodeIt NodeIt; | 
|---|
| 511 |     typedef typename GraphWrapper<Graph>::Edge Edge; | 
|---|
| 512 |     typedef typename GraphWrapper<Graph>::EdgeIt EdgeIt; | 
|---|
| 513 |  | 
|---|
| 514 |     UndirGraphWrapper(Graph& _graph) : GraphWrapper<Graph>(_graph) { }   | 
|---|
| 515 |  | 
|---|
| 516 |     class OutEdgeIt { | 
|---|
| 517 |       friend class UndirGraphWrapper<Graph>; | 
|---|
| 518 |       bool out_or_in; //true iff out | 
|---|
| 519 |       typename Graph::OutEdgeIt out; | 
|---|
| 520 |       typename Graph::InEdgeIt in; | 
|---|
| 521 |     public: | 
|---|
| 522 |       OutEdgeIt() { } | 
|---|
| 523 |       OutEdgeIt(const Invalid& i) : Edge(i) { } | 
|---|
| 524 |       OutEdgeIt(const UndirGraphWrapper<Graph>& _G, const Node& _n) { | 
|---|
| 525 |         out_or_in=true; _G.graph->first(out, _n); | 
|---|
| 526 |         if (!(_G.graph->valid(out))) { out_or_in=false; _G.graph->first(in, _n);        } | 
|---|
| 527 |       }  | 
|---|
| 528 |       operator Edge() const {  | 
|---|
| 529 |         if (out_or_in) return Edge(out); else return Edge(in);  | 
|---|
| 530 |       } | 
|---|
| 531 |     }; | 
|---|
| 532 |  | 
|---|
| 533 |     typedef OutEdgeIt InEdgeIt;  | 
|---|
| 534 |  | 
|---|
| 535 |     using GraphWrapper<Graph>::first; | 
|---|
| 536 |     OutEdgeIt& first(OutEdgeIt& i, const Node& p) const {  | 
|---|
| 537 |       i=OutEdgeIt(*this, p); return i; | 
|---|
| 538 |     } | 
|---|
| 539 |  | 
|---|
| 540 |     using GraphWrapper<Graph>::next; | 
|---|
| 541 |  | 
|---|
| 542 |     OutEdgeIt& next(OutEdgeIt& e) const { | 
|---|
| 543 |       if (e.out_or_in) { | 
|---|
| 544 |         typename Graph::Node n=this->graph->tail(e.out); | 
|---|
| 545 |         this->graph->next(e.out); | 
|---|
| 546 |         if (!this->graph->valid(e.out)) {  | 
|---|
| 547 |           e.out_or_in=false; this->graph->first(e.in, n); } | 
|---|
| 548 |       } else { | 
|---|
| 549 |         this->graph->next(e.in); | 
|---|
| 550 |       } | 
|---|
| 551 |       return e; | 
|---|
| 552 |     } | 
|---|
| 553 |  | 
|---|
| 554 |     Node aNode(const OutEdgeIt& e) const {  | 
|---|
| 555 |       if (e.out_or_in) return this->graph->tail(e); else  | 
|---|
| 556 |         return this->graph->head(e); } | 
|---|
| 557 |     Node bNode(const OutEdgeIt& e) const {  | 
|---|
| 558 |       if (e.out_or_in) return this->graph->head(e); else  | 
|---|
| 559 |         return this->graph->tail(e); } | 
|---|
| 560 |  | 
|---|
| 561 |     KEEP_MAPS(Parent, UndirGraphWrapper); | 
|---|
| 562 |  | 
|---|
| 563 |   }; | 
|---|
| 564 |    | 
|---|
| 565 |   /// \brief An undirected graph template. | 
|---|
| 566 |   /// | 
|---|
| 567 |   ///\warning Graph wrappers are in even more experimental state than the other | 
|---|
| 568 |   ///parts of the lib. Use them at you own risk. | 
|---|
| 569 |   /// | 
|---|
| 570 |   /// An undirected graph template. | 
|---|
| 571 |   /// This class works as an undirected graph and a directed graph of  | 
|---|
| 572 |   /// class \c Graph is used for the physical storage. | 
|---|
| 573 |   /// \ingroup graphs | 
|---|
| 574 |   template<typename Graph> | 
|---|
| 575 |   class UndirGraph : public UndirGraphWrapper<Graph> { | 
|---|
| 576 |     typedef UndirGraphWrapper<Graph> Parent; | 
|---|
| 577 |   protected: | 
|---|
| 578 |     Graph gr; | 
|---|
| 579 |   public: | 
|---|
| 580 |     UndirGraph() : UndirGraphWrapper<Graph>() {  | 
|---|
| 581 |       Parent::setGraph(gr);  | 
|---|
| 582 |     } | 
|---|
| 583 |  | 
|---|
| 584 |     KEEP_MAPS(Parent, UndirGraph); | 
|---|
| 585 |   }; | 
|---|
| 586 |  | 
|---|
| 587 |  | 
|---|
| 588 |  | 
|---|
| 589 |   ///\brief A wrapper for composing a subgraph of a  | 
|---|
| 590 |   /// bidirected graph made from a directed one.  | 
|---|
| 591 |   /// | 
|---|
| 592 |   ///\warning Graph wrappers are in even more experimental state than the other | 
|---|
| 593 |   ///parts of the lib. Use them at you own risk. | 
|---|
| 594 |   /// | 
|---|
| 595 |   /// Suppose that for a directed graph $G=(V, A)$,  | 
|---|
| 596 |   /// two predicates on the edge-set, $forward_filter$, and $backward_filter$  | 
|---|
| 597 |   /// is given, and we are dealing with the directed graph | 
|---|
| 598 |   /// a $G'=(V, \{uv : uv\in A \mbox{ and } forward_filter(uv) \mbox{ is true}\}+\{vu : uv\in A \mbox{ and } backward_filter(uv) \mbox{ is true}\})$.  | 
|---|
| 599 |   /// The purpose of writing + instead of union is because parallel  | 
|---|
| 600 |   /// edges can arose.  | 
|---|
| 601 |   /// In other words, a subgraph of the bidirected graph obtained, which  | 
|---|
| 602 |   /// is given by orienting the edges of the original graph in both directions. | 
|---|
| 603 |   /// An example for such a construction is the \c RevGraphWrapper where the  | 
|---|
| 604 |   /// forward_filter is everywhere false and the backward_filter is  | 
|---|
| 605 |   /// everywhere true. We note that for sake of efficiency,  | 
|---|
| 606 |   /// \c RevGraphWrapper is implemented in a different way.  | 
|---|
| 607 |   /// But BidirGraphWrapper is obtained from  | 
|---|
| 608 |   /// SubBidirGraphWrapper by considering everywhere true  | 
|---|
| 609 |   /// predicates both forward_filter and backward_filter.  | 
|---|
| 610 |   /// Finally, one of the most important applications of SubBidirGraphWrapper  | 
|---|
| 611 |   /// is ResGraphWrapper, which stands for the residual graph in directed  | 
|---|
| 612 |   /// flow and circulation problems.  | 
|---|
| 613 |   /// As wrappers usually, the SubBidirGraphWrapper implements the  | 
|---|
| 614 |   /// above mentioned graph structure without its physical storage,  | 
|---|
| 615 |   /// that is the whole stuff eats constant memory.  | 
|---|
| 616 |   /// As the oppositely directed edges are logical different,  | 
|---|
| 617 |   /// the maps are able to attach different values for them.  | 
|---|
| 618 |   template<typename Graph,  | 
|---|
| 619 |            typename ForwardFilterMap, typename BackwardFilterMap> | 
|---|
| 620 |   class SubBidirGraphWrapper : public GraphWrapper<Graph> { | 
|---|
| 621 |   public: | 
|---|
| 622 |     typedef GraphWrapper<Graph> Parent;  | 
|---|
| 623 |   protected: | 
|---|
| 624 |     ForwardFilterMap* forward_filter; | 
|---|
| 625 |     BackwardFilterMap* backward_filter; | 
|---|
| 626 |  | 
|---|
| 627 |     SubBidirGraphWrapper() : GraphWrapper<Graph>() { } | 
|---|
| 628 |     void setForwardFilterMap(ForwardFilterMap& _forward_filter) { | 
|---|
| 629 |       forward_filter=&_forward_filter; | 
|---|
| 630 |     } | 
|---|
| 631 |     void setBackwardFilterMap(BackwardFilterMap& _backward_filter) { | 
|---|
| 632 |       backward_filter=&_backward_filter; | 
|---|
| 633 |     } | 
|---|
| 634 |  | 
|---|
| 635 |   public: | 
|---|
| 636 |  | 
|---|
| 637 |     SubBidirGraphWrapper(Graph& _graph, ForwardFilterMap& _forward_filter,  | 
|---|
| 638 |                          BackwardFilterMap& _backward_filter) :  | 
|---|
| 639 |       GraphWrapper<Graph>(_graph),  | 
|---|
| 640 |       forward_filter(&_forward_filter), backward_filter(&_backward_filter) { } | 
|---|
| 641 |     SubBidirGraphWrapper(const SubBidirGraphWrapper<Graph,  | 
|---|
| 642 |                          ForwardFilterMap, BackwardFilterMap>& gw) :  | 
|---|
| 643 |       Parent(gw),  | 
|---|
| 644 |       forward_filter(gw.forward_filter),  | 
|---|
| 645 |       backward_filter(gw.backward_filter) { } | 
|---|
| 646 |  | 
|---|
| 647 |     class Edge;  | 
|---|
| 648 |     class OutEdgeIt;  | 
|---|
| 649 |     friend class Edge;  | 
|---|
| 650 |     friend class OutEdgeIt;  | 
|---|
| 651 |  | 
|---|
| 652 |     template<typename T> class EdgeMap; | 
|---|
| 653 |  | 
|---|
| 654 |     typedef typename GraphWrapper<Graph>::Node Node; | 
|---|
| 655 |  | 
|---|
| 656 |     typedef typename Graph::Edge GraphEdge; | 
|---|
| 657 |     /// SubBidirGraphWrapper<..., ..., ...>::Edge is inherited from  | 
|---|
| 658 |     /// Graph::Edge. It contains an extra bool flag which shows if the  | 
|---|
| 659 |     /// edge is the backward version of the original edge. | 
|---|
| 660 |     class Edge : public Graph::Edge { | 
|---|
| 661 |       friend class SubBidirGraphWrapper<Graph,  | 
|---|
| 662 |                                         ForwardFilterMap, BackwardFilterMap>; | 
|---|
| 663 |       template<typename T> friend class EdgeMap; | 
|---|
| 664 |     protected: | 
|---|
| 665 |       bool backward; //true, iff backward | 
|---|
| 666 |     public: | 
|---|
| 667 |       Edge() { } | 
|---|
| 668 |       /// \todo =false is needed, or causes problems? | 
|---|
| 669 |       /// If \c _backward is false, then we get an edge corresponding to the  | 
|---|
| 670 |       /// original one, otherwise its oppositely directed pair is obtained. | 
|---|
| 671 |       Edge(const typename Graph::Edge& e, bool _backward/*=false*/) :  | 
|---|
| 672 |         Graph::Edge(e), backward(_backward) { } | 
|---|
| 673 |       Edge(Invalid i) : Graph::Edge(i), backward(true) { } | 
|---|
| 674 |       bool operator==(const Edge& v) const {  | 
|---|
| 675 |         return (this->backward==v.backward &&  | 
|---|
| 676 |                 static_cast<typename Graph::Edge>(*this)== | 
|---|
| 677 |                 static_cast<typename Graph::Edge>(v)); | 
|---|
| 678 |       }  | 
|---|
| 679 |       bool operator!=(const Edge& v) const {  | 
|---|
| 680 |         return (this->backward!=v.backward ||  | 
|---|
| 681 |                 static_cast<typename Graph::Edge>(*this)!= | 
|---|
| 682 |                 static_cast<typename Graph::Edge>(v)); | 
|---|
| 683 |       } | 
|---|
| 684 |     }; | 
|---|
| 685 |  | 
|---|
| 686 |     class OutEdgeIt : public Edge { | 
|---|
| 687 |       friend class SubBidirGraphWrapper<Graph,  | 
|---|
| 688 |                                         ForwardFilterMap, BackwardFilterMap>; | 
|---|
| 689 |     protected: | 
|---|
| 690 |       const SubBidirGraphWrapper<Graph,  | 
|---|
| 691 |                                  ForwardFilterMap, BackwardFilterMap>* gw; | 
|---|
| 692 |     public: | 
|---|
| 693 |       OutEdgeIt() { } | 
|---|
| 694 |       OutEdgeIt(Invalid i) : Edge(i) { } | 
|---|
| 695 |       OutEdgeIt(const SubBidirGraphWrapper<Graph,  | 
|---|
| 696 |                 ForwardFilterMap, BackwardFilterMap>& _gw, const Node& n) :  | 
|---|
| 697 |         Edge(typename Graph::OutEdgeIt(*(_gw.graph), n), false), gw(&_gw) {  | 
|---|
| 698 |         while (*static_cast<GraphEdge*>(this)!=INVALID &&  | 
|---|
| 699 |                !(*(gw->forward_filter))[*this])  | 
|---|
| 700 |           *(static_cast<GraphEdge*>(this))= | 
|---|
| 701 |             ++(typename Graph::OutEdgeIt(*(gw->graph), *this)); | 
|---|
| 702 |         if (*static_cast<GraphEdge*>(this)==INVALID) { | 
|---|
| 703 |           *static_cast<Edge*>(this)= | 
|---|
| 704 |             Edge(typename Graph::InEdgeIt(*(_gw.graph), n), true); | 
|---|
| 705 |           while (*static_cast<GraphEdge*>(this)!=INVALID &&  | 
|---|
| 706 |                  !(*(gw->backward_filter))[*this])  | 
|---|
| 707 |             *(static_cast<GraphEdge*>(this))= | 
|---|
| 708 |               ++(typename Graph::InEdgeIt(*(gw->graph), *this)); | 
|---|
| 709 |         } | 
|---|
| 710 |       } | 
|---|
| 711 |       OutEdgeIt(const SubBidirGraphWrapper<Graph,  | 
|---|
| 712 |                 ForwardFilterMap, BackwardFilterMap>& _gw, const Edge& e) :  | 
|---|
| 713 |         Edge(e), gw(&_gw) { } | 
|---|
| 714 |       OutEdgeIt& operator++() {  | 
|---|
| 715 |         if (!this->backward) { | 
|---|
| 716 |           Node n=gw->tail(*this); | 
|---|
| 717 |           *(static_cast<GraphEdge*>(this))= | 
|---|
| 718 |             ++(typename Graph::OutEdgeIt(*(gw->graph), *this)); | 
|---|
| 719 |           while (*static_cast<GraphEdge*>(this)!=INVALID &&  | 
|---|
| 720 |                  !(*(gw->forward_filter))[*this])  | 
|---|
| 721 |             *(static_cast<GraphEdge*>(this))= | 
|---|
| 722 |               ++(typename Graph::OutEdgeIt(*(gw->graph), *this)); | 
|---|
| 723 |           if (*static_cast<GraphEdge*>(this)==INVALID) { | 
|---|
| 724 |             *static_cast<Edge*>(this)= | 
|---|
| 725 |               Edge(typename Graph::InEdgeIt(*(gw->graph), n), true); | 
|---|
| 726 |             while (*static_cast<GraphEdge*>(this)!=INVALID &&  | 
|---|
| 727 |                    !(*(gw->backward_filter))[*this])  | 
|---|
| 728 |               *(static_cast<GraphEdge*>(this))= | 
|---|
| 729 |                 ++(typename Graph::InEdgeIt(*(gw->graph), *this)); | 
|---|
| 730 |           } | 
|---|
| 731 |         } else { | 
|---|
| 732 |           *(static_cast<GraphEdge*>(this))= | 
|---|
| 733 |             ++(typename Graph::InEdgeIt(*(gw->graph), *this)); | 
|---|
| 734 |           while (*static_cast<GraphEdge*>(this)!=INVALID &&  | 
|---|
| 735 |                  !(*(gw->backward_filter))[*this])  | 
|---|
| 736 |             *(static_cast<GraphEdge*>(this))= | 
|---|
| 737 |               ++(typename Graph::InEdgeIt(*(gw->graph), *this)); | 
|---|
| 738 |         } | 
|---|
| 739 |         return *this; | 
|---|
| 740 |       } | 
|---|
| 741 |     }; | 
|---|
| 742 |  | 
|---|
| 743 |     class InEdgeIt : public Edge { | 
|---|
| 744 |       friend class SubBidirGraphWrapper<Graph,  | 
|---|
| 745 |                                         ForwardFilterMap, BackwardFilterMap>; | 
|---|
| 746 |     protected: | 
|---|
| 747 |       const SubBidirGraphWrapper<Graph,  | 
|---|
| 748 |                                  ForwardFilterMap, BackwardFilterMap>* gw; | 
|---|
| 749 |     public: | 
|---|
| 750 |       InEdgeIt() { } | 
|---|
| 751 |       InEdgeIt(Invalid i) : Edge(i) { } | 
|---|
| 752 |       InEdgeIt(const SubBidirGraphWrapper<Graph,  | 
|---|
| 753 |                ForwardFilterMap, BackwardFilterMap>& _gw, const Node& n) :  | 
|---|
| 754 |         Edge(typename Graph::InEdgeIt(*(_gw.graph), n), false), gw(&_gw) {  | 
|---|
| 755 |         while (*static_cast<GraphEdge*>(this)!=INVALID &&  | 
|---|
| 756 |                !(*(gw->forward_filter))[*this])  | 
|---|
| 757 |           *(static_cast<GraphEdge*>(this))= | 
|---|
| 758 |             ++(typename Graph::InEdgeIt(*(gw->graph), *this)); | 
|---|
| 759 |         if (*static_cast<GraphEdge*>(this)==INVALID) { | 
|---|
| 760 |           *static_cast<Edge*>(this)= | 
|---|
| 761 |             Edge(typename Graph::OutEdgeIt(*(_gw.graph), n), true); | 
|---|
| 762 |           while (*static_cast<GraphEdge*>(this)!=INVALID &&  | 
|---|
| 763 |                  !(*(gw->backward_filter))[*this])  | 
|---|
| 764 |             *(static_cast<GraphEdge*>(this))= | 
|---|
| 765 |               ++(typename Graph::OutEdgeIt(*(gw->graph), *this)); | 
|---|
| 766 |         } | 
|---|
| 767 |       } | 
|---|
| 768 |       InEdgeIt(const SubBidirGraphWrapper<Graph,  | 
|---|
| 769 |                ForwardFilterMap, BackwardFilterMap>& _gw, const Edge& e) :  | 
|---|
| 770 |         Edge(e), gw(&_gw) { } | 
|---|
| 771 |       InEdgeIt& operator++() {  | 
|---|
| 772 |         if (!this->backward) { | 
|---|
| 773 |           Node n=gw->tail(*this); | 
|---|
| 774 |           *(static_cast<GraphEdge*>(this))= | 
|---|
| 775 |             ++(typename Graph::InEdgeIt(*(gw->graph), *this)); | 
|---|
| 776 |           while (*static_cast<GraphEdge*>(this)!=INVALID &&  | 
|---|
| 777 |                  !(*(gw->forward_filter))[*this])  | 
|---|
| 778 |             *(static_cast<GraphEdge*>(this))= | 
|---|
| 779 |               ++(typename Graph::InEdgeIt(*(gw->graph), *this)); | 
|---|
| 780 |           if (*static_cast<GraphEdge*>(this)==INVALID) { | 
|---|
| 781 |             *static_cast<Edge*>(this)= | 
|---|
| 782 |               Edge(typename Graph::OutEdgeIt(*(gw->graph), n), true); | 
|---|
| 783 |             while (*static_cast<GraphEdge*>(this)!=INVALID &&  | 
|---|
| 784 |                    !(*(gw->backward_filter))[*this])  | 
|---|
| 785 |               *(static_cast<GraphEdge*>(this))= | 
|---|
| 786 |                 ++(typename Graph::OutEdgeIt(*(gw->graph), *this)); | 
|---|
| 787 |           } | 
|---|
| 788 |         } else { | 
|---|
| 789 |           *(static_cast<GraphEdge*>(this))= | 
|---|
| 790 |             ++(typename Graph::OutEdgeIt(*(gw->graph), *this)); | 
|---|
| 791 |           while (*static_cast<GraphEdge*>(this)!=INVALID &&  | 
|---|
| 792 |                  !(*(gw->backward_filter))[*this])  | 
|---|
| 793 |             *(static_cast<GraphEdge*>(this))= | 
|---|
| 794 |               ++(typename Graph::OutEdgeIt(*(gw->graph), *this)); | 
|---|
| 795 |         } | 
|---|
| 796 |         return *this; | 
|---|
| 797 |       } | 
|---|
| 798 |     }; | 
|---|
| 799 |  | 
|---|
| 800 |     class EdgeIt : public Edge { | 
|---|
| 801 |       friend class SubBidirGraphWrapper<Graph,  | 
|---|
| 802 |                                         ForwardFilterMap, BackwardFilterMap>; | 
|---|
| 803 |     protected: | 
|---|
| 804 |       const SubBidirGraphWrapper<Graph,  | 
|---|
| 805 |                                  ForwardFilterMap, BackwardFilterMap>* gw; | 
|---|
| 806 |     public: | 
|---|
| 807 |       EdgeIt() { } | 
|---|
| 808 |       EdgeIt(Invalid i) : Edge(i) { } | 
|---|
| 809 |       EdgeIt(const SubBidirGraphWrapper<Graph,  | 
|---|
| 810 |              ForwardFilterMap, BackwardFilterMap>& _gw) :  | 
|---|
| 811 |         Edge(typename Graph::OutEdgeIt(*(_gw.graph)), false), gw(&_gw) {  | 
|---|
| 812 |         while (*static_cast<GraphEdge*>(this)!=INVALID &&  | 
|---|
| 813 |                !(*(gw->forward_filter))[*this])  | 
|---|
| 814 |           *(static_cast<GraphEdge*>(this))= | 
|---|
| 815 |             ++(typename Graph::EdgeIt(*(gw->graph), *this)); | 
|---|
| 816 |         if (*static_cast<GraphEdge*>(this)==INVALID) { | 
|---|
| 817 |           *static_cast<Edge*>(this)= | 
|---|
| 818 |             Edge(typename Graph::EdgeIt(*(_gw.graph)), true); | 
|---|
| 819 |           while (*static_cast<GraphEdge*>(this)!=INVALID &&  | 
|---|
| 820 |                  !(*(gw->backward_filter))[*this])  | 
|---|
| 821 |             *(static_cast<GraphEdge*>(this))= | 
|---|
| 822 |               ++(typename Graph::EdgeIt(*(gw->graph), *this)); | 
|---|
| 823 |         } | 
|---|
| 824 |       } | 
|---|
| 825 |       EdgeIt(const SubBidirGraphWrapper<Graph,  | 
|---|
| 826 |              ForwardFilterMap, BackwardFilterMap>& _gw, const Edge& e) :  | 
|---|
| 827 |         Edge(e), gw(&_gw) { } | 
|---|
| 828 |       EdgeIt& operator++() {  | 
|---|
| 829 |         if (!this->backward) { | 
|---|
| 830 |           *(static_cast<GraphEdge*>(this))= | 
|---|
| 831 |             ++(typename Graph::EdgeIt(*(gw->graph), *this)); | 
|---|
| 832 |           while (*static_cast<GraphEdge*>(this)!=INVALID &&  | 
|---|
| 833 |                  !(*(gw->forward_filter))[*this])  | 
|---|
| 834 |             *(static_cast<GraphEdge*>(this))= | 
|---|
| 835 |               ++(typename Graph::EdgeIt(*(gw->graph), *this)); | 
|---|
| 836 |           if (*static_cast<GraphEdge*>(this)==INVALID) { | 
|---|
| 837 |             *static_cast<Edge*>(this)= | 
|---|
| 838 |               Edge(typename Graph::EdgeIt(*(gw->graph)), true); | 
|---|
| 839 |             while (*static_cast<GraphEdge*>(this)!=INVALID &&  | 
|---|
| 840 |                    !(*(gw->backward_filter))[*this])  | 
|---|
| 841 |               *(static_cast<GraphEdge*>(this))= | 
|---|
| 842 |                 ++(typename Graph::EdgeIt(*(gw->graph), *this)); | 
|---|
| 843 |           } | 
|---|
| 844 |         } else { | 
|---|
| 845 |           *(static_cast<GraphEdge*>(this))= | 
|---|
| 846 |             ++(typename Graph::EdgeIt(*(gw->graph), *this)); | 
|---|
| 847 |           while (*static_cast<GraphEdge*>(this)!=INVALID &&  | 
|---|
| 848 |                  !(*(gw->backward_filter))[*this])  | 
|---|
| 849 |             *(static_cast<GraphEdge*>(this))= | 
|---|
| 850 |               ++(typename Graph::EdgeIt(*(gw->graph), *this)); | 
|---|
| 851 |         } | 
|---|
| 852 |         return *this; | 
|---|
| 853 |       } | 
|---|
| 854 |     }; | 
|---|
| 855 |  | 
|---|
| 856 |     using GraphWrapper<Graph>::first; | 
|---|
| 857 |     OutEdgeIt& first(OutEdgeIt& i, const Node& p) const {  | 
|---|
| 858 |       i=OutEdgeIt(*this, p); return i; | 
|---|
| 859 |     } | 
|---|
| 860 |     InEdgeIt& first(InEdgeIt& i, const Node& p) const {  | 
|---|
| 861 |       i=InEdgeIt(*this, p); return i; | 
|---|
| 862 |     } | 
|---|
| 863 |     EdgeIt& first(EdgeIt& i) const {  | 
|---|
| 864 |       i=EdgeIt(*this); return i; | 
|---|
| 865 |     } | 
|---|
| 866 |    | 
|---|
| 867 |  | 
|---|
| 868 |     Node tail(Edge e) const {  | 
|---|
| 869 |       return ((!e.backward) ? this->graph->tail(e) : this->graph->head(e)); } | 
|---|
| 870 |     Node head(Edge e) const {  | 
|---|
| 871 |       return ((!e.backward) ? this->graph->head(e) : this->graph->tail(e)); } | 
|---|
| 872 |  | 
|---|
| 873 |     /// Gives back the opposite edge. | 
|---|
| 874 |     Edge opposite(const Edge& e) const {  | 
|---|
| 875 |       Edge f=e; | 
|---|
| 876 |       f.backward=!f.backward; | 
|---|
| 877 |       return f; | 
|---|
| 878 |     } | 
|---|
| 879 |  | 
|---|
| 880 |     /// \warning This is a linear time operation and works only if  | 
|---|
| 881 |     /// \c Graph::EdgeIt is defined. | 
|---|
| 882 |     int edgeNum() const {  | 
|---|
| 883 |       int i=0; | 
|---|
| 884 |       for (EdgeIt e(*this); e!=INVALID; ++e) ++i; | 
|---|
| 885 |       return i;  | 
|---|
| 886 |     } | 
|---|
| 887 |  | 
|---|
| 888 |     bool forward(const Edge& e) const { return !e.backward; } | 
|---|
| 889 |     bool backward(const Edge& e) const { return e.backward; } | 
|---|
| 890 |  | 
|---|
| 891 |  | 
|---|
| 892 |     template <typename T> | 
|---|
| 893 |     /// \c SubBidirGraphWrapper<..., ..., ...>::EdgeMap contains two  | 
|---|
| 894 |     /// Graph::EdgeMap one for the forward edges and  | 
|---|
| 895 |     /// one for the backward edges. | 
|---|
| 896 |     class EdgeMap { | 
|---|
| 897 |       typename Graph::template EdgeMap<T> forward_map, backward_map;  | 
|---|
| 898 |     public: | 
|---|
| 899 |       typedef T ValueType; | 
|---|
| 900 |       typedef Edge KeyType; | 
|---|
| 901 |       EdgeMap(const SubBidirGraphWrapper<Graph,  | 
|---|
| 902 |               ForwardFilterMap, BackwardFilterMap>& g) :  | 
|---|
| 903 |         forward_map(*(g.graph)), backward_map(*(g.graph)) { } | 
|---|
| 904 |       EdgeMap(const SubBidirGraphWrapper<Graph,  | 
|---|
| 905 |               ForwardFilterMap, BackwardFilterMap>& g, T a) :  | 
|---|
| 906 |         forward_map(*(g.graph), a), backward_map(*(g.graph), a) { } | 
|---|
| 907 |       void set(Edge e, T a) {  | 
|---|
| 908 |         if (!e.backward)  | 
|---|
| 909 |           forward_map.set(e, a);  | 
|---|
| 910 |         else  | 
|---|
| 911 |           backward_map.set(e, a);  | 
|---|
| 912 |       } | 
|---|
| 913 |       T operator[](Edge e) const {  | 
|---|
| 914 |         if (!e.backward)  | 
|---|
| 915 |           return forward_map[e];  | 
|---|
| 916 |         else  | 
|---|
| 917 |           return backward_map[e];  | 
|---|
| 918 |       } | 
|---|
| 919 |       void update() {  | 
|---|
| 920 |         forward_map.update();  | 
|---|
| 921 |         backward_map.update(); | 
|---|
| 922 |       } | 
|---|
| 923 |     }; | 
|---|
| 924 |  | 
|---|
| 925 |  | 
|---|
| 926 |     KEEP_NODE_MAP(Parent, SubBidirGraphWrapper); | 
|---|
| 927 |  | 
|---|
| 928 |   }; | 
|---|
| 929 |  | 
|---|
| 930 |  | 
|---|
| 931 |   ///\brief A wrapper for composing bidirected graph from a directed one.  | 
|---|
| 932 |   /// | 
|---|
| 933 |   ///\warning Graph wrappers are in even more experimental state than the other | 
|---|
| 934 |   ///parts of the lib. Use them at you own risk. | 
|---|
| 935 |   /// | 
|---|
| 936 |   /// A wrapper for composing bidirected graph from a directed one.  | 
|---|
| 937 |   /// A bidirected graph is composed over the directed one without physical  | 
|---|
| 938 |   /// storage. As the oppositely directed edges are logically different ones  | 
|---|
| 939 |   /// the maps are able to attach different values for them. | 
|---|
| 940 |   template<typename Graph> | 
|---|
| 941 |   class BidirGraphWrapper :  | 
|---|
| 942 |     public SubBidirGraphWrapper< | 
|---|
| 943 |     Graph,  | 
|---|
| 944 |     ConstMap<typename Graph::Edge, bool>,  | 
|---|
| 945 |     ConstMap<typename Graph::Edge, bool> > { | 
|---|
| 946 |   public: | 
|---|
| 947 |     typedef  SubBidirGraphWrapper< | 
|---|
| 948 |       Graph,  | 
|---|
| 949 |       ConstMap<typename Graph::Edge, bool>,  | 
|---|
| 950 |       ConstMap<typename Graph::Edge, bool> > Parent;  | 
|---|
| 951 |   protected: | 
|---|
| 952 |     ConstMap<typename Graph::Edge, bool> cm; | 
|---|
| 953 |  | 
|---|
| 954 |     BidirGraphWrapper() : Parent(), cm(true) {  | 
|---|
| 955 |       Parent::setForwardFilterMap(cm); | 
|---|
| 956 |       Parent::setBackwardFilterMap(cm); | 
|---|
| 957 |     } | 
|---|
| 958 |   public: | 
|---|
| 959 |     BidirGraphWrapper(Graph& _graph) : Parent() {  | 
|---|
| 960 |       Parent::setGraph(_graph); | 
|---|
| 961 |       Parent::setForwardFilterMap(cm); | 
|---|
| 962 |       Parent::setBackwardFilterMap(cm); | 
|---|
| 963 |     } | 
|---|
| 964 |  | 
|---|
| 965 |     int edgeNum() const {  | 
|---|
| 966 |       return 2*this->graph->edgeNum(); | 
|---|
| 967 |     } | 
|---|
| 968 |     KEEP_MAPS(Parent, BidirGraphWrapper); | 
|---|
| 969 |   }; | 
|---|
| 970 |  | 
|---|
| 971 |  | 
|---|
| 972 |   /// \brief A bidirected graph template. | 
|---|
| 973 |   /// | 
|---|
| 974 |   ///\warning Graph wrappers are in even more experimental state than the other | 
|---|
| 975 |   ///parts of the lib. Use them at you own risk. | 
|---|
| 976 |   /// | 
|---|
| 977 |   /// A bidirected graph template. | 
|---|
| 978 |   /// Such a bidirected graph stores each pair of oppositely directed edges  | 
|---|
| 979 |   /// ones in the memory, i.e. a directed graph of type  | 
|---|
| 980 |   /// \c Graph is used for that. | 
|---|
| 981 |   /// As the oppositely directed edges are logically different ones  | 
|---|
| 982 |   /// the maps are able to attach different values for them. | 
|---|
| 983 |   /// \ingroup graphs | 
|---|
| 984 |   template<typename Graph> | 
|---|
| 985 |   class BidirGraph : public BidirGraphWrapper<Graph> { | 
|---|
| 986 |   public: | 
|---|
| 987 |     typedef UndirGraphWrapper<Graph> Parent; | 
|---|
| 988 |   protected: | 
|---|
| 989 |     Graph gr; | 
|---|
| 990 |   public: | 
|---|
| 991 |     BidirGraph() : BidirGraphWrapper<Graph>() {  | 
|---|
| 992 |       Parent::setGraph(gr);  | 
|---|
| 993 |     } | 
|---|
| 994 |     KEEP_MAPS(Parent, BidirGraph); | 
|---|
| 995 |   }; | 
|---|
| 996 |  | 
|---|
| 997 |  | 
|---|
| 998 |  | 
|---|
| 999 |   template<typename Graph, typename Number, | 
|---|
| 1000 |            typename CapacityMap, typename FlowMap> | 
|---|
| 1001 |   class ResForwardFilter { | 
|---|
| 1002 |     //    const Graph* graph; | 
|---|
| 1003 |     const CapacityMap* capacity; | 
|---|
| 1004 |     const FlowMap* flow; | 
|---|
| 1005 |   public: | 
|---|
| 1006 |     ResForwardFilter(/*const Graph& _graph, */ | 
|---|
| 1007 |                      const CapacityMap& _capacity, const FlowMap& _flow) : | 
|---|
| 1008 |       /*graph(&_graph),*/ capacity(&_capacity), flow(&_flow) { } | 
|---|
| 1009 |     ResForwardFilter() : /*graph(0),*/ capacity(0), flow(0) { } | 
|---|
| 1010 |     void setCapacity(const CapacityMap& _capacity) { capacity=&_capacity; } | 
|---|
| 1011 |     void setFlow(const FlowMap& _flow) { flow=&_flow; } | 
|---|
| 1012 |     bool operator[](const typename Graph::Edge& e) const { | 
|---|
| 1013 |       return (Number((*flow)[e]) < Number((*capacity)[e])); | 
|---|
| 1014 |     } | 
|---|
| 1015 |   }; | 
|---|
| 1016 |  | 
|---|
| 1017 |   template<typename Graph, typename Number, | 
|---|
| 1018 |            typename CapacityMap, typename FlowMap> | 
|---|
| 1019 |   class ResBackwardFilter { | 
|---|
| 1020 |     const CapacityMap* capacity; | 
|---|
| 1021 |     const FlowMap* flow; | 
|---|
| 1022 |   public: | 
|---|
| 1023 |     ResBackwardFilter(/*const Graph& _graph,*/  | 
|---|
| 1024 |                       const CapacityMap& _capacity, const FlowMap& _flow) : | 
|---|
| 1025 |       /*graph(&_graph),*/ capacity(&_capacity), flow(&_flow) { } | 
|---|
| 1026 |     ResBackwardFilter() : /*graph(0),*/ capacity(0), flow(0) { } | 
|---|
| 1027 |     void setCapacity(const CapacityMap& _capacity) { capacity=&_capacity; } | 
|---|
| 1028 |     void setFlow(const FlowMap& _flow) { flow=&_flow; } | 
|---|
| 1029 |     bool operator[](const typename Graph::Edge& e) const { | 
|---|
| 1030 |       return (Number(0) < Number((*flow)[e])); | 
|---|
| 1031 |     } | 
|---|
| 1032 |   }; | 
|---|
| 1033 |  | 
|---|
| 1034 |    | 
|---|
| 1035 |   /// A wrapper for composing the residual graph for directed flow and circulation problems. | 
|---|
| 1036 |  | 
|---|
| 1037 |   ///\warning Graph wrappers are in even more experimental state than the other | 
|---|
| 1038 |   ///parts of the lib. Use them at you own risk. | 
|---|
| 1039 |   /// | 
|---|
| 1040 |   /// A wrapper for composing the residual graph for directed flow and circulation problems. | 
|---|
| 1041 |   template<typename Graph, typename Number,  | 
|---|
| 1042 |            typename CapacityMap, typename FlowMap> | 
|---|
| 1043 |   class ResGraphWrapper :  | 
|---|
| 1044 |     public SubBidirGraphWrapper<  | 
|---|
| 1045 |     Graph,  | 
|---|
| 1046 |     ResForwardFilter<Graph, Number, CapacityMap, FlowMap>,   | 
|---|
| 1047 |     ResBackwardFilter<Graph, Number, CapacityMap, FlowMap> > { | 
|---|
| 1048 |   public: | 
|---|
| 1049 |     typedef SubBidirGraphWrapper<  | 
|---|
| 1050 |       Graph,  | 
|---|
| 1051 |       ResForwardFilter<Graph, Number, CapacityMap, FlowMap>,   | 
|---|
| 1052 |       ResBackwardFilter<Graph, Number, CapacityMap, FlowMap> > Parent; | 
|---|
| 1053 |   protected: | 
|---|
| 1054 |     const CapacityMap* capacity; | 
|---|
| 1055 |     FlowMap* flow; | 
|---|
| 1056 |     ResForwardFilter<Graph, Number, CapacityMap, FlowMap> forward_filter; | 
|---|
| 1057 |     ResBackwardFilter<Graph, Number, CapacityMap, FlowMap> backward_filter; | 
|---|
| 1058 |     ResGraphWrapper() : Parent(),  | 
|---|
| 1059 |                         capacity(0), flow(0) { } | 
|---|
| 1060 |     void setCapacityMap(const CapacityMap& _capacity) { | 
|---|
| 1061 |       capacity=&_capacity; | 
|---|
| 1062 |       forward_filter.setCapacity(_capacity); | 
|---|
| 1063 |       backward_filter.setCapacity(_capacity); | 
|---|
| 1064 |     } | 
|---|
| 1065 |     void setFlowMap(FlowMap& _flow) { | 
|---|
| 1066 |       flow=&_flow; | 
|---|
| 1067 |       forward_filter.setFlow(_flow); | 
|---|
| 1068 |       backward_filter.setFlow(_flow); | 
|---|
| 1069 |     } | 
|---|
| 1070 |   public: | 
|---|
| 1071 |     ResGraphWrapper(Graph& _graph, const CapacityMap& _capacity,  | 
|---|
| 1072 |                        FlowMap& _flow) :  | 
|---|
| 1073 |       Parent(), capacity(&_capacity), flow(&_flow),  | 
|---|
| 1074 |       forward_filter(/*_graph,*/ _capacity, _flow),  | 
|---|
| 1075 |       backward_filter(/*_graph,*/ _capacity, _flow) { | 
|---|
| 1076 |       Parent::setGraph(_graph); | 
|---|
| 1077 |       Parent::setForwardFilterMap(forward_filter); | 
|---|
| 1078 |       Parent::setBackwardFilterMap(backward_filter); | 
|---|
| 1079 |     } | 
|---|
| 1080 |  | 
|---|
| 1081 |     typedef typename Parent::Edge Edge; | 
|---|
| 1082 |  | 
|---|
| 1083 |     void augment(const Edge& e, Number a) const { | 
|---|
| 1084 |       if (Parent::forward(e))   | 
|---|
| 1085 |         flow->set(e, (*flow)[e]+a); | 
|---|
| 1086 |       else   | 
|---|
| 1087 |         flow->set(e, (*flow)[e]-a); | 
|---|
| 1088 |     } | 
|---|
| 1089 |  | 
|---|
| 1090 |     /// \brief Residual capacity map. | 
|---|
| 1091 |     /// | 
|---|
| 1092 |     /// In generic residual graphs the residual capacity can be obtained as a map. Not tested. | 
|---|
| 1093 |     class ResCap { | 
|---|
| 1094 |     protected: | 
|---|
| 1095 |       const ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>* res_graph; | 
|---|
| 1096 |     public: | 
|---|
| 1097 |       typedef Number ValueType; | 
|---|
| 1098 |       typedef Edge KeyType; | 
|---|
| 1099 |       ResCap(const ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>& _res_graph) :  | 
|---|
| 1100 |         res_graph(&_res_graph) { } | 
|---|
| 1101 |       Number operator[](const Edge& e) const {  | 
|---|
| 1102 |         if (res_graph->forward(e))  | 
|---|
| 1103 |           return (*(res_graph->capacity))[e]-(*(res_graph->flow))[e];  | 
|---|
| 1104 |         else  | 
|---|
| 1105 |           return (*(res_graph->flow))[e];  | 
|---|
| 1106 |       } | 
|---|
| 1107 |     }; | 
|---|
| 1108 |  | 
|---|
| 1109 |     KEEP_MAPS(Parent, ResGraphWrapper); | 
|---|
| 1110 |   }; | 
|---|
| 1111 |  | 
|---|
| 1112 |  | 
|---|
| 1113 |   /// For blocking flows. | 
|---|
| 1114 |  | 
|---|
| 1115 |   ///\warning Graph wrappers are in even more experimental state than the other | 
|---|
| 1116 |   ///parts of the lib. Use them at you own risk. | 
|---|
| 1117 |   /// | 
|---|
| 1118 |   /// This graph wrapper is used for on-the-fly  | 
|---|
| 1119 |   /// Dinits blocking flow computations. | 
|---|
| 1120 |   /// For each node, an out-edge is stored which is used when the  | 
|---|
| 1121 |   /// \code  | 
|---|
| 1122 |   /// OutEdgeIt& first(OutEdgeIt&, const Node&) | 
|---|
| 1123 |   /// \endcode | 
|---|
| 1124 |   /// is called.  | 
|---|
| 1125 |   /// | 
|---|
| 1126 |   /// \author Marton Makai | 
|---|
| 1127 |   template<typename Graph, typename FirstOutEdgesMap> | 
|---|
| 1128 |   class ErasingFirstGraphWrapper : public GraphWrapper<Graph> { | 
|---|
| 1129 |   public: | 
|---|
| 1130 |     typedef GraphWrapper<Graph> Parent;  | 
|---|
| 1131 |   protected: | 
|---|
| 1132 |     FirstOutEdgesMap* first_out_edges; | 
|---|
| 1133 |   public: | 
|---|
| 1134 |     ErasingFirstGraphWrapper(Graph& _graph,  | 
|---|
| 1135 |                              FirstOutEdgesMap& _first_out_edges) :  | 
|---|
| 1136 |       GraphWrapper<Graph>(_graph), first_out_edges(&_first_out_edges) { }   | 
|---|
| 1137 |  | 
|---|
| 1138 |     typedef typename GraphWrapper<Graph>::Node Node; | 
|---|
| 1139 |     typedef typename GraphWrapper<Graph>::Edge Edge; | 
|---|
| 1140 |     class OutEdgeIt : public Edge {  | 
|---|
| 1141 |       friend class GraphWrapper<Graph>; | 
|---|
| 1142 |       friend class ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>; | 
|---|
| 1143 |       const ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>* gw; | 
|---|
| 1144 |     public: | 
|---|
| 1145 |       OutEdgeIt() { } | 
|---|
| 1146 |       OutEdgeIt(Invalid i) : Edge(i) { } | 
|---|
| 1147 |       OutEdgeIt(const ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>& _gw,  | 
|---|
| 1148 |                 const Node& n) :  | 
|---|
| 1149 |         Edge((*(_gw.first_out_edges))[n]), gw(&_gw) { } | 
|---|
| 1150 |       OutEdgeIt(const ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>& _gw,  | 
|---|
| 1151 |                 const Edge& e) :  | 
|---|
| 1152 |         Edge(e), gw(&_gw) { } | 
|---|
| 1153 |       OutEdgeIt& operator++() {  | 
|---|
| 1154 |         *(static_cast<Edge*>(this))= | 
|---|
| 1155 |           ++(typename Graph::OutEdgeIt(*(gw->graph), *this)); | 
|---|
| 1156 |         return *this;  | 
|---|
| 1157 |       } | 
|---|
| 1158 |     }; | 
|---|
| 1159 |  | 
|---|
| 1160 |     using GraphWrapper<Graph>::first; | 
|---|
| 1161 |     OutEdgeIt& first(OutEdgeIt& i, const Node& p) const {  | 
|---|
| 1162 |       i=OutEdgeIt(*this, p); return i; | 
|---|
| 1163 |     } | 
|---|
| 1164 |     void erase(const Edge& e) const { | 
|---|
| 1165 |       Node n=tail(e); | 
|---|
| 1166 |       typename Graph::OutEdgeIt f(*Parent::graph, n); | 
|---|
| 1167 |       ++f; | 
|---|
| 1168 |       first_out_edges->set(n, f); | 
|---|
| 1169 |     } | 
|---|
| 1170 |  | 
|---|
| 1171 |     KEEP_MAPS(Parent, ErasingFirstGraphWrapper); | 
|---|
| 1172 |   }; | 
|---|
| 1173 |  | 
|---|
| 1174 |   ///@} | 
|---|
| 1175 |  | 
|---|
| 1176 | } //namespace hugo | 
|---|
| 1177 |  | 
|---|
| 1178 | #endif //HUGO_GRAPH_WRAPPER_H | 
|---|
| 1179 |  | 
|---|