# HG changeset patch # User marci # Date 1100959767 0 # Node ID b3bdd856faf43a606e175669849e83087a9d84c7 # Parent 2bfbe3f4307c944e28f755f3e500c3bbdf1577c5 MergeGraphWrapper diff -r 2bfbe3f4307c -r b3bdd856faf4 src/lemon/graph_wrapper.h --- a/src/lemon/graph_wrapper.h Sat Nov 20 11:10:56 2004 +0000 +++ b/src/lemon/graph_wrapper.h Sat Nov 20 14:09:27 2004 +0000 @@ -1175,17 +1175,6 @@ EdgeMap(const SubBidirGraphWrapperBase<_Graph, ForwardFilterMap, BackwardFilterMap>& g, T a) : forward_map(*(g.graph), a), backward_map(*(g.graph), a) { } - -// template -// EdgeMap(const EdgeMap& copy) -// : forward_map(copy.forward_map), backward_map(copy.backward_map) {} - -// template -// EdgeMap& operator=(const EdgeMap& copy) { -// forward_map = copy.forward_map; -// backward_map = copy.backward_map; -// return *this; -// } void set(Edge e, T a) { if (!e.backward) diff -r 2bfbe3f4307c -r b3bdd856faf4 src/work/marci/merge_node_graph_wrapper.h --- a/src/work/marci/merge_node_graph_wrapper.h Sat Nov 20 11:10:56 2004 +0000 +++ b/src/work/marci/merge_node_graph_wrapper.h Sat Nov 20 14:09:27 2004 +0000 @@ -22,6 +22,7 @@ #include #include #include + using std::cout; using std::endl; @@ -38,14 +39,17 @@ class P2 : public GraphWrapperBase<_Graph2> { }; - /*! A base class for merging the node-set of two node-disjoint graphs - into the node-set of one graph. + + /*! A graph wrapper base class + for merging the node-set of two node-disjoint graphs + into the node-set of one graph. + Generic implementation for unrelated _Graph1::Node and _Graph2::Node. */ template class MergeNodeGraphWrapperBase : public P1<_Graph1>, public P2<_Graph2> { public: - void printNode() const { std::cout << "generic" << std::endl; } + static void printNode() { std::cout << "node: generic" << std::endl; } typedef _Graph1 Graph1; typedef _Graph2 Graph2; typedef P1<_Graph1> Parent1; @@ -59,7 +63,7 @@ class Node : public Graph1Node, public Graph2Node { friend class MergeNodeGraphWrapperBase<_Graph1, _Graph2>; - template friend class NodeMap; + template friend class NodeMap; protected: bool backward; //true, iff backward public: @@ -72,18 +76,15 @@ Graph1Node(n1), Graph2Node(n2), backward(_backward) { } Node(Invalid i) : Graph1Node(i), Graph2Node(i), backward(true) { } bool operator==(const Node& v) const { - return (this->backward==v.backward && - static_cast(*this)== - static_cast(v) && - static_cast(*this)== - static_cast(v)); + if (backward) + return (v.backward && + static_cast(*this)==static_cast(v)); + else + return (!v.backward && + static_cast(*this)==static_cast(v)); } bool operator!=(const Node& v) const { - return (this->backward!=v.backward || - static_cast(*this)!= - static_cast(v) || - static_cast(*this)!= - static_cast(v)); + return !(*this==v); } }; @@ -118,29 +119,33 @@ } template - class NodeMap : public Parent1::template NodeMap<_Value>, - public Parent2::template NodeMap<_Value> { - typedef typename Parent1::template NodeMap<_Value> ParentMap1; - typedef typename Parent2::template NodeMap<_Value> ParentMap2; + class NodeMap { + protected: + typedef typename _Graph1::template NodeMap<_Value> ParentMap1; + typedef typename _Graph2::template NodeMap<_Value> ParentMap2; + ParentMap1 forward_map; + ParentMap2 backward_map; public: typedef _Value Value; typedef Node Key; NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw) : - ParentMap1(gw), ParentMap2(gw) { } + forward_map(*(gw.Parent1::graph)), + backward_map(*(gw.Parent2::graph)) { } NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw, const _Value& value) : - ParentMap1(gw, value), ParentMap2(gw, value) { } + forward_map(*(gw.Parent1::graph), value), + backward_map(*(gw.Parent2::graph), value) { } _Value operator[](const Node& n) const { if (!n.backward) - return ParentMap1::operator[](n); + return forward_map[n]; else - return ParentMap2::operator[](n); + return backward_map[n]; } void set(const Node& n, const _Value& value) { if (!n.backward) - ParentMap1::set(n, value); + forward_map.set(n, value); else - ParentMap2::set(n, value); + backward_map.set(n, value); } // using ParentMap1::operator[]; // using ParentMap2::operator[]; @@ -148,14 +153,19 @@ }; - //not yet working + + /*! A graph wrapper base class + for merging the node-set of two node-disjoint graphs + into the node-set of one graph. + Specialization for the case when _Graph1::Node are the same _Graph2::Node. + */ template class MergeNodeGraphWrapperBase< _Graph1, _Graph2, typename boost::enable_if< boost::is_same >::type> : public P1<_Graph1>, public P2<_Graph2> { - public : - void printNode() const { std::cout << "same" << std::endl; } + public: + static void printNode() { std::cout << "node: same" << std::endl; } typedef _Graph1 Graph1; typedef _Graph2 Graph2; typedef P1<_Graph1> Parent1; @@ -165,20 +175,111 @@ protected: MergeNodeGraphWrapperBase() { } public: - class Node { }; + template class NodeMap; + + class Node : public Graph1Node { + friend class MergeNodeGraphWrapperBase<_Graph1, _Graph2>; + template friend class NodeMap; + protected: + bool backward; //true, iff backward + public: + Node() { } + /// \todo =false is needed, or causes problems? + /// If \c _backward is false, then we get an edge corresponding to the + /// original one, otherwise its oppositely directed pair is obtained. + Node(const Graph1Node& n1, + const Graph2Node& n2, bool _backward) : + Graph1Node(!backward ? n1 : n2), backward(_backward) { } + Node(Invalid i) : Graph1Node(i), backward(true) { } + bool operator==(const Node& v) const { + return (backward==v.backward && + static_cast(*this)==static_cast(v)); + } + bool operator!=(const Node& v) const { + return !(*this==v); + } + }; + + //typedef void Edge; class Edge { }; - void first() const; - void next() const; + + void first(Node& i) const { + Parent1::graph->first(*static_cast(&i)); + i.backward=false; + if (*static_cast(&i)==INVALID) { + Parent2::graph->first(*static_cast(&i)); + i.backward=true; + } + } + void next(Node& i) const { + if (!(i.backward)) { + Parent1::graph->next(*static_cast(&i)); + if (*static_cast(&i)==INVALID) { + Parent2::graph->first(*static_cast(&i)); + i.backward=true; + } + } else { + Parent2::graph->next(*static_cast(&i)); + } + } + + int id(const Node& n) const { + if (!n.backward) + return this->Parent1::graph->id(n); + else + return this->Parent2::graph->id(n); + } + + template + class NodeMap { + protected: + typedef typename _Graph1::template NodeMap<_Value> ParentMap1; + typedef typename _Graph2::template NodeMap<_Value> ParentMap2; + ParentMap1 forward_map; + ParentMap2 backward_map; + public: + typedef _Value Value; + typedef Node Key; + NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw) : + forward_map(*(gw.Parent1::graph)), + backward_map(*(gw.Parent2::graph)) { } + NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw, + const _Value& value) : + forward_map(*(gw.Parent1::graph), value), + backward_map(*(gw.Parent2::graph), value) { } + _Value operator[](const Node& n) const { + if (!n.backward) + return forward_map[n]; + else + return backward_map[n]; + } + void set(const Node& n, const _Value& value) { + if (!n.backward) + forward_map.set(n, value); + else + backward_map.set(n, value); + } +// using ParentMap1::operator[]; +// using ParentMap2::operator[]; + }; + }; - //not yet working + + /*! A graph wrapper base class + for merging the node-set of two node-disjoint graphs + into the node-set of one graph. + Specialization for the case when + _Graph1::Node are base and derived _Graph2::Node. + NOT YET IMPLEMENTED + */ template class MergeNodeGraphWrapperBase< _Graph1, _Graph2, typename boost::enable_if< boost::is_base_and_derived >::type> : public P1<_Graph1>, public P2<_Graph2> { public : - void printNode() const { std::cout << "2. nagyobb" << std::endl; } + static void printNode() { std::cout << "node: 2nd is derived" << std::endl; } typedef _Graph1 Graph1; typedef _Graph2 Graph2; typedef P1<_Graph1> Parent1; @@ -201,7 +302,7 @@ boost::is_base_and_derived >::type> : public P1<_Graph1>, public P2<_Graph2> { public : - void printNode() const { std::cout << "1. nagyobb" << std::endl; } + static void printNode() { std::cout << "node: 1st is derived" << std::endl; } typedef _Graph1 Graph1; typedef _Graph2 Graph2; typedef P1<_Graph1> Parent1; @@ -218,6 +319,12 @@ }; + /*! A graph wrapper class + fors merging the node-set of two node-disjoint graphs + into one node-set. It does not satisfy + StaticGraph concept as it has no edge-set which + works together with the node-set. + */ template class MergeNodeGraphWrapper : public IterableGraphExtender > { @@ -236,15 +343,17 @@ }; - /*! A base class for merging the node-sets and edge-sets of + /*! A grah wrapper base class + for merging the node-sets and edge-sets of two node-disjoint graphs into one graph. + Generic implementation for unrelated _Graph1::Edge and _Graph2::Edge. */ template class MergeEdgeGraphWrapperBase : public MergeNodeGraphWrapperBase<_Graph1, _Graph2> { public: - void printEdge() const { std::cout << "generic" << std::endl; } + static void printEdge() { std::cout << "edge: generic" << std::endl; } typedef _Graph1 Graph1; typedef _Graph2 Graph2; typedef MergeNodeGraphWrapperBase<_Graph1, _Graph2> Parent; @@ -263,7 +372,7 @@ class Edge : public Graph1Edge, public Graph2Edge { friend class MergeEdgeGraphWrapperBase<_Graph1, _Graph2>; - template friend class EdgeMap; + template friend class EdgeMap; protected: bool backward; //true, iff backward public: @@ -276,18 +385,15 @@ Graph1Edge(n1), Graph2Edge(n2), backward(_backward) { } Edge(Invalid i) : Graph1Edge(i), Graph2Edge(i), backward(true) { } bool operator==(const Edge& v) const { - return (this->backward==v.backward && - static_cast(*this)== - static_cast(v) && - static_cast(*this)== - static_cast(v)); + if (backward) + return (v.backward && + static_cast(*this)==static_cast(v)); + else + return (!v.backward && + static_cast(*this)==static_cast(v)); } bool operator!=(const Edge& v) const { - return (this->backward!=v.backward || - static_cast(*this)!= - static_cast(v) || - static_cast(*this)!= - static_cast(v)); + return !(*this==v); } }; @@ -381,29 +487,33 @@ } template - class EdgeMap : public Parent1::template EdgeMap<_Value>, - public Parent2::template EdgeMap<_Value> { - typedef typename Parent1::template EdgeMap<_Value> ParentMap1; - typedef typename Parent2::template EdgeMap<_Value> ParentMap2; + class EdgeMap { + protected: + typedef typename Parent::Graph1::template EdgeMap<_Value> ParentMap1; + typedef typename Parent::Graph2::template EdgeMap<_Value> ParentMap2; + ParentMap1 forward_map; + ParentMap2 backward_map; public: typedef _Value Value; typedef Edge Key; EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw) : - ParentMap1(gw), ParentMap2(gw) { } + forward_map(*(gw.Parent1::graph)), + backward_map(*(gw.Parent2::graph)) { } EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw, const _Value& value) : - ParentMap1(gw, value), ParentMap2(gw, value) { } + forward_map(*(gw.Parent1::graph), value), + backward_map(*(gw.Parent2::graph), value) { } _Value operator[](const Edge& n) const { if (!n.backward) - return ParentMap1::operator[](n); + return forward_map[n]; else - return ParentMap2::operator[](n); + return backward_map[n]; } void set(const Edge& n, const _Value& value) { if (!n.backward) - ParentMap1::set(n, value); + forward_map.set(n, value); else - ParentMap2::set(n, value); + backward_map.set(n, value); } // using ParentMap1::operator[]; // using ParentMap2::operator[]; @@ -412,6 +522,189 @@ }; + /*! A graph wrapper base class + for merging the node-sets and edge-sets of + two node-disjoint graphs + into one graph. + Specialization for the case when _Graph1::Edge and _Graph2::Edge + are the same. + */ + template + class MergeEdgeGraphWrapperBase< + _Graph1, _Graph2, typename boost::enable_if< + boost::is_same >::type> : + public MergeNodeGraphWrapperBase<_Graph1, _Graph2> { + public: + static void printEdge() { std::cout << "edge: same" << std::endl; } + typedef _Graph1 Graph1; + typedef _Graph2 Graph2; + typedef MergeNodeGraphWrapperBase<_Graph1, _Graph2> Parent; + typedef typename Parent::Parent1 Parent1; + typedef typename Parent::Parent2 Parent2; +// typedef P1<_Graph1> Parent1; +// typedef P2<_Graph2> Parent2; + typedef typename Parent1::Edge Graph1Edge; + typedef typename Parent2::Edge Graph2Edge; + protected: + MergeEdgeGraphWrapperBase() { } + public: + template class EdgeMap; + + typedef typename Parent::Node Node; + + class Edge : public Graph1Edge { + friend class MergeEdgeGraphWrapperBase<_Graph1, _Graph2>; + template friend class EdgeMap; + protected: + bool backward; //true, iff backward + public: + Edge() { } + /// \todo =false is needed, or causes problems? + /// If \c _backward is false, then we get an edge corresponding to the + /// original one, otherwise its oppositely directed pair is obtained. + Edge(const Graph1Edge& n1, + const Graph2Edge& n2, bool _backward) : + Graph1Edge(!backward ? n1 : n2), backward(_backward) { } + Edge(Invalid i) : Graph1Edge(i), backward(true) { } + bool operator==(const Edge& v) const { + return (backward==v.backward && + static_cast(*this)==static_cast(v)); + } + bool operator!=(const Edge& v) const { + return !(*this==v); + } + }; + + using Parent::first; + void first(Edge& i) const { + Parent1::graph->first(*static_cast(&i)); + i.backward=false; + if (*static_cast(&i)==INVALID) { + Parent2::graph->first(*static_cast(&i)); + i.backward=true; + } + } + void firstIn(Edge& i, const Node& n) const { + Parent1::graph->firstIn(*static_cast(&i), n); + i.backward=false; + if (*static_cast(&i)==INVALID) { + Parent2::graph->firstIn(*static_cast(&i), n); + i.backward=true; + } + } + void firstOut(Edge& i, const Node& n) const { + Parent1::graph->firstOut(*static_cast(&i), n); + i.backward=false; + if (*static_cast(&i)==INVALID) { + Parent2::graph->firstOut(*static_cast(&i), n); + i.backward=true; + } + } + + using Parent::next; + void next(Edge& i) const { + if (!(i.backward)) { + Parent1::graph->next(*static_cast(&i)); + if (*static_cast(&i)==INVALID) { + Parent2::graph->first(*static_cast(&i)); + i.backward=true; + } + } else { + Parent2::graph->next(*static_cast(&i)); + } + } + void nextIn(Edge& i) const { + if (!(i.backward)) { + Parent1::graph->nextIn(*static_cast(&i)); + if (*static_cast(&i)==INVALID) { + Parent2::graph->first(*static_cast(&i)); + i.backward=true; + } + } else { + Parent2::graph->nextIn(*static_cast(&i)); + } + } + void nextOut(Edge& i) const { + if (!(i.backward)) { + Parent1::graph->nextOut(*static_cast(&i)); + if (*static_cast(&i)==INVALID) { + Parent2::graph->first(*static_cast(&i)); + i.backward=true; + } + } else { + Parent2::graph->nextOut(*static_cast(&i)); + } + } + + Node source(const Edge& i) const { + if (!(i.backward)) { + return + Node(Parent1::graph->source(i), INVALID, false); + } else { + return + Node(INVALID, Parent2::graph->source(i), true); + } + } + + Node target(const Edge& i) const { + if (!(i.backward)) { + return + Node(Parent1::graph->target(i), INVALID, false); + } else { + return + Node(INVALID, Parent2::graph->target(i), true); + } + } + + using Parent::id; + int id(const Edge& n) const { + if (!n.backward) + return this->Parent1::graph->id(n); + else + return this->Parent2::graph->id(n); + } + + template + class EdgeMap { + protected: + typedef typename Parent::Graph1::template EdgeMap<_Value> ParentMap1; + typedef typename Parent::Graph2::template EdgeMap<_Value> ParentMap2; + ParentMap1 forward_map; + ParentMap2 backward_map; + public: + typedef _Value Value; + typedef Edge Key; + EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw) : + forward_map(*(gw.Parent1::graph)), + backward_map(*(gw.Parent2::graph)) { } + EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw, + const _Value& value) : + forward_map(*(gw.Parent1::graph), value), + backward_map(*(gw.Parent2::graph), value) { } + _Value operator[](const Edge& n) const { + if (!n.backward) + return forward_map[n]; + else + return backward_map[n]; + } + void set(const Edge& n, const _Value& value) { + if (!n.backward) + forward_map.set(n, value); + else + backward_map.set(n, value); + } +// using ParentMap1::operator[]; +// using ParentMap2::operator[]; + }; + + }; + + + /*! A graph wrapper class + for merging the node-sets and edge-sets of + two node-disjoint graphs + into one graph. + */ template class MergeEdgeGraphWrapper : public IterableGraphExtender > { @@ -430,6 +723,11 @@ }; + /*! A graph wrapper base class for the following functionality. + If a bijection is given between the node-sets of two graphs, + then the second one can be considered as a new edge-set + over th first node-set. + */ template class NewEdgeSetGraphWrapperBase : public GraphWrapperBase<_Graph> { public: @@ -507,7 +805,7 @@ bool forward(const Edge& e) const { return edge_set_graph->forward(e); } bool backward(const Edge& e) const { return edge_set_graph->backward(e); } - using Parent::id; + int id(const Node& e) const { return Parent::id(e); } int id(const Edge& e) const { return edge_set_graph->id(e); } Edge opposite(const Edge& e) const { return edge_set_graph->opposite(e); } @@ -526,6 +824,12 @@ }; + + /*! A graph wrapper class for the following functionality. + If a bijection is given between the node-sets of two graphs, + then the second one can be considered as a new edge-set + over th first node-set. + */ template class NewEdgeSetGraphWrapper : public IterableGraphExtender< @@ -551,6 +855,212 @@ } }; + + /*! A graph wrapper base class + for merging graphs of type _Graph1 and _Graph2 + which are given on the same node-set + (specially on the node-set of Graph1) + into one graph. + In an other point of view, _Graph1 is extended with + the edge-set of _Graph2. + */ + template + class AugmentingGraphWrapperBase : + public P1<_Graph1> { + public: + void printAugment() const { std::cout << "generic" << std::endl; } + typedef _Graph1 Graph1; + typedef _Graph2 Graph2; + typedef P1<_Graph1> Parent1; + typedef P2<_Graph2> Parent2; + typedef typename Parent1::Edge Graph1Edge; + typedef typename Parent2::Edge Graph2Edge; + protected: + AugmentingGraphWrapperBase() { } + _Graph2* graph2; + void setGraph2(_Graph2& _graph2) { graph2=&_graph2; } + public: + + template class EdgeMap; + + typedef typename Parent1::Node Node; + + class Edge : public Graph1Edge, public Graph2Edge { + friend class AugmentingGraphWrapperBase<_Graph1, _Graph2>; + template friend class EdgeMap; + protected: + bool backward; //true, iff backward + public: + Edge() { } + /// \todo =false is needed, or causes problems? + /// If \c _backward is false, then we get an edge corresponding to the + /// original one, otherwise its oppositely directed pair is obtained. + Edge(const Graph1Edge& n1, + const Graph2Edge& n2, bool _backward) : + Graph1Edge(n1), Graph2Edge(n2), backward(_backward) { } + Edge(Invalid i) : Graph1Edge(i), Graph2Edge(i), backward(true) { } + bool operator==(const Edge& v) const { + if (backward) + return (v.backward && + static_cast(*this)==static_cast(v)); + else + return (!v.backward && + static_cast(*this)==static_cast(v)); + } + bool operator!=(const Edge& v) const { + return !(*this==v); + } + }; + + using Parent1::first; + void first(Edge& i) const { + Parent1::graph->first(*static_cast(&i)); + i.backward=false; + if (*static_cast(&i)==INVALID) { + graph2->first(*static_cast(&i)); + i.backward=true; + } + } + void firstIn(Edge& i, const Node& n) const { + Parent1::graph->firstIn(*static_cast(&i), n); + i.backward=false; + if (*static_cast(&i)==INVALID) { + graph2->firstIn(*static_cast(&i), n); + i.backward=true; + } + } + void firstOut(Edge& i, const Node& n) const { + Parent1::graph->firstOut(*static_cast(&i), n); + i.backward=false; + if (*static_cast(&i)==INVALID) { + graph2->firstOut(*static_cast(&i), n); + i.backward=true; + } + } + + using Parent1::next; + void next(Edge& i) const { + if (!(i.backward)) { + Parent1::graph->next(*static_cast(&i)); + if (*static_cast(&i)==INVALID) { + graph2->first(*static_cast(&i)); + i.backward=true; + } + } else { + graph2->next(*static_cast(&i)); + } + } + void nextIn(Edge& i) const { + if (!(i.backward)) { + Parent1::graph->nextIn(*static_cast(&i)); + if (*static_cast(&i)==INVALID) { + graph2->first(*static_cast(&i)); + i.backward=true; + } + } else { + graph2->nextIn(*static_cast(&i)); + } + } + void nextOut(Edge& i) const { + if (!(i.backward)) { + Parent1::graph->nextOut(*static_cast(&i)); + if (*static_cast(&i)==INVALID) { + graph2->first(*static_cast(&i)); + i.backward=true; + } + } else { + graph2->nextOut(*static_cast(&i)); + } + } + + Node source(const Edge& i) const { + if (!(i.backward)) { + return Parent1::graph->source(i); + } else { + return graph2->source(i); + } + } + + Node target(const Edge& i) const { + if (!(i.backward)) { + return Parent1::graph->target(i); + } else { + return graph2->target(i); + } + } + + int id(const Node& n) const { + return Parent1::id(n); + }; + int id(const Edge& n) const { + if (!n.backward) + return this->Parent1::graph->id(n); + else + return this->graph2->id(n); + } + + template + class EdgeMap { + protected: + typedef typename _Graph1::template EdgeMap<_Value> ParentMap1; + typedef typename _Graph2::template EdgeMap<_Value> ParentMap2; + ParentMap1 forward_map; + ParentMap2 backward_map; + public: + typedef _Value Value; + typedef Edge Key; + EdgeMap(const AugmentingGraphWrapperBase<_Graph1, _Graph2>& gw) : + forward_map(*(gw.Parent1::graph)), + backward_map(*(gw.graph2)) { } + EdgeMap(const AugmentingGraphWrapperBase<_Graph1, _Graph2>& gw, + const _Value& value) : + forward_map(*(gw.Parent1::graph), value), + backward_map(*(gw.graph2), value) { } + _Value operator[](const Edge& n) const { + if (!n.backward) + return forward_map[n]; + else + return backward_map[n]; + } + void set(const Edge& n, const _Value& value) { + if (!n.backward) + forward_map.set(n, value); + else + backward_map.set(n, value); + } +// using ParentMap1::operator[]; +// using ParentMap2::operator[]; + }; + + }; + + + /*! A graph wrapper class + for merging two graphs (of type _Graph1 and _Graph2) + with the same node-set + (specially on the node-set of Graph1) + into one graph. + In an other point of view, _Graph1 is extended with + the edge-set of _Graph2. + */ + template + class AugmentingGraphWrapper : public + IterableGraphExtender > { + public: + typedef + IterableGraphExtender > + Parent; + typedef _Graph1 Graph1; + typedef _Graph2 Graph2; + protected: + AugmentingGraphWrapper() { } + public: + AugmentingGraphWrapper(_Graph1& _graph1, _Graph2& _graph2) { + setGraph(_graph1); + setGraph2(_graph2); + } + }; + } //namespace lemon #endif //LEMON_MERGE_NODE_GRAPH_WRAPPER_H diff -r 2bfbe3f4307c -r b3bdd856faf4 src/work/marci/merge_node_graph_wrapper_test.cc --- a/src/work/marci/merge_node_graph_wrapper_test.cc Sat Nov 20 11:10:56 2004 +0000 +++ b/src/work/marci/merge_node_graph_wrapper_test.cc Sat Nov 20 14:09:27 2004 +0000 @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -21,165 +22,141 @@ class Edge { }; }; -int main() { - typedef SmartGraph Graph1; - typedef ListGraph Graph2; - - { - checkConcept >(); - } - { - checkConcept >(); - } - - Graph1 g; - Graph2 h; - typedef MergeEdgeGraphWrapper GW; - GW gw(g, h); - - std::ifstream f1("graph1.dim"); - std::ifstream f2("graph2.dim"); - readDimacs(f1, g); - readDimacs(f2, h); - { - -// Graph1::Node n1=g.addNode(); -// Graph1::Node n2=g.addNode(); -// Graph1::Node n3=g.addNode(); -// Graph2::Node n4=h.addNode(); -// Graph2::Node n5=h.addNode(); -// Graph2::Node n6=h.addNode(); -// Graph1::Edge e1=g.addEdge(n1, n2); -// Graph1::Edge e2=g.addEdge(n1, n3); -// Graph2::Edge e3=h.addEdge(n4, n5); -// Graph2::Edge e4=h.addEdge(n4, n5); - //GW::NodeIt n(gw) - cout << "1st graph" << endl; +template +void printGraph(const Graph& g) { cout << " nodes:" << endl; - for (Graph1::NodeIt n(g); n!=INVALID; ++n) { + for (typename Graph::NodeIt n(g); n!=INVALID; ++n) { cout << " " << g.id(n) << endl; } cout << " edges:" << endl; - for (Graph1::EdgeIt n(g); n!=INVALID; ++n) { + for (typename Graph::EdgeIt n(g); n!=INVALID; ++n) { cout << " " << g.id(n) << ": " << g.id(g.source(n)) << "->" << g.id(g.target(n)) << endl; - } - cout << "2nd graph" << endl; - cout << " nodes:" << endl; - for (Graph2::NodeIt n(h); n!=INVALID; ++n) { - cout << " " << h.id(n) << endl; - } - cout << " edges:" << endl; - for (Graph2::EdgeIt n(h); n!=INVALID; ++n) { - cout << " " << h.id(n) << ": " - << h.id(h.source(n)) << "->" << h.id(h.target(n)) << endl; - } - cout << "merged graph" << endl; - cout << " nodes:" << endl; - for (GW::NodeIt n(gw); n!=INVALID; ++n) { - cout << " "<< gw.id(n) << endl; - } - cout << " edges:" << endl; - for (GW::EdgeIt n(gw); n!=INVALID; ++n) { - cout << " " << gw.id(n) << ": " - << gw.id(gw.source(n)) << "->" << gw.id(gw.target(n)) << endl; + } +} + +int main() { + { + cout << "FIRST TEST" << endl; + typedef SmartGraph Graph1; + typedef ListGraph Graph2; + + { + checkConcept >(); + MergeEdgeGraphWrapper::printNode(); + MergeEdgeGraphWrapper::printEdge(); + checkConcept >(); + MergeEdgeGraphWrapper::printNode(); + MergeEdgeGraphWrapper::printEdge(); + } + + Graph1 g1; + Graph2 g2; + typedef MergeEdgeGraphWrapper GW; + GW gw(g1, g2); + + std::ifstream f1("graph1.dim"); + std::ifstream f2("graph2.dim"); + readDimacs(f1, g1); + readDimacs(f2, g2); + + cout << "1st graph" << endl; + printGraph(g1); + + cout << "2nd graph" << endl; + printGraph(g2); + + cout << "merged graph" << endl; + printGraph(gw); + } - GW::NodeMap nm(gw); - int i=0; - for (GW::NodeIt n(gw); n!=INVALID; ++n) { - ++i; - nm.set(n, i); - } - for (Graph1::NodeIt n(g); n!=INVALID; ++n) { - cout << nm[GW::Node(n,INVALID,false)] << endl; - } - for (Graph2::NodeIt n(h); n!=INVALID; ++n) { - cout << nm[GW::Node(INVALID,n,true)] << endl; + + { + cout << "SECOND TEST" << endl; + typedef SmartGraph Graph1; + { + checkConcept(); + } + + Graph1 g1; + + FullGraph pre_g2(2); + ConstMap const_false_map(false); + typedef EdgeSubGraphWrapper > + Graph2; + { + checkConcept(); + } + + Graph2 g2(pre_g2, const_false_map); + + typedef MergeEdgeGraphWrapper GW; + { + checkConcept(); + } + GW gw(g1, g2); + GW::Node sw; + GW::Node tw; + { + Graph2::NodeIt k(g2); + sw=GW::Node(INVALID, k, true); + ++k; + tw=GW::Node(INVALID, k, true); + } + + std::ifstream f1("graph2.dim"); + readDimacs(f1, g1); + + cout << "1st graph" << endl; + printGraph(g1); + + cout << "2nd graph" << endl; + printGraph(g2); + + cout << "merged graph" << endl; + printGraph(gw); + + typedef ListGraph Graph3; + Graph3 g3; + GW::NodeMap gwn(gw); + Graph3::NodeMap g3n(g3); + for (GW::NodeIt n(gw); n!=INVALID; ++n) { + Graph3::Node m=g3.addNode(); + gwn.set(n, m); + g3n.set(m, n); + } + + typedef NewEdgeSetGraphWrapper GWW; + { + checkConcept(); + } + + GWW gww(gw, g3, gwn, g3n); + + for (Graph1::NodeIt n(g1); n!=INVALID; ++n) { + g3.addEdge(gwn[sw], gwn[GW::Node(n,INVALID,false)]); + } + +// for (Graph1::NodeIt n(g1); n!=INVALID; ++n) { +// gww.addEdge(sw, GW::Node(n,INVALID,false)); +// } + + cout << "new edges" << endl; + printGraph(g3); + + cout << "new edges in the new graph" << endl; + printGraph(gww); + + typedef AugmentingGraphWrapper GWWW; + { + checkConcept(); + } + GWWW gwww(gw, gww); + + cout << "new edges merged into the original graph" << endl; + printGraph(gwww); + } - gw.printNode(); - - { -// typedef SmartGraph Graph1; - typedef ListGraph Graph1; - typedef ListGraph Graph2; - Graph1 g; - Graph2 h; - typedef MergeNodeGraphWrapper GW; - GW gw(g, h); - gw.printNode(); - } - { -// typedef SmartGraph Graph1; - typedef Graph3 Graph1; - typedef ListGraph Graph2; - Graph1 g; - Graph2 h; - typedef MergeNodeGraphWrapper GW; - GW gw(g, h); - gw.printNode(); - } - { -// typedef SmartGraph Graph1; - typedef ListGraph Graph1; - typedef Graph3 Graph2; - Graph1 g; - Graph2 h; - typedef MergeNodeGraphWrapper GW; - GW gw(g, h); - gw.printNode(); - } - } - { - Graph1 g; - Graph2 h; - typedef Graph1::Node Node1; - typedef Graph2::Node Node2; - typedef NewEdgeSetGraphWrapper GW; - Graph1::NodeMap e_node(g); - Graph2::NodeMap n_node(h); - GW gw(g, h, e_node, n_node); - for (int i=0; i<4; ++i) { - Node1 n=g.addNode(); - e_node.set(n, INVALID); - } - for (int i=0; i<4; ++i) { - Graph1::Node n1=g.addNode(); - Graph2::Node n2=h.addNode(); - e_node.set(n1, n2); - n_node.set(n2, n1); - } - for (Graph2::NodeIt n(h); n!=INVALID; ++n) - for (Graph2::NodeIt m(h); m!=INVALID; ++m) - if ((h.id(n)+h.id(m))%3==0) h.addEdge(n, m); -// Graph1::NodeIt n(g); -// Node1 n1=n; -// Node1 n2=++n; -// Node1 n3=++n; -// Node1 n4=n; -// gw.addEdge(n1, n2); -// gw.addEdge(n1, n2); -// for (EdgeIt(e)) -// Graph1::Node n1=g.addNode(); -// Graph1::Node n2=g.addNode(); -// Graph1::Node n3=g.addNode(); -// Graph2::Node n4=h.addNode(); -// Graph2::Node n5=h.addNode(); - for (GW::EdgeIt e(gw); e!=INVALID; ++e) - cout << gw.id(e) << endl; - for (GW::NodeIt n(gw); n!=INVALID; ++n) { - if (e_node[n]==INVALID) { - cout<