[Lemon-commits] [lemon_svn] marci: r1403 - in hugo/trunk/src: lemon work/marci
Lemon SVN
svn at lemon.cs.elte.hu
Mon Nov 6 20:45:09 CET 2006
Author: marci
Date: Sat Nov 20 15:09:27 2004
New Revision: 1403
Modified:
hugo/trunk/src/lemon/graph_wrapper.h
hugo/trunk/src/work/marci/merge_node_graph_wrapper.h
hugo/trunk/src/work/marci/merge_node_graph_wrapper_test.cc
Log:
MergeGraphWrapper
Modified: hugo/trunk/src/lemon/graph_wrapper.h
==============================================================================
--- hugo/trunk/src/lemon/graph_wrapper.h (original)
+++ hugo/trunk/src/lemon/graph_wrapper.h Sat Nov 20 15:09:27 2004
@@ -1175,17 +1175,6 @@
EdgeMap(const SubBidirGraphWrapperBase<_Graph,
ForwardFilterMap, BackwardFilterMap>& g, T a) :
forward_map(*(g.graph), a), backward_map(*(g.graph), a) { }
-
-// template <typename TT>
-// EdgeMap(const EdgeMap<TT>& copy)
-// : forward_map(copy.forward_map), backward_map(copy.backward_map) {}
-
-// template <typename TT>
-// EdgeMap& operator=(const EdgeMap<TT>& copy) {
-// forward_map = copy.forward_map;
-// backward_map = copy.backward_map;
-// return *this;
-// }
void set(Edge e, T a) {
if (!e.backward)
Modified: hugo/trunk/src/work/marci/merge_node_graph_wrapper.h
==============================================================================
--- hugo/trunk/src/work/marci/merge_node_graph_wrapper.h (original)
+++ hugo/trunk/src/work/marci/merge_node_graph_wrapper.h Sat Nov 20 15:09:27 2004
@@ -22,6 +22,7 @@
#include <lemon/map_defines.h>
#include <lemon/graph_wrapper.h>
#include <iostream>
+
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 <typename _Graph1, typename _Graph2, typename Enable=void>
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 <typename Value> friend class NodeMap;
+ template <typename _Value> 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<Graph1Node>(*this)==
- static_cast<Graph1Node>(v) &&
- static_cast<Graph2Node>(*this)==
- static_cast<Graph2Node>(v));
+ if (backward)
+ return (v.backward &&
+ static_cast<Graph2Node>(*this)==static_cast<Graph2Node>(v));
+ else
+ return (!v.backward &&
+ static_cast<Graph1Node>(*this)==static_cast<Graph1Node>(v));
}
bool operator!=(const Node& v) const {
- return (this->backward!=v.backward ||
- static_cast<Graph1Node>(*this)!=
- static_cast<Graph1Node>(v) ||
- static_cast<Graph2Node>(*this)!=
- static_cast<Graph2Node>(v));
+ return !(*this==v);
}
};
@@ -118,29 +119,33 @@
}
template <typename _Value>
- 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 <typename _Graph1, typename _Graph2>
class MergeNodeGraphWrapperBase<
_Graph1, _Graph2, typename boost::enable_if<
boost::is_same<typename _Graph1::Node, typename _Graph2::Node> >::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 <typename _Value> class NodeMap;
+
+ class Node : public Graph1Node {
+ friend class MergeNodeGraphWrapperBase<_Graph1, _Graph2>;
+ template <typename _Value> 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<Graph1Node>(*this)==static_cast<Graph1Node>(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<Graph1Node*>(&i));
+ i.backward=false;
+ if (*static_cast<Graph1Node*>(&i)==INVALID) {
+ Parent2::graph->first(*static_cast<Graph1Node*>(&i));
+ i.backward=true;
+ }
+ }
+ void next(Node& i) const {
+ if (!(i.backward)) {
+ Parent1::graph->next(*static_cast<Graph1Node*>(&i));
+ if (*static_cast<Graph1Node*>(&i)==INVALID) {
+ Parent2::graph->first(*static_cast<Graph1Node*>(&i));
+ i.backward=true;
+ }
+ } else {
+ Parent2::graph->next(*static_cast<Graph1Node*>(&i));
+ }
+ }
+
+ int id(const Node& n) const {
+ if (!n.backward)
+ return this->Parent1::graph->id(n);
+ else
+ return this->Parent2::graph->id(n);
+ }
+
+ template <typename _Value>
+ 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 <typename _Graph1, typename _Graph2>
class MergeNodeGraphWrapperBase<
_Graph1, _Graph2, typename boost::enable_if<
boost::is_base_and_derived<typename _Graph1::Node, typename _Graph2::Node> >::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<typename _Graph2::Node, typename _Graph1::Node> >::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 <typename _Graph1, typename _Graph2>
class MergeNodeGraphWrapper : public
IterableGraphExtender<MergeNodeGraphWrapperBase<_Graph1, _Graph2> > {
@@ -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 <typename _Graph1, typename _Graph2, typename Enable=void>
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 <typename Value> friend class EdgeMap;
+ template <typename _Value> 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<Graph1Edge>(*this)==
- static_cast<Graph1Edge>(v) &&
- static_cast<Graph2Edge>(*this)==
- static_cast<Graph2Edge>(v));
+ if (backward)
+ return (v.backward &&
+ static_cast<Graph2Edge>(*this)==static_cast<Graph2Edge>(v));
+ else
+ return (!v.backward &&
+ static_cast<Graph1Edge>(*this)==static_cast<Graph1Edge>(v));
}
bool operator!=(const Edge& v) const {
- return (this->backward!=v.backward ||
- static_cast<Graph1Edge>(*this)!=
- static_cast<Graph1Edge>(v) ||
- static_cast<Graph2Edge>(*this)!=
- static_cast<Graph2Edge>(v));
+ return !(*this==v);
}
};
@@ -381,29 +487,33 @@
}
template <typename _Value>
- 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 <typename _Graph1, typename _Graph2>
+ class MergeEdgeGraphWrapperBase<
+ _Graph1, _Graph2, typename boost::enable_if<
+ boost::is_same<typename _Graph1::Node, typename _Graph2::Node> >::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 <typename _Value> class EdgeMap;
+
+ typedef typename Parent::Node Node;
+
+ class Edge : public Graph1Edge {
+ friend class MergeEdgeGraphWrapperBase<_Graph1, _Graph2>;
+ template <typename _Value> 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<Graph1Edge>(*this)==static_cast<Graph1Edge>(v));
+ }
+ bool operator!=(const Edge& v) const {
+ return !(*this==v);
+ }
+ };
+
+ using Parent::first;
+ void first(Edge& i) const {
+ Parent1::graph->first(*static_cast<Graph1Edge*>(&i));
+ i.backward=false;
+ if (*static_cast<Graph1Edge*>(&i)==INVALID) {
+ Parent2::graph->first(*static_cast<Graph1Edge*>(&i));
+ i.backward=true;
+ }
+ }
+ void firstIn(Edge& i, const Node& n) const {
+ Parent1::graph->firstIn(*static_cast<Graph1Edge*>(&i), n);
+ i.backward=false;
+ if (*static_cast<Graph1Edge*>(&i)==INVALID) {
+ Parent2::graph->firstIn(*static_cast<Graph1Edge*>(&i), n);
+ i.backward=true;
+ }
+ }
+ void firstOut(Edge& i, const Node& n) const {
+ Parent1::graph->firstOut(*static_cast<Graph1Edge*>(&i), n);
+ i.backward=false;
+ if (*static_cast<Graph1Edge*>(&i)==INVALID) {
+ Parent2::graph->firstOut(*static_cast<Graph1Edge*>(&i), n);
+ i.backward=true;
+ }
+ }
+
+ using Parent::next;
+ void next(Edge& i) const {
+ if (!(i.backward)) {
+ Parent1::graph->next(*static_cast<Graph1Edge*>(&i));
+ if (*static_cast<Graph1Edge*>(&i)==INVALID) {
+ Parent2::graph->first(*static_cast<Graph1Edge*>(&i));
+ i.backward=true;
+ }
+ } else {
+ Parent2::graph->next(*static_cast<Graph1Edge*>(&i));
+ }
+ }
+ void nextIn(Edge& i) const {
+ if (!(i.backward)) {
+ Parent1::graph->nextIn(*static_cast<Graph1Edge*>(&i));
+ if (*static_cast<Graph1Edge*>(&i)==INVALID) {
+ Parent2::graph->first(*static_cast<Graph1Edge*>(&i));
+ i.backward=true;
+ }
+ } else {
+ Parent2::graph->nextIn(*static_cast<Graph1Edge*>(&i));
+ }
+ }
+ void nextOut(Edge& i) const {
+ if (!(i.backward)) {
+ Parent1::graph->nextOut(*static_cast<Graph1Edge*>(&i));
+ if (*static_cast<Graph1Edge*>(&i)==INVALID) {
+ Parent2::graph->first(*static_cast<Graph1Edge*>(&i));
+ i.backward=true;
+ }
+ } else {
+ Parent2::graph->nextOut(*static_cast<Graph1Edge*>(&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 <typename _Value>
+ 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 <typename _Graph1, typename _Graph2>
class MergeEdgeGraphWrapper : public
IterableGraphExtender<MergeEdgeGraphWrapperBase<_Graph1, _Graph2> > {
@@ -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 <typename _Graph, typename _EdgeSetGraph>
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 <typename _Graph, typename _EdgeSetGraph>
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 <typename _Graph1, typename _Graph2, typename Enable=void>
+ 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 <typename _Value> class EdgeMap;
+
+ typedef typename Parent1::Node Node;
+
+ class Edge : public Graph1Edge, public Graph2Edge {
+ friend class AugmentingGraphWrapperBase<_Graph1, _Graph2>;
+ template <typename _Value> 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<Graph2Edge>(*this)==static_cast<Graph2Edge>(v));
+ else
+ return (!v.backward &&
+ static_cast<Graph1Edge>(*this)==static_cast<Graph1Edge>(v));
+ }
+ bool operator!=(const Edge& v) const {
+ return !(*this==v);
+ }
+ };
+
+ using Parent1::first;
+ void first(Edge& i) const {
+ Parent1::graph->first(*static_cast<Graph1Edge*>(&i));
+ i.backward=false;
+ if (*static_cast<Graph1Edge*>(&i)==INVALID) {
+ graph2->first(*static_cast<Graph2Edge*>(&i));
+ i.backward=true;
+ }
+ }
+ void firstIn(Edge& i, const Node& n) const {
+ Parent1::graph->firstIn(*static_cast<Graph1Edge*>(&i), n);
+ i.backward=false;
+ if (*static_cast<Graph1Edge*>(&i)==INVALID) {
+ graph2->firstIn(*static_cast<Graph2Edge*>(&i), n);
+ i.backward=true;
+ }
+ }
+ void firstOut(Edge& i, const Node& n) const {
+ Parent1::graph->firstOut(*static_cast<Graph1Edge*>(&i), n);
+ i.backward=false;
+ if (*static_cast<Graph1Edge*>(&i)==INVALID) {
+ graph2->firstOut(*static_cast<Graph2Edge*>(&i), n);
+ i.backward=true;
+ }
+ }
+
+ using Parent1::next;
+ void next(Edge& i) const {
+ if (!(i.backward)) {
+ Parent1::graph->next(*static_cast<Graph1Edge*>(&i));
+ if (*static_cast<Graph1Edge*>(&i)==INVALID) {
+ graph2->first(*static_cast<Graph2Edge*>(&i));
+ i.backward=true;
+ }
+ } else {
+ graph2->next(*static_cast<Graph2Edge*>(&i));
+ }
+ }
+ void nextIn(Edge& i) const {
+ if (!(i.backward)) {
+ Parent1::graph->nextIn(*static_cast<Graph1Edge*>(&i));
+ if (*static_cast<Graph1Edge*>(&i)==INVALID) {
+ graph2->first(*static_cast<Graph2Edge*>(&i));
+ i.backward=true;
+ }
+ } else {
+ graph2->nextIn(*static_cast<Graph2Edge*>(&i));
+ }
+ }
+ void nextOut(Edge& i) const {
+ if (!(i.backward)) {
+ Parent1::graph->nextOut(*static_cast<Graph1Edge*>(&i));
+ if (*static_cast<Graph1Edge*>(&i)==INVALID) {
+ graph2->first(*static_cast<Graph2Edge*>(&i));
+ i.backward=true;
+ }
+ } else {
+ graph2->nextOut(*static_cast<Graph2Edge*>(&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 <typename _Value>
+ 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 <typename _Graph1, typename _Graph2>
+ class AugmentingGraphWrapper : public
+ IterableGraphExtender<AugmentingGraphWrapperBase<_Graph1, _Graph2> > {
+ public:
+ typedef
+ IterableGraphExtender<AugmentingGraphWrapperBase<_Graph1, _Graph2> >
+ 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
Modified: hugo/trunk/src/work/marci/merge_node_graph_wrapper_test.cc
==============================================================================
--- hugo/trunk/src/work/marci/merge_node_graph_wrapper_test.cc (original)
+++ hugo/trunk/src/work/marci/merge_node_graph_wrapper_test.cc Sat Nov 20 15:09:27 2004
@@ -4,6 +4,7 @@
#include <lemon/list_graph.h>
#include <lemon/smart_graph.h>
#include <lemon/dimacs.h>
+#include <lemon/full_graph.h>
#include <merge_node_graph_wrapper.h>
#include<lemon/concept_check.h>
@@ -21,165 +22,141 @@
class Edge { };
};
-int main() {
- typedef SmartGraph Graph1;
- typedef ListGraph Graph2;
-
- {
- checkConcept<StaticGraph, NewEdgeSetGraphWrapper<Graph1, Graph2> >();
- }
- {
- checkConcept<StaticGraph, MergeEdgeGraphWrapper<Graph1, Graph2> >();
- }
-
- Graph1 g;
- Graph2 h;
- typedef MergeEdgeGraphWrapper<Graph1, Graph2> 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 <typename Graph>
+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;
- }
-
- GW::NodeMap<int> 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;
- }
-
- gw.printNode();
+ }
+}
+int main() {
{
-// typedef SmartGraph Graph1;
- typedef ListGraph Graph1;
- typedef ListGraph Graph2;
- Graph1 g;
- Graph2 h;
- typedef MergeNodeGraphWrapper<Graph1, Graph2> GW;
- GW gw(g, h);
- gw.printNode();
- }
- {
-// typedef SmartGraph Graph1;
- typedef Graph3 Graph1;
+ cout << "FIRST TEST" << endl;
+ typedef SmartGraph Graph1;
typedef ListGraph Graph2;
- Graph1 g;
- Graph2 h;
- typedef MergeNodeGraphWrapper<Graph1, Graph2> GW;
- GW gw(g, h);
- gw.printNode();
- }
- {
-// typedef SmartGraph Graph1;
- typedef ListGraph Graph1;
- typedef Graph3 Graph2;
- Graph1 g;
- Graph2 h;
- typedef MergeNodeGraphWrapper<Graph1, Graph2> GW;
- GW gw(g, h);
- gw.printNode();
- }
+
+ {
+ checkConcept<StaticGraph, MergeEdgeGraphWrapper<Graph1, Graph2> >();
+ MergeEdgeGraphWrapper<Graph1, Graph2>::printNode();
+ MergeEdgeGraphWrapper<Graph1, Graph2>::printEdge();
+ checkConcept<StaticGraph, MergeEdgeGraphWrapper<Graph1, Graph1> >();
+ MergeEdgeGraphWrapper<Graph1, Graph1>::printNode();
+ MergeEdgeGraphWrapper<Graph1, Graph1>::printEdge();
+ }
+
+ Graph1 g1;
+ Graph2 g2;
+ typedef MergeEdgeGraphWrapper<Graph1, Graph2> 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);
+
}
+
+
{
- Graph1 g;
- Graph2 h;
- typedef Graph1::Node Node1;
- typedef Graph2::Node Node2;
- typedef NewEdgeSetGraphWrapper<Graph1, Graph2> GW;
- Graph1::NodeMap<Graph2::Node> e_node(g);
- Graph2::NodeMap<Graph1::Node> 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;
+ cout << "SECOND TEST" << endl;
+ typedef SmartGraph Graph1;
+ {
+ checkConcept<StaticGraph, Graph1>();
+ }
+
+ Graph1 g1;
+
+ FullGraph pre_g2(2);
+ ConstMap<FullGraph::Edge, bool> const_false_map(false);
+ typedef EdgeSubGraphWrapper<FullGraph, ConstMap<FullGraph::Edge, bool> >
+ Graph2;
+ {
+ checkConcept<StaticGraph, Graph2>();
+ }
+
+ Graph2 g2(pre_g2, const_false_map);
+
+ typedef MergeEdgeGraphWrapper<Graph1, Graph2> GW;
+ {
+ checkConcept<StaticGraph, GW>();
+ }
+ 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<Graph3::Node> gwn(gw);
+ Graph3::NodeMap<GW::Node> g3n(g3);
for (GW::NodeIt n(gw); n!=INVALID; ++n) {
- if (e_node[n]==INVALID) {
- cout<<gw.id(n)<<" INVALID"<<endl;
- } else {
- cout <<gw.id(n)<<" "<<h.id(e_node[n])<<" out_edges: ";
- // cout << &e_node << endl;
- //cout << &n_node << endl;
- for (GW::OutEdgeIt e(gw, n); e!=INVALID; ++e) {
- cout<<gw.id(e)<<" ";
- }
- cout<< endl;
- }
+ Graph3::Node m=g3.addNode();
+ gwn.set(n, m);
+ g3n.set(m, n);
+ }
+
+ typedef NewEdgeSetGraphWrapper<GW, Graph3> GWW;
+ {
+ checkConcept<StaticGraph, GWW>();
}
+
+ 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<GW, GWW> GWWW;
+ {
+ checkConcept<StaticGraph, GWWW>();
+ }
+ GWWW gwww(gw, gww);
+
+ cout << "new edges merged into the original graph" << endl;
+ printGraph(gwww);
+
}
+
}
More information about the Lemon-commits
mailing list