Merge back the whole branches/hugo++ to trunk.
2 #ifndef HUGO_BIPARTITE_GRAPH_WRAPPER_H
3 #define HUGO_BIPARTITE_GRAPH_WRAPPER_H
7 ///\brief Several graph wrappers.
9 ///This file contains several useful graph wrapper functions.
11 ///\author Marton Makai
13 #include <hugo/invalid.h>
15 #include <hugo/graph_wrapper.h>
16 #include <for_each_macros.h>
20 /// \brief A wrapper for composing a bipartite graph from a graph
21 /// and from a node-map showing for any node which color class it belongs to.
23 /// A wrapper for composing a bipartite graph.
24 /// \c _graph have to be a reference to a graph of type \c Graph
25 /// and \c _s_false_t_true_map is an \c IterableBoolMap
26 /// reference containing the elements for the
27 /// color classes S and T. \c _graph is to be referred to an undirected
28 /// graph or a directed graph with edges oriented from S to T.
30 /// \author Marton Makai
31 template<typename Graph>
32 class BipartiteGraphWrapper : public GraphWrapper<Graph> {
34 typedef IterableBoolMap< typename Graph::template NodeMap<int> >
37 SFalseTTrueMap* s_false_t_true_map;
39 BipartiteGraphWrapper() : GraphWrapper<Graph>()/*,
40 S_CLASS(false), T_CLASS(true)*/ { }
41 void setSFalseTTrueMap(SFalseTTrueMap& _s_false_t_true_map) {
42 s_false_t_true_map=&_s_false_t_true_map;
47 //FIXME vhogy igy kellene, csak az en forditom nem eszi meg
48 static const bool S_CLASS;
49 static const bool T_CLASS;
51 /// This method is to reach the iterable maps of the bipartite graph or
52 /// bipartite graph wrapper.
53 const SFalseTTrueMap& sFalseTTrueMap() const {
54 return *s_false_t_true_map;
60 BipartiteGraphWrapper(Graph& _graph, SFalseTTrueMap& _s_false_t_true_map)
61 : GraphWrapper<Graph>(_graph),
62 s_false_t_true_map(&_s_false_t_true_map)/*,
63 S_CLASS(false), T_CLASS(true)*/ { }
64 typedef typename GraphWrapper<Graph>::Node Node;
65 //using GraphWrapper<Graph>::NodeIt;
66 typedef typename GraphWrapper<Graph>::Edge Edge;
67 //using GraphWrapper<Graph>::EdgeIt;
69 friend class ClassNodeIt;
71 friend class OutEdgeIt;
73 friend class InEdgeIt;
75 friend class BipartiteGraphWrapper<Graph>;
80 ClassNodeIt(const Invalid& i) : n(i) { }
81 ClassNodeIt(const BipartiteGraphWrapper<Graph>& _G, bool _class) {
82 _G.s_false_t_true_map->first(n, _class);
84 //FIXME needed in new concept, important here
85 ClassNodeIt(const Node& _n) : n(_n) { }
86 operator Node() const { return n; }
92 // SNodeIt(const Invalid& i) : n(i) { }
93 // SNodeIt(const BipartiteGraphWrapper<Graph>& _G) {
94 // _G.s_false_t_true_map->first(n, false);
96 // operator Node() const { return n; }
102 // TNodeIt(const Invalid& i) : n(i) { }
103 // TNodeIt(const BipartiteGraphWrapper<Graph>& _G) {
104 // _G.s_false_t_true_map->first(n, true);
106 // operator Node() const { return n; }
109 friend class BipartiteGraphWrapper<Graph>;
111 typename Graph::OutEdgeIt e;
114 OutEdgeIt(const Invalid& i) : e(i) { }
115 OutEdgeIt(const BipartiteGraphWrapper<Graph>& _G, const Node& _n) {
116 if (!(*(_G.s_false_t_true_map))[_n])
117 e=typename Graph::OutEdgeIt(*(_G.graph), typename Graph::Node(_n));
121 operator Edge() const { return Edge(typename Graph::Edge(e)); }
124 friend class BipartiteGraphWrapper<Graph>;
126 typename Graph::InEdgeIt e;
129 InEdgeIt(const Invalid& i) : e(i) { }
130 InEdgeIt(const BipartiteGraphWrapper<Graph>& _G, const Node& _n) {
131 if ((*(_G.s_false_t_true_map))[_n])
132 e=typename Graph::InEdgeIt(*(_G.graph), typename Graph::Node(_n));
136 operator Edge() const { return Edge(typename Graph::Edge(e)); }
139 using GraphWrapper<Graph>::first;
140 ClassNodeIt& first(ClassNodeIt& n, bool _class) const {
141 n=ClassNodeIt(*this, _class) ; return n; }
142 // SNodeIt& first(SNodeIt& n) const { n=SNodeIt(*this); return n; }
143 // TNodeIt& first(TNodeIt& n) const { n=TNodeIt(*this); return n; }
144 OutEdgeIt& first(OutEdgeIt& i, const Node& p) const {
145 i=OutEdgeIt(*this, p); return i;
147 InEdgeIt& first(InEdgeIt& i, const Node& p) const {
148 i=InEdgeIt(*this, p); return i;
151 using GraphWrapper<Graph>::next;
152 ClassNodeIt& next(ClassNodeIt& n) const {
153 this->s_false_t_true_map->next(n.n); return n;
155 // SNodeIt& next(SNodeIt& n) const {
156 // this->s_false_t_true_map->next(n); return n;
158 // TNodeIt& next(TNodeIt& n) const {
159 // this->s_false_t_true_map->next(n); return n;
161 OutEdgeIt& next(OutEdgeIt& i) const { this->graph->next(i.e); return i; }
162 InEdgeIt& next(InEdgeIt& i) const { this->graph->next(i.e); return i; }
164 Node tail(const Edge& e) {
165 if (!(*(this->s_false_t_true_map))[this->graph->tail(e)])
166 return Node(this->graph->tail(e));
168 return Node(this->graph->head(e));
170 Node head(const Edge& e) {
171 if (!(*(this->s_false_t_true_map))[this->graph->tail(e)])
172 return Node(this->graph->head(e));
174 return Node(this->graph->tail(e));
177 Node aNode(const OutEdgeIt& e) const {
178 return Node(this->graph->aNode(e.e));
180 Node aNode(const InEdgeIt& e) const {
181 return Node(this->graph->aNode(e.e));
183 Node bNode(const OutEdgeIt& e) const {
184 return Node(this->graph->bNode(e.e));
186 Node bNode(const InEdgeIt& e) const {
187 return Node(this->graph->bNode(e.e));
190 /// Returns true iff \c n is in S.
191 bool inSClass(const Node& n) const {
192 return !(*(this->s_false_t_true_map))[n];
195 /// Returns true iff \c n is in T.
196 bool inTClass(const Node& n) const {
197 return (*(this->s_false_t_true_map))[n];
203 const bool BipartiteGraphWrapper<G>::S_CLASS=false;
205 const bool BipartiteGraphWrapper<G>::T_CLASS=true;
207 /// \brief A bipartite graph template class
209 /// This class composes a bipartite graph over a directed or undirected
210 /// graph structure of type \c Graph.
211 /// \c _graph have to be a reference to a graph of type \c Graph
212 /// and \c _s_false_t_true_map is an \c IterableBoolMap
213 /// reference containing the elements for the
214 /// color classes S and T. \c _graph is to be referred to an undirected
215 /// graph or a directed graph with edges oriented from S to T.
217 ///\bug experimental. Do not use this while the bipartitemap augmentation
218 /// does not work well.
219 template<typename Graph>
220 class BipartiteGraph : public BipartiteGraphWrapper<Graph> {
221 // typedef IterableBoolMap< typename Graph::template NodeMap<int> >
223 typedef BipartiteGraphWrapper<Graph> Parent;
226 typename Graph::template NodeMap<int> bipartite_map;
227 typename Parent::SFalseTTrueMap s_false_t_true_map;
229 typedef typename Parent::Node Node;
230 typedef typename Parent::Edge Edge;
231 BipartiteGraph() : BipartiteGraphWrapper<Graph>(),
232 gr(), bipartite_map(gr, -1),
233 s_false_t_true_map(bipartite_map) {
234 Parent::setGraph(gr);
235 Parent::setSFalseTTrueMap(s_false_t_true_map);
238 /// the \c bool parameter which can be \c S_Class or \c T_Class shows
239 /// the color class where the new node is to be inserted.
240 Node addNode(bool b) {
241 Node n=Parent::graph->addNode();
242 bipartite_map.update();
243 //bipartite_map.set(n, -1);
244 s_false_t_true_map.insert(n, b);
248 /// A new edge is inserted.
249 ///\pre \c tail have to be in \c S_Class and \c head in \c T_Class.
250 Edge addEdge(const Node& tail, const Node& head) {
251 return Parent::graph->addEdge(tail, head);
254 void erase(const Node& n) {
255 s_false_t_true_map.remove(n);
256 Parent::graph->erase(n);
258 void erase(const Edge& e) {
259 Parent::graph->erase(e);
263 FOR_EACH_LOC(typename Parent::EdgeIt, e, *this) erase(e);
264 FOR_EACH_LOC(typename Parent::NodeIt, n, *this) erase(n);
268 template<typename Graph, typename sIterableMap, typename tIterableMap>
269 class stGraphWrapper;
271 /// Easier stuff for bipartite graphs.
272 template<typename Graph>
273 class stBipartiteGraphWrapper : public
274 stGraphWrapper<Graph, typename Graph::SFalseTTrueMap,
275 typename Graph::SFalseTTrueMap> {
277 typedef stGraphWrapper<Graph, typename Graph::SFalseTTrueMap,
278 typename Graph::SFalseTTrueMap> Parent;
279 stBipartiteGraphWrapper(Graph& _graph) :
280 Parent(_graph, _graph.sFalseTTrueMap(), _graph.sFalseTTrueMap()) { }
283 // template<typename Graph>
285 // operator<<(std::ostream& os, const typename stGraphWrapper<Graph>::Node& i) {
286 // os << "(node: " << typename Graph::Node(i) << " spec: " << i.spec <<")";
289 // template<typename Graph>
291 // operator<<(std::ostream& os, const typename stGraphWrapper<Graph>::Edge& i) {
292 // os << "(edge: " << typename Graph::Edge(i) << " spec: " << i.spec <<
293 // " node: " << i.n << ")";
297 /// \brief A wrapper for adding extra nodes s and t to a bipartite graph
298 /// and edges from s to each node of S and form each node of T to t.
300 /// A wrapper for adding extra nodes s and t to a bipartite graph
301 /// and edges from s to each node of S and form each node of T to t.
302 /// This class is very useful to reduce some matching or more
303 /// generally, capacitataed b-matching problem to a flow problem.
304 /// According to the bipartite graph concepts the bipartite
305 /// graph have to be oriented from S to T.
307 /// \author Marton Makai
308 template<typename Graph, typename sIterableMap, typename tIterableMap>
309 class stGraphWrapper : public GraphWrapper<Graph> {
311 const sIterableMap* s_iterable_map;
312 const tIterableMap* t_iterable_map;
317 //0 normalis, 1 s, 2 t, ez az iteralasi sorrend,
318 //es a vege a false azaz (invalid, 3)
325 //0 normalis, 1 s->vmi, 2 vmi->t, ez a sorrend,
326 //invalid: (invalid, 3, invalid)
328 friend class OutEdgeIt;
330 //normalis pontbol (first, 0, invalid), ..., (invalid, 2, vmi), ... (invalid, 3, invalid)
331 //s-bol (invalid, 1, first), ... (invalid, 3, invalid)
332 //t-bol (invalid, 3, invalid)
334 friend class InEdgeIt;
336 //normalis pontbol (first, 0, invalid), ..., (invalid, 1, vmi), ... (invalid, 3, invalid)
337 //s-be (invalid, 3, invalid)
338 //t-be (invalid, 2, first), ... (invalid, 3, invalid)
341 //(first, 0, invalid) ...
344 //invalid, 3, invalid)
345 template <typename T> class NodeMap;
346 template <typename T> class EdgeMap;
348 // template <typename T> friend class NodeMap;
349 // template <typename T> friend class EdgeMap;
351 ///\todo FIXME ezt majd static-ra kell javitani
355 static const bool S_CLASS=false;
356 static const bool T_CLASS=true;
358 // \bug not too nice constructor.
359 stGraphWrapper(Graph& _graph,
360 const sIterableMap& _s_iterable_map,
361 const tIterableMap& _t_iterable_map) :
362 GraphWrapper<Graph>(_graph),
363 s_iterable_map(&_s_iterable_map),
364 t_iterable_map(&_t_iterable_map),
366 T_NODE(INVALID, 2) { }
370 // operator<<(std::ostream& os, const /*typename stGraphWrapper<Graph>::*/Node& i);
371 // friend std::ostream&
372 // operator<<(std::ostream& os, const /*typename stGraphWrapper<Graph>::*/Node& i);
373 // friend std::ostream&
374 // operator<<(std::ostream& os, const /*typename stGraphWrapper<Graph>::*/Edge& i);
376 class Node : public Graph::Node {
378 friend class GraphWrapper<Graph>;
379 friend class stGraphWrapper<Graph, sIterableMap, tIterableMap>;
380 template <typename T> friend class NodeMap;
382 friend class OutEdgeIt;
383 friend class InEdgeIt;
388 Node(const typename Graph::Node& _n, int _spec=0) :
389 Graph::Node(_n), spec(_spec) { }
390 Node(const Invalid& i) : Graph::Node(i), spec(3) { }
391 friend bool operator==(const Node& u, const Node& v) {
392 return (u.spec==v.spec &&
393 static_cast<typename Graph::Node>(u)==
394 static_cast<typename Graph::Node>(v));
396 friend bool operator!=(const Node& u, const Node& v) {
397 return (v.spec!=u.spec ||
398 static_cast<typename Graph::Node>(u)!=
399 static_cast<typename Graph::Node>(v));
401 // template<typename G>
402 // friend std::ostream&
403 // operator<<(std::ostream& os, const typename stGraphWrapper<G>::Node& i);
404 friend std::ostream& operator<< (std::ostream& os, const Node& i);
405 int getSpec() const { return spec; }
409 friend class GraphWrapper<Graph>;
410 friend class stGraphWrapper<Graph, sIterableMap, tIterableMap>;
411 typename Graph::NodeIt n;
415 NodeIt(const typename Graph::NodeIt& _n, int _spec) :
416 n(_n), spec(_spec) { }
417 NodeIt(const Invalid& i) : n(i), spec(3) { }
418 NodeIt(const stGraphWrapper<Graph, sIterableMap, tIterableMap>& _G)
419 : n(*(_G.graph)), spec(0) {
420 if (!_G.graph->valid(n)) spec=1;
422 operator Node() const { return Node(n, spec); }
425 class Edge : public Graph::Edge {
426 friend class GraphWrapper<Graph>;
427 friend class stGraphWrapper<Graph, sIterableMap, tIterableMap>;
428 template <typename T> friend class EdgeMap;
430 typename Graph::Node n;
433 Edge(const typename Graph::Edge& _e, int _spec,
434 const typename Graph::Node& _n) :
435 Graph::Edge(_e), spec(_spec), n(_n) {
437 Edge(const Invalid& i) : Graph::Edge(i), spec(3), n(i) { }
438 friend bool operator==(const Edge& u, const Edge& v) {
439 return (u.spec==v.spec &&
440 static_cast<typename Graph::Edge>(u)==
441 static_cast<typename Graph::Edge>(v) &&
444 friend bool operator!=(const Edge& u, const Edge& v) {
445 return (v.spec!=u.spec ||
446 static_cast<typename Graph::Edge>(u)!=
447 static_cast<typename Graph::Edge>(v) ||
450 // template<typename G>
451 // friend std::ostream&
452 // operator<<(std::ostream& os, const typename stGraphWrapper<G>::Edge& i);
453 friend std::ostream& operator<< (std::ostream& os, const Edge& i);
454 int getSpec() const { return spec; }
455 typename Graph::Node getNode() const { return n; }
459 friend class GraphWrapper<Graph>;
460 friend class stGraphWrapper<Graph, sIterableMap, tIterableMap>;
461 typename Graph::OutEdgeIt e;
463 typename Graph::ClassNodeIt n;
466 OutEdgeIt(const typename Graph::OutEdgeIt& _e, int _spec,
467 const typename Graph::ClassNodeIt& _n) :
468 e(_e), spec(_spec), n(_n) {
470 OutEdgeIt(const Invalid& i) : e(i), spec(3), n(i) { }
471 OutEdgeIt(const stGraphWrapper<Graph, sIterableMap, tIterableMap>& _G,
475 if (_G.graph->inSClass(_n)) { //S, van normalis kiel
476 e=typename Graph::OutEdgeIt(*(_G.graph),
477 typename Graph::Node(_n));
480 if (!_G.graph->valid(e)) spec=3;
481 } else { //T, specko kiel van
490 _G.graph->first(n, S_CLASS); //s->vmi;
491 if (!_G.graph->valid(n)) spec=3; //Ha S ures
500 operator Edge() const { return Edge(e, spec, n); }
504 friend class GraphWrapper<Graph>;
505 friend class stGraphWrapper<Graph, sIterableMap, tIterableMap>;
506 typename Graph::InEdgeIt e;
508 typename Graph::ClassNodeIt n;
511 InEdgeIt(const typename Graph::InEdgeIt& _e, int _spec,
512 const typename Graph::ClassNodeIt& _n) :
513 e(_e), spec(_spec), n(_n) {
515 InEdgeIt(const Invalid& i) : e(i), spec(3), n(i) { }
516 InEdgeIt(const stGraphWrapper<Graph, sIterableMap, tIterableMap>& _G,
520 if (_G.graph->inTClass(_n)) { //T, van normalis beel
521 e=typename Graph::InEdgeIt(*(_G.graph),
522 typename Graph::Node(_n));
525 if (!_G.graph->valid(e)) spec=3;
526 } else { //S, specko beel van
540 _G.graph->first(n, T_CLASS); //vmi->t;
541 if (!_G.graph->valid(n)) spec=3; //Ha T ures
545 operator Edge() const { return Edge(e, spec, n); }
549 friend class GraphWrapper<Graph>;
550 friend class stGraphWrapper<Graph, sIterableMap, tIterableMap>;
551 typename Graph::EdgeIt e;
553 typename Graph::ClassNodeIt n;
556 EdgeIt(const typename Graph::EdgeIt& _e, int _spec,
557 const typename Graph::ClassNodeIt& _n) :
558 e(_e), spec(_spec), n(_n) { }
559 EdgeIt(const Invalid& i) : e(i), spec(3), n(i) { }
560 EdgeIt(const stGraphWrapper<Graph, sIterableMap, tIterableMap>& _G) :
561 e(*(_G.graph)), spec(0), n(INVALID) {
562 if (!_G.graph->valid(e)) {
564 _G.graph->first(n, S_CLASS);
565 if (!_G.graph->valid(n)) { //Ha S ures
567 _G.graph->first(n, T_CLASS);
568 if (!_G.graph->valid(n)) { //Ha T ures
574 operator Edge() const { return Edge(e, spec, n); }
577 NodeIt& first(NodeIt& i) const {
578 i=NodeIt(*this); return i;
580 OutEdgeIt& first(OutEdgeIt& i, const Node& p) const {
581 i=OutEdgeIt(*this, p); return i;
583 InEdgeIt& first(InEdgeIt& i, const Node& p) const {
584 i=InEdgeIt(*this, p); return i;
586 EdgeIt& first(EdgeIt& i) const {
587 i=EdgeIt(*this); return i;
590 NodeIt& next(NodeIt& i) const {
593 this->graph->next(i.n);
594 if (!this->graph->valid(i.n)) {
607 OutEdgeIt& next(OutEdgeIt& i) const {
608 typename Graph::Node v;
610 case 0: //normal edge
611 v=this->graph->aNode(i.e);
612 this->graph->next(i.e);
613 if (!this->graph->valid(i.e)) { //Az igazi elek vegere ertunk
614 if (this->graph->inSClass(v)) { //S, nincs kiel
617 } else { //T, van kiel
624 this->graph->next(i.n);
625 if (!this->graph->valid(i.n)) i.spec=3;
634 InEdgeIt& next(InEdgeIt& i) const {
635 typename Graph::Node v;
637 case 0: //normal edge
638 v=this->graph->aNode(i.e);
639 this->graph->next(i.e);
640 if (!this->graph->valid(i.e)) { //Az igazi elek vegere ertunk
641 if (this->graph->inTClass(v)) { //S, nincs beel
644 } else { //S, van beel
655 this->graph->next(i.n);
656 if (!this->graph->valid(i.n)) i.spec=3;
662 EdgeIt& next(EdgeIt& i) const {
665 this->graph->next(i.e);
666 if (!this->graph->valid(i.e)) {
668 this->graph->first(i.n, S_CLASS);
669 if (!this->graph->valid(i.n)) {
671 this->graph->first(i.n, T_CLASS);
672 if (!this->graph->valid(i.n)) i.spec=3;
677 this->graph->next(i.n);
678 if (!this->graph->valid(i.n)) {
680 this->graph->first(i.n, T_CLASS);
681 if (!this->graph->valid(i.n)) i.spec=3;
685 this->graph->next(i.n);
686 if (!this->graph->valid(i.n)) i.spec=3;
692 Node tail(const Edge& e) const {
695 return Node(this->graph->tail(e));
706 Node head(const Edge& e) const {
709 return Node(this->graph->head(e));
721 bool valid(const Node& n) const { return (n.spec<3); }
722 bool valid(const Edge& e) const { return (e.spec<3); }
724 int nodeNum() const { return this->graph->nodeNum()+2; }
725 int edgeNum() const {
726 return this->graph->edgeNum()+this->graph->nodeNum();
729 Node aNode(const OutEdgeIt& e) const { return tail(e); }
730 Node aNode(const InEdgeIt& e) const { return head(e); }
731 Node bNode(const OutEdgeIt& e) const { return head(e); }
732 Node bNode(const InEdgeIt& e) const { return tail(e); }
734 void addNode() const { }
735 void addEdge() const { }
737 // Node addNode() const { return Node(this->graph->addNode()); }
738 // Edge addEdge(const Node& tail, const Node& head) const {
739 // return Edge(this->graph->addEdge(tail, head)); }
741 // void erase(const Node& i) const { this->graph->erase(i); }
742 // void erase(const Edge& i) const { this->graph->erase(i); }
744 // void clear() const { this->graph->clear(); }
746 template<typename T> class NodeMap : public GraphWrapper<Graph>::template NodeMap<T> {
747 typedef typename GraphWrapper<Graph>::template NodeMap<T> Parent;
751 NodeMap(const stGraphWrapper<Graph, sIterableMap, tIterableMap>& _G) :
755 NodeMap(const stGraphWrapper<Graph, sIterableMap, tIterableMap>& _G, T a)
759 T operator[](const Node& n) const {
762 return Parent::operator[](n);
770 void set(const Node& n, T t) {
773 GraphWrapper<Graph>::template NodeMap<T>::set(n, t);
786 /// This class is to wrap a node-map of \c Graph and two variables
787 /// storing values for \c S_NODE and \c T_NODE to a node-map of
788 /// stGraphWrapper<Graph, sIterableMap, tIterableMap>.
789 template<typename NM> class NodeMapWrapper {
791 typedef Node KeyType;
792 typedef typename NM::ValueType ValueType;
795 ValueType* s_value, t_value;
797 NodeMapWrapper(NM& _nm, ValueType& _s_value, ValueType& _t_value) :
798 nm(&_nm), s_value(&_s_value), t_value(&_t_value) { }
799 ValueType operator[](const Node& n) const {
800 switch (n.getSpec()) {
810 void set(const Node& n, ValueType t) {
811 switch (n.getSpec()) {
827 class EdgeMap : public GraphWrapper<Graph>::template EdgeMap<T> {
828 typedef typename GraphWrapper<Graph>::template EdgeMap<T> Parent;
830 typename GraphWrapper<Graph>::template NodeMap<T> node_value;
832 EdgeMap(const stGraphWrapper<Graph, sIterableMap, tIterableMap>& _G)
835 EdgeMap(const stGraphWrapper<Graph, sIterableMap, tIterableMap>& _G, T a)
837 node_value(_G, a) { }
838 T operator[](const Edge& e) const {
841 return Parent::operator[](e);
843 return node_value[e.n];
846 return node_value[e.n];
849 void set(const Edge& e, T t) {
855 node_value.set(e.n, t);
859 node_value.set(e.n, t);
865 /// This class is to wrap an edge-map and a node-map of \c Graph
866 /// to an edge-map of stGraphWrapper<Graph, sIterableMap, tIterableMap>.
867 template<typename EM, typename NM>
868 class EdgeMapWrapper {
870 typedef Edge KeyType;
871 typedef typename EM::ValueType ValueType;
876 EdgeMapWrapper(EM& _em, NM& _nm) : em(&_em), nm(&_nm) { }
877 ValueType operator[](const Edge& e) const {
878 switch (e.getSpec()) {
882 return (*nm)[e.getNode()];
885 return (*nm)[e.getNode()];
888 void set(const Edge& e, ValueType t) {
889 switch (e.getSpec()) {
894 nm->set(e.getNode(), t);
898 nm->set(e.getNode(), t);
905 // template<typename G>
907 operator<<(std::ostream& os, const /*typename stGraphWrapper<Graph>::*/Node& i) {
908 os << "(node: " << typename Graph::Node(i) << " spec: " << i.spec <<")";
911 // template<typename G>
913 operator<<(std::ostream& os, const /*typename stGraphWrapper<Graph>::*/Edge& i) {
914 os << "(edge: " << typename Graph::Edge(i) << " spec: " << i.spec <<
915 " node: " << i.n << ")";
926 #endif //HUGO_BIPARTITE_GRAPH_WRAPPER_H