1.1 --- a/src/lemon/graph_wrapper.h Sat Nov 20 11:10:56 2004 +0000
1.2 +++ b/src/lemon/graph_wrapper.h Sat Nov 20 14:09:27 2004 +0000
1.3 @@ -1175,17 +1175,6 @@
1.4 EdgeMap(const SubBidirGraphWrapperBase<_Graph,
1.5 ForwardFilterMap, BackwardFilterMap>& g, T a) :
1.6 forward_map(*(g.graph), a), backward_map(*(g.graph), a) { }
1.7 -
1.8 -// template <typename TT>
1.9 -// EdgeMap(const EdgeMap<TT>& copy)
1.10 -// : forward_map(copy.forward_map), backward_map(copy.backward_map) {}
1.11 -
1.12 -// template <typename TT>
1.13 -// EdgeMap& operator=(const EdgeMap<TT>& copy) {
1.14 -// forward_map = copy.forward_map;
1.15 -// backward_map = copy.backward_map;
1.16 -// return *this;
1.17 -// }
1.18
1.19 void set(Edge e, T a) {
1.20 if (!e.backward)
2.1 --- a/src/work/marci/merge_node_graph_wrapper.h Sat Nov 20 11:10:56 2004 +0000
2.2 +++ b/src/work/marci/merge_node_graph_wrapper.h Sat Nov 20 14:09:27 2004 +0000
2.3 @@ -22,6 +22,7 @@
2.4 #include <lemon/map_defines.h>
2.5 #include <lemon/graph_wrapper.h>
2.6 #include <iostream>
2.7 +
2.8 using std::cout;
2.9 using std::endl;
2.10
2.11 @@ -38,14 +39,17 @@
2.12 class P2 : public GraphWrapperBase<_Graph2> {
2.13 };
2.14
2.15 - /*! A base class for merging the node-set of two node-disjoint graphs
2.16 - into the node-set of one graph.
2.17 +
2.18 + /*! A graph wrapper base class
2.19 + for merging the node-set of two node-disjoint graphs
2.20 + into the node-set of one graph.
2.21 + Generic implementation for unrelated _Graph1::Node and _Graph2::Node.
2.22 */
2.23 template <typename _Graph1, typename _Graph2, typename Enable=void>
2.24 class MergeNodeGraphWrapperBase :
2.25 public P1<_Graph1>, public P2<_Graph2> {
2.26 public:
2.27 - void printNode() const { std::cout << "generic" << std::endl; }
2.28 + static void printNode() { std::cout << "node: generic" << std::endl; }
2.29 typedef _Graph1 Graph1;
2.30 typedef _Graph2 Graph2;
2.31 typedef P1<_Graph1> Parent1;
2.32 @@ -59,7 +63,7 @@
2.33
2.34 class Node : public Graph1Node, public Graph2Node {
2.35 friend class MergeNodeGraphWrapperBase<_Graph1, _Graph2>;
2.36 - template <typename Value> friend class NodeMap;
2.37 + template <typename _Value> friend class NodeMap;
2.38 protected:
2.39 bool backward; //true, iff backward
2.40 public:
2.41 @@ -72,18 +76,15 @@
2.42 Graph1Node(n1), Graph2Node(n2), backward(_backward) { }
2.43 Node(Invalid i) : Graph1Node(i), Graph2Node(i), backward(true) { }
2.44 bool operator==(const Node& v) const {
2.45 - return (this->backward==v.backward &&
2.46 - static_cast<Graph1Node>(*this)==
2.47 - static_cast<Graph1Node>(v) &&
2.48 - static_cast<Graph2Node>(*this)==
2.49 - static_cast<Graph2Node>(v));
2.50 + if (backward)
2.51 + return (v.backward &&
2.52 + static_cast<Graph2Node>(*this)==static_cast<Graph2Node>(v));
2.53 + else
2.54 + return (!v.backward &&
2.55 + static_cast<Graph1Node>(*this)==static_cast<Graph1Node>(v));
2.56 }
2.57 bool operator!=(const Node& v) const {
2.58 - return (this->backward!=v.backward ||
2.59 - static_cast<Graph1Node>(*this)!=
2.60 - static_cast<Graph1Node>(v) ||
2.61 - static_cast<Graph2Node>(*this)!=
2.62 - static_cast<Graph2Node>(v));
2.63 + return !(*this==v);
2.64 }
2.65 };
2.66
2.67 @@ -118,29 +119,33 @@
2.68 }
2.69
2.70 template <typename _Value>
2.71 - class NodeMap : public Parent1::template NodeMap<_Value>,
2.72 - public Parent2::template NodeMap<_Value> {
2.73 - typedef typename Parent1::template NodeMap<_Value> ParentMap1;
2.74 - typedef typename Parent2::template NodeMap<_Value> ParentMap2;
2.75 + class NodeMap {
2.76 + protected:
2.77 + typedef typename _Graph1::template NodeMap<_Value> ParentMap1;
2.78 + typedef typename _Graph2::template NodeMap<_Value> ParentMap2;
2.79 + ParentMap1 forward_map;
2.80 + ParentMap2 backward_map;
2.81 public:
2.82 typedef _Value Value;
2.83 typedef Node Key;
2.84 NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw) :
2.85 - ParentMap1(gw), ParentMap2(gw) { }
2.86 + forward_map(*(gw.Parent1::graph)),
2.87 + backward_map(*(gw.Parent2::graph)) { }
2.88 NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw,
2.89 const _Value& value) :
2.90 - ParentMap1(gw, value), ParentMap2(gw, value) { }
2.91 + forward_map(*(gw.Parent1::graph), value),
2.92 + backward_map(*(gw.Parent2::graph), value) { }
2.93 _Value operator[](const Node& n) const {
2.94 if (!n.backward)
2.95 - return ParentMap1::operator[](n);
2.96 + return forward_map[n];
2.97 else
2.98 - return ParentMap2::operator[](n);
2.99 + return backward_map[n];
2.100 }
2.101 void set(const Node& n, const _Value& value) {
2.102 if (!n.backward)
2.103 - ParentMap1::set(n, value);
2.104 + forward_map.set(n, value);
2.105 else
2.106 - ParentMap2::set(n, value);
2.107 + backward_map.set(n, value);
2.108 }
2.109 // using ParentMap1::operator[];
2.110 // using ParentMap2::operator[];
2.111 @@ -148,14 +153,19 @@
2.112
2.113 };
2.114
2.115 - //not yet working
2.116 +
2.117 + /*! A graph wrapper base class
2.118 + for merging the node-set of two node-disjoint graphs
2.119 + into the node-set of one graph.
2.120 + Specialization for the case when _Graph1::Node are the same _Graph2::Node.
2.121 + */
2.122 template <typename _Graph1, typename _Graph2>
2.123 class MergeNodeGraphWrapperBase<
2.124 _Graph1, _Graph2, typename boost::enable_if<
2.125 boost::is_same<typename _Graph1::Node, typename _Graph2::Node> >::type> :
2.126 public P1<_Graph1>, public P2<_Graph2> {
2.127 - public :
2.128 - void printNode() const { std::cout << "same" << std::endl; }
2.129 + public:
2.130 + static void printNode() { std::cout << "node: same" << std::endl; }
2.131 typedef _Graph1 Graph1;
2.132 typedef _Graph2 Graph2;
2.133 typedef P1<_Graph1> Parent1;
2.134 @@ -165,20 +175,111 @@
2.135 protected:
2.136 MergeNodeGraphWrapperBase() { }
2.137 public:
2.138 - class Node { };
2.139 + template <typename _Value> class NodeMap;
2.140 +
2.141 + class Node : public Graph1Node {
2.142 + friend class MergeNodeGraphWrapperBase<_Graph1, _Graph2>;
2.143 + template <typename _Value> friend class NodeMap;
2.144 + protected:
2.145 + bool backward; //true, iff backward
2.146 + public:
2.147 + Node() { }
2.148 + /// \todo =false is needed, or causes problems?
2.149 + /// If \c _backward is false, then we get an edge corresponding to the
2.150 + /// original one, otherwise its oppositely directed pair is obtained.
2.151 + Node(const Graph1Node& n1,
2.152 + const Graph2Node& n2, bool _backward) :
2.153 + Graph1Node(!backward ? n1 : n2), backward(_backward) { }
2.154 + Node(Invalid i) : Graph1Node(i), backward(true) { }
2.155 + bool operator==(const Node& v) const {
2.156 + return (backward==v.backward &&
2.157 + static_cast<Graph1Node>(*this)==static_cast<Graph1Node>(v));
2.158 + }
2.159 + bool operator!=(const Node& v) const {
2.160 + return !(*this==v);
2.161 + }
2.162 + };
2.163 +
2.164 + //typedef void Edge;
2.165 class Edge { };
2.166 - void first() const;
2.167 - void next() const;
2.168 +
2.169 + void first(Node& i) const {
2.170 + Parent1::graph->first(*static_cast<Graph1Node*>(&i));
2.171 + i.backward=false;
2.172 + if (*static_cast<Graph1Node*>(&i)==INVALID) {
2.173 + Parent2::graph->first(*static_cast<Graph1Node*>(&i));
2.174 + i.backward=true;
2.175 + }
2.176 + }
2.177 + void next(Node& i) const {
2.178 + if (!(i.backward)) {
2.179 + Parent1::graph->next(*static_cast<Graph1Node*>(&i));
2.180 + if (*static_cast<Graph1Node*>(&i)==INVALID) {
2.181 + Parent2::graph->first(*static_cast<Graph1Node*>(&i));
2.182 + i.backward=true;
2.183 + }
2.184 + } else {
2.185 + Parent2::graph->next(*static_cast<Graph1Node*>(&i));
2.186 + }
2.187 + }
2.188 +
2.189 + int id(const Node& n) const {
2.190 + if (!n.backward)
2.191 + return this->Parent1::graph->id(n);
2.192 + else
2.193 + return this->Parent2::graph->id(n);
2.194 + }
2.195 +
2.196 + template <typename _Value>
2.197 + class NodeMap {
2.198 + protected:
2.199 + typedef typename _Graph1::template NodeMap<_Value> ParentMap1;
2.200 + typedef typename _Graph2::template NodeMap<_Value> ParentMap2;
2.201 + ParentMap1 forward_map;
2.202 + ParentMap2 backward_map;
2.203 + public:
2.204 + typedef _Value Value;
2.205 + typedef Node Key;
2.206 + NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw) :
2.207 + forward_map(*(gw.Parent1::graph)),
2.208 + backward_map(*(gw.Parent2::graph)) { }
2.209 + NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw,
2.210 + const _Value& value) :
2.211 + forward_map(*(gw.Parent1::graph), value),
2.212 + backward_map(*(gw.Parent2::graph), value) { }
2.213 + _Value operator[](const Node& n) const {
2.214 + if (!n.backward)
2.215 + return forward_map[n];
2.216 + else
2.217 + return backward_map[n];
2.218 + }
2.219 + void set(const Node& n, const _Value& value) {
2.220 + if (!n.backward)
2.221 + forward_map.set(n, value);
2.222 + else
2.223 + backward_map.set(n, value);
2.224 + }
2.225 +// using ParentMap1::operator[];
2.226 +// using ParentMap2::operator[];
2.227 + };
2.228 +
2.229 };
2.230
2.231 - //not yet working
2.232 +
2.233 + /*! A graph wrapper base class
2.234 + for merging the node-set of two node-disjoint graphs
2.235 + into the node-set of one graph.
2.236 + Specialization for the case when
2.237 + _Graph1::Node are base and derived _Graph2::Node.
2.238 + NOT YET IMPLEMENTED
2.239 + */
2.240 template <typename _Graph1, typename _Graph2>
2.241 class MergeNodeGraphWrapperBase<
2.242 _Graph1, _Graph2, typename boost::enable_if<
2.243 boost::is_base_and_derived<typename _Graph1::Node, typename _Graph2::Node> >::type> :
2.244 public P1<_Graph1>, public P2<_Graph2> {
2.245 public :
2.246 - void printNode() const { std::cout << "2. nagyobb" << std::endl; }
2.247 + static void printNode() { std::cout << "node: 2nd is derived" << std::endl; }
2.248 typedef _Graph1 Graph1;
2.249 typedef _Graph2 Graph2;
2.250 typedef P1<_Graph1> Parent1;
2.251 @@ -201,7 +302,7 @@
2.252 boost::is_base_and_derived<typename _Graph2::Node, typename _Graph1::Node> >::type> :
2.253 public P1<_Graph1>, public P2<_Graph2> {
2.254 public :
2.255 - void printNode() const { std::cout << "1. nagyobb" << std::endl; }
2.256 + static void printNode() { std::cout << "node: 1st is derived" << std::endl; }
2.257 typedef _Graph1 Graph1;
2.258 typedef _Graph2 Graph2;
2.259 typedef P1<_Graph1> Parent1;
2.260 @@ -218,6 +319,12 @@
2.261 };
2.262
2.263
2.264 + /*! A graph wrapper class
2.265 + fors merging the node-set of two node-disjoint graphs
2.266 + into one node-set. It does not satisfy
2.267 + StaticGraph concept as it has no edge-set which
2.268 + works together with the node-set.
2.269 + */
2.270 template <typename _Graph1, typename _Graph2>
2.271 class MergeNodeGraphWrapper : public
2.272 IterableGraphExtender<MergeNodeGraphWrapperBase<_Graph1, _Graph2> > {
2.273 @@ -236,15 +343,17 @@
2.274 };
2.275
2.276
2.277 - /*! A base class for merging the node-sets and edge-sets of
2.278 + /*! A grah wrapper base class
2.279 + for merging the node-sets and edge-sets of
2.280 two node-disjoint graphs
2.281 into one graph.
2.282 + Generic implementation for unrelated _Graph1::Edge and _Graph2::Edge.
2.283 */
2.284 template <typename _Graph1, typename _Graph2, typename Enable=void>
2.285 class MergeEdgeGraphWrapperBase :
2.286 public MergeNodeGraphWrapperBase<_Graph1, _Graph2> {
2.287 public:
2.288 - void printEdge() const { std::cout << "generic" << std::endl; }
2.289 + static void printEdge() { std::cout << "edge: generic" << std::endl; }
2.290 typedef _Graph1 Graph1;
2.291 typedef _Graph2 Graph2;
2.292 typedef MergeNodeGraphWrapperBase<_Graph1, _Graph2> Parent;
2.293 @@ -263,7 +372,7 @@
2.294
2.295 class Edge : public Graph1Edge, public Graph2Edge {
2.296 friend class MergeEdgeGraphWrapperBase<_Graph1, _Graph2>;
2.297 - template <typename Value> friend class EdgeMap;
2.298 + template <typename _Value> friend class EdgeMap;
2.299 protected:
2.300 bool backward; //true, iff backward
2.301 public:
2.302 @@ -276,18 +385,15 @@
2.303 Graph1Edge(n1), Graph2Edge(n2), backward(_backward) { }
2.304 Edge(Invalid i) : Graph1Edge(i), Graph2Edge(i), backward(true) { }
2.305 bool operator==(const Edge& v) const {
2.306 - return (this->backward==v.backward &&
2.307 - static_cast<Graph1Edge>(*this)==
2.308 - static_cast<Graph1Edge>(v) &&
2.309 - static_cast<Graph2Edge>(*this)==
2.310 - static_cast<Graph2Edge>(v));
2.311 + if (backward)
2.312 + return (v.backward &&
2.313 + static_cast<Graph2Edge>(*this)==static_cast<Graph2Edge>(v));
2.314 + else
2.315 + return (!v.backward &&
2.316 + static_cast<Graph1Edge>(*this)==static_cast<Graph1Edge>(v));
2.317 }
2.318 bool operator!=(const Edge& v) const {
2.319 - return (this->backward!=v.backward ||
2.320 - static_cast<Graph1Edge>(*this)!=
2.321 - static_cast<Graph1Edge>(v) ||
2.322 - static_cast<Graph2Edge>(*this)!=
2.323 - static_cast<Graph2Edge>(v));
2.324 + return !(*this==v);
2.325 }
2.326 };
2.327
2.328 @@ -381,29 +487,33 @@
2.329 }
2.330
2.331 template <typename _Value>
2.332 - class EdgeMap : public Parent1::template EdgeMap<_Value>,
2.333 - public Parent2::template EdgeMap<_Value> {
2.334 - typedef typename Parent1::template EdgeMap<_Value> ParentMap1;
2.335 - typedef typename Parent2::template EdgeMap<_Value> ParentMap2;
2.336 + class EdgeMap {
2.337 + protected:
2.338 + typedef typename Parent::Graph1::template EdgeMap<_Value> ParentMap1;
2.339 + typedef typename Parent::Graph2::template EdgeMap<_Value> ParentMap2;
2.340 + ParentMap1 forward_map;
2.341 + ParentMap2 backward_map;
2.342 public:
2.343 typedef _Value Value;
2.344 typedef Edge Key;
2.345 EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw) :
2.346 - ParentMap1(gw), ParentMap2(gw) { }
2.347 + forward_map(*(gw.Parent1::graph)),
2.348 + backward_map(*(gw.Parent2::graph)) { }
2.349 EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw,
2.350 const _Value& value) :
2.351 - ParentMap1(gw, value), ParentMap2(gw, value) { }
2.352 + forward_map(*(gw.Parent1::graph), value),
2.353 + backward_map(*(gw.Parent2::graph), value) { }
2.354 _Value operator[](const Edge& n) const {
2.355 if (!n.backward)
2.356 - return ParentMap1::operator[](n);
2.357 + return forward_map[n];
2.358 else
2.359 - return ParentMap2::operator[](n);
2.360 + return backward_map[n];
2.361 }
2.362 void set(const Edge& n, const _Value& value) {
2.363 if (!n.backward)
2.364 - ParentMap1::set(n, value);
2.365 + forward_map.set(n, value);
2.366 else
2.367 - ParentMap2::set(n, value);
2.368 + backward_map.set(n, value);
2.369 }
2.370 // using ParentMap1::operator[];
2.371 // using ParentMap2::operator[];
2.372 @@ -412,6 +522,189 @@
2.373 };
2.374
2.375
2.376 + /*! A graph wrapper base class
2.377 + for merging the node-sets and edge-sets of
2.378 + two node-disjoint graphs
2.379 + into one graph.
2.380 + Specialization for the case when _Graph1::Edge and _Graph2::Edge
2.381 + are the same.
2.382 + */
2.383 + template <typename _Graph1, typename _Graph2>
2.384 + class MergeEdgeGraphWrapperBase<
2.385 + _Graph1, _Graph2, typename boost::enable_if<
2.386 + boost::is_same<typename _Graph1::Node, typename _Graph2::Node> >::type> :
2.387 + public MergeNodeGraphWrapperBase<_Graph1, _Graph2> {
2.388 + public:
2.389 + static void printEdge() { std::cout << "edge: same" << std::endl; }
2.390 + typedef _Graph1 Graph1;
2.391 + typedef _Graph2 Graph2;
2.392 + typedef MergeNodeGraphWrapperBase<_Graph1, _Graph2> Parent;
2.393 + typedef typename Parent::Parent1 Parent1;
2.394 + typedef typename Parent::Parent2 Parent2;
2.395 +// typedef P1<_Graph1> Parent1;
2.396 +// typedef P2<_Graph2> Parent2;
2.397 + typedef typename Parent1::Edge Graph1Edge;
2.398 + typedef typename Parent2::Edge Graph2Edge;
2.399 + protected:
2.400 + MergeEdgeGraphWrapperBase() { }
2.401 + public:
2.402 + template <typename _Value> class EdgeMap;
2.403 +
2.404 + typedef typename Parent::Node Node;
2.405 +
2.406 + class Edge : public Graph1Edge {
2.407 + friend class MergeEdgeGraphWrapperBase<_Graph1, _Graph2>;
2.408 + template <typename _Value> friend class EdgeMap;
2.409 + protected:
2.410 + bool backward; //true, iff backward
2.411 + public:
2.412 + Edge() { }
2.413 + /// \todo =false is needed, or causes problems?
2.414 + /// If \c _backward is false, then we get an edge corresponding to the
2.415 + /// original one, otherwise its oppositely directed pair is obtained.
2.416 + Edge(const Graph1Edge& n1,
2.417 + const Graph2Edge& n2, bool _backward) :
2.418 + Graph1Edge(!backward ? n1 : n2), backward(_backward) { }
2.419 + Edge(Invalid i) : Graph1Edge(i), backward(true) { }
2.420 + bool operator==(const Edge& v) const {
2.421 + return (backward==v.backward &&
2.422 + static_cast<Graph1Edge>(*this)==static_cast<Graph1Edge>(v));
2.423 + }
2.424 + bool operator!=(const Edge& v) const {
2.425 + return !(*this==v);
2.426 + }
2.427 + };
2.428 +
2.429 + using Parent::first;
2.430 + void first(Edge& i) const {
2.431 + Parent1::graph->first(*static_cast<Graph1Edge*>(&i));
2.432 + i.backward=false;
2.433 + if (*static_cast<Graph1Edge*>(&i)==INVALID) {
2.434 + Parent2::graph->first(*static_cast<Graph1Edge*>(&i));
2.435 + i.backward=true;
2.436 + }
2.437 + }
2.438 + void firstIn(Edge& i, const Node& n) const {
2.439 + Parent1::graph->firstIn(*static_cast<Graph1Edge*>(&i), n);
2.440 + i.backward=false;
2.441 + if (*static_cast<Graph1Edge*>(&i)==INVALID) {
2.442 + Parent2::graph->firstIn(*static_cast<Graph1Edge*>(&i), n);
2.443 + i.backward=true;
2.444 + }
2.445 + }
2.446 + void firstOut(Edge& i, const Node& n) const {
2.447 + Parent1::graph->firstOut(*static_cast<Graph1Edge*>(&i), n);
2.448 + i.backward=false;
2.449 + if (*static_cast<Graph1Edge*>(&i)==INVALID) {
2.450 + Parent2::graph->firstOut(*static_cast<Graph1Edge*>(&i), n);
2.451 + i.backward=true;
2.452 + }
2.453 + }
2.454 +
2.455 + using Parent::next;
2.456 + void next(Edge& i) const {
2.457 + if (!(i.backward)) {
2.458 + Parent1::graph->next(*static_cast<Graph1Edge*>(&i));
2.459 + if (*static_cast<Graph1Edge*>(&i)==INVALID) {
2.460 + Parent2::graph->first(*static_cast<Graph1Edge*>(&i));
2.461 + i.backward=true;
2.462 + }
2.463 + } else {
2.464 + Parent2::graph->next(*static_cast<Graph1Edge*>(&i));
2.465 + }
2.466 + }
2.467 + void nextIn(Edge& i) const {
2.468 + if (!(i.backward)) {
2.469 + Parent1::graph->nextIn(*static_cast<Graph1Edge*>(&i));
2.470 + if (*static_cast<Graph1Edge*>(&i)==INVALID) {
2.471 + Parent2::graph->first(*static_cast<Graph1Edge*>(&i));
2.472 + i.backward=true;
2.473 + }
2.474 + } else {
2.475 + Parent2::graph->nextIn(*static_cast<Graph1Edge*>(&i));
2.476 + }
2.477 + }
2.478 + void nextOut(Edge& i) const {
2.479 + if (!(i.backward)) {
2.480 + Parent1::graph->nextOut(*static_cast<Graph1Edge*>(&i));
2.481 + if (*static_cast<Graph1Edge*>(&i)==INVALID) {
2.482 + Parent2::graph->first(*static_cast<Graph1Edge*>(&i));
2.483 + i.backward=true;
2.484 + }
2.485 + } else {
2.486 + Parent2::graph->nextOut(*static_cast<Graph1Edge*>(&i));
2.487 + }
2.488 + }
2.489 +
2.490 + Node source(const Edge& i) const {
2.491 + if (!(i.backward)) {
2.492 + return
2.493 + Node(Parent1::graph->source(i), INVALID, false);
2.494 + } else {
2.495 + return
2.496 + Node(INVALID, Parent2::graph->source(i), true);
2.497 + }
2.498 + }
2.499 +
2.500 + Node target(const Edge& i) const {
2.501 + if (!(i.backward)) {
2.502 + return
2.503 + Node(Parent1::graph->target(i), INVALID, false);
2.504 + } else {
2.505 + return
2.506 + Node(INVALID, Parent2::graph->target(i), true);
2.507 + }
2.508 + }
2.509 +
2.510 + using Parent::id;
2.511 + int id(const Edge& n) const {
2.512 + if (!n.backward)
2.513 + return this->Parent1::graph->id(n);
2.514 + else
2.515 + return this->Parent2::graph->id(n);
2.516 + }
2.517 +
2.518 + template <typename _Value>
2.519 + class EdgeMap {
2.520 + protected:
2.521 + typedef typename Parent::Graph1::template EdgeMap<_Value> ParentMap1;
2.522 + typedef typename Parent::Graph2::template EdgeMap<_Value> ParentMap2;
2.523 + ParentMap1 forward_map;
2.524 + ParentMap2 backward_map;
2.525 + public:
2.526 + typedef _Value Value;
2.527 + typedef Edge Key;
2.528 + EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw) :
2.529 + forward_map(*(gw.Parent1::graph)),
2.530 + backward_map(*(gw.Parent2::graph)) { }
2.531 + EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw,
2.532 + const _Value& value) :
2.533 + forward_map(*(gw.Parent1::graph), value),
2.534 + backward_map(*(gw.Parent2::graph), value) { }
2.535 + _Value operator[](const Edge& n) const {
2.536 + if (!n.backward)
2.537 + return forward_map[n];
2.538 + else
2.539 + return backward_map[n];
2.540 + }
2.541 + void set(const Edge& n, const _Value& value) {
2.542 + if (!n.backward)
2.543 + forward_map.set(n, value);
2.544 + else
2.545 + backward_map.set(n, value);
2.546 + }
2.547 +// using ParentMap1::operator[];
2.548 +// using ParentMap2::operator[];
2.549 + };
2.550 +
2.551 + };
2.552 +
2.553 +
2.554 + /*! A graph wrapper class
2.555 + for merging the node-sets and edge-sets of
2.556 + two node-disjoint graphs
2.557 + into one graph.
2.558 + */
2.559 template <typename _Graph1, typename _Graph2>
2.560 class MergeEdgeGraphWrapper : public
2.561 IterableGraphExtender<MergeEdgeGraphWrapperBase<_Graph1, _Graph2> > {
2.562 @@ -430,6 +723,11 @@
2.563 };
2.564
2.565
2.566 + /*! A graph wrapper base class for the following functionality.
2.567 + If a bijection is given between the node-sets of two graphs,
2.568 + then the second one can be considered as a new edge-set
2.569 + over th first node-set.
2.570 + */
2.571 template <typename _Graph, typename _EdgeSetGraph>
2.572 class NewEdgeSetGraphWrapperBase : public GraphWrapperBase<_Graph> {
2.573 public:
2.574 @@ -507,7 +805,7 @@
2.575 bool forward(const Edge& e) const { return edge_set_graph->forward(e); }
2.576 bool backward(const Edge& e) const { return edge_set_graph->backward(e); }
2.577
2.578 - using Parent::id;
2.579 + int id(const Node& e) const { return Parent::id(e); }
2.580 int id(const Edge& e) const { return edge_set_graph->id(e); }
2.581
2.582 Edge opposite(const Edge& e) const { return edge_set_graph->opposite(e); }
2.583 @@ -526,6 +824,12 @@
2.584
2.585 };
2.586
2.587 +
2.588 + /*! A graph wrapper class for the following functionality.
2.589 + If a bijection is given between the node-sets of two graphs,
2.590 + then the second one can be considered as a new edge-set
2.591 + over th first node-set.
2.592 + */
2.593 template <typename _Graph, typename _EdgeSetGraph>
2.594 class NewEdgeSetGraphWrapper :
2.595 public IterableGraphExtender<
2.596 @@ -551,6 +855,212 @@
2.597 }
2.598 };
2.599
2.600 +
2.601 + /*! A graph wrapper base class
2.602 + for merging graphs of type _Graph1 and _Graph2
2.603 + which are given on the same node-set
2.604 + (specially on the node-set of Graph1)
2.605 + into one graph.
2.606 + In an other point of view, _Graph1 is extended with
2.607 + the edge-set of _Graph2.
2.608 + */
2.609 + template <typename _Graph1, typename _Graph2, typename Enable=void>
2.610 + class AugmentingGraphWrapperBase :
2.611 + public P1<_Graph1> {
2.612 + public:
2.613 + void printAugment() const { std::cout << "generic" << std::endl; }
2.614 + typedef _Graph1 Graph1;
2.615 + typedef _Graph2 Graph2;
2.616 + typedef P1<_Graph1> Parent1;
2.617 + typedef P2<_Graph2> Parent2;
2.618 + typedef typename Parent1::Edge Graph1Edge;
2.619 + typedef typename Parent2::Edge Graph2Edge;
2.620 + protected:
2.621 + AugmentingGraphWrapperBase() { }
2.622 + _Graph2* graph2;
2.623 + void setGraph2(_Graph2& _graph2) { graph2=&_graph2; }
2.624 + public:
2.625 +
2.626 + template <typename _Value> class EdgeMap;
2.627 +
2.628 + typedef typename Parent1::Node Node;
2.629 +
2.630 + class Edge : public Graph1Edge, public Graph2Edge {
2.631 + friend class AugmentingGraphWrapperBase<_Graph1, _Graph2>;
2.632 + template <typename _Value> friend class EdgeMap;
2.633 + protected:
2.634 + bool backward; //true, iff backward
2.635 + public:
2.636 + Edge() { }
2.637 + /// \todo =false is needed, or causes problems?
2.638 + /// If \c _backward is false, then we get an edge corresponding to the
2.639 + /// original one, otherwise its oppositely directed pair is obtained.
2.640 + Edge(const Graph1Edge& n1,
2.641 + const Graph2Edge& n2, bool _backward) :
2.642 + Graph1Edge(n1), Graph2Edge(n2), backward(_backward) { }
2.643 + Edge(Invalid i) : Graph1Edge(i), Graph2Edge(i), backward(true) { }
2.644 + bool operator==(const Edge& v) const {
2.645 + if (backward)
2.646 + return (v.backward &&
2.647 + static_cast<Graph2Edge>(*this)==static_cast<Graph2Edge>(v));
2.648 + else
2.649 + return (!v.backward &&
2.650 + static_cast<Graph1Edge>(*this)==static_cast<Graph1Edge>(v));
2.651 + }
2.652 + bool operator!=(const Edge& v) const {
2.653 + return !(*this==v);
2.654 + }
2.655 + };
2.656 +
2.657 + using Parent1::first;
2.658 + void first(Edge& i) const {
2.659 + Parent1::graph->first(*static_cast<Graph1Edge*>(&i));
2.660 + i.backward=false;
2.661 + if (*static_cast<Graph1Edge*>(&i)==INVALID) {
2.662 + graph2->first(*static_cast<Graph2Edge*>(&i));
2.663 + i.backward=true;
2.664 + }
2.665 + }
2.666 + void firstIn(Edge& i, const Node& n) const {
2.667 + Parent1::graph->firstIn(*static_cast<Graph1Edge*>(&i), n);
2.668 + i.backward=false;
2.669 + if (*static_cast<Graph1Edge*>(&i)==INVALID) {
2.670 + graph2->firstIn(*static_cast<Graph2Edge*>(&i), n);
2.671 + i.backward=true;
2.672 + }
2.673 + }
2.674 + void firstOut(Edge& i, const Node& n) const {
2.675 + Parent1::graph->firstOut(*static_cast<Graph1Edge*>(&i), n);
2.676 + i.backward=false;
2.677 + if (*static_cast<Graph1Edge*>(&i)==INVALID) {
2.678 + graph2->firstOut(*static_cast<Graph2Edge*>(&i), n);
2.679 + i.backward=true;
2.680 + }
2.681 + }
2.682 +
2.683 + using Parent1::next;
2.684 + void next(Edge& i) const {
2.685 + if (!(i.backward)) {
2.686 + Parent1::graph->next(*static_cast<Graph1Edge*>(&i));
2.687 + if (*static_cast<Graph1Edge*>(&i)==INVALID) {
2.688 + graph2->first(*static_cast<Graph2Edge*>(&i));
2.689 + i.backward=true;
2.690 + }
2.691 + } else {
2.692 + graph2->next(*static_cast<Graph2Edge*>(&i));
2.693 + }
2.694 + }
2.695 + void nextIn(Edge& i) const {
2.696 + if (!(i.backward)) {
2.697 + Parent1::graph->nextIn(*static_cast<Graph1Edge*>(&i));
2.698 + if (*static_cast<Graph1Edge*>(&i)==INVALID) {
2.699 + graph2->first(*static_cast<Graph2Edge*>(&i));
2.700 + i.backward=true;
2.701 + }
2.702 + } else {
2.703 + graph2->nextIn(*static_cast<Graph2Edge*>(&i));
2.704 + }
2.705 + }
2.706 + void nextOut(Edge& i) const {
2.707 + if (!(i.backward)) {
2.708 + Parent1::graph->nextOut(*static_cast<Graph1Edge*>(&i));
2.709 + if (*static_cast<Graph1Edge*>(&i)==INVALID) {
2.710 + graph2->first(*static_cast<Graph2Edge*>(&i));
2.711 + i.backward=true;
2.712 + }
2.713 + } else {
2.714 + graph2->nextOut(*static_cast<Graph2Edge*>(&i));
2.715 + }
2.716 + }
2.717 +
2.718 + Node source(const Edge& i) const {
2.719 + if (!(i.backward)) {
2.720 + return Parent1::graph->source(i);
2.721 + } else {
2.722 + return graph2->source(i);
2.723 + }
2.724 + }
2.725 +
2.726 + Node target(const Edge& i) const {
2.727 + if (!(i.backward)) {
2.728 + return Parent1::graph->target(i);
2.729 + } else {
2.730 + return graph2->target(i);
2.731 + }
2.732 + }
2.733 +
2.734 + int id(const Node& n) const {
2.735 + return Parent1::id(n);
2.736 + };
2.737 + int id(const Edge& n) const {
2.738 + if (!n.backward)
2.739 + return this->Parent1::graph->id(n);
2.740 + else
2.741 + return this->graph2->id(n);
2.742 + }
2.743 +
2.744 + template <typename _Value>
2.745 + class EdgeMap {
2.746 + protected:
2.747 + typedef typename _Graph1::template EdgeMap<_Value> ParentMap1;
2.748 + typedef typename _Graph2::template EdgeMap<_Value> ParentMap2;
2.749 + ParentMap1 forward_map;
2.750 + ParentMap2 backward_map;
2.751 + public:
2.752 + typedef _Value Value;
2.753 + typedef Edge Key;
2.754 + EdgeMap(const AugmentingGraphWrapperBase<_Graph1, _Graph2>& gw) :
2.755 + forward_map(*(gw.Parent1::graph)),
2.756 + backward_map(*(gw.graph2)) { }
2.757 + EdgeMap(const AugmentingGraphWrapperBase<_Graph1, _Graph2>& gw,
2.758 + const _Value& value) :
2.759 + forward_map(*(gw.Parent1::graph), value),
2.760 + backward_map(*(gw.graph2), value) { }
2.761 + _Value operator[](const Edge& n) const {
2.762 + if (!n.backward)
2.763 + return forward_map[n];
2.764 + else
2.765 + return backward_map[n];
2.766 + }
2.767 + void set(const Edge& n, const _Value& value) {
2.768 + if (!n.backward)
2.769 + forward_map.set(n, value);
2.770 + else
2.771 + backward_map.set(n, value);
2.772 + }
2.773 +// using ParentMap1::operator[];
2.774 +// using ParentMap2::operator[];
2.775 + };
2.776 +
2.777 + };
2.778 +
2.779 +
2.780 + /*! A graph wrapper class
2.781 + for merging two graphs (of type _Graph1 and _Graph2)
2.782 + with the same node-set
2.783 + (specially on the node-set of Graph1)
2.784 + into one graph.
2.785 + In an other point of view, _Graph1 is extended with
2.786 + the edge-set of _Graph2.
2.787 + */
2.788 + template <typename _Graph1, typename _Graph2>
2.789 + class AugmentingGraphWrapper : public
2.790 + IterableGraphExtender<AugmentingGraphWrapperBase<_Graph1, _Graph2> > {
2.791 + public:
2.792 + typedef
2.793 + IterableGraphExtender<AugmentingGraphWrapperBase<_Graph1, _Graph2> >
2.794 + Parent;
2.795 + typedef _Graph1 Graph1;
2.796 + typedef _Graph2 Graph2;
2.797 + protected:
2.798 + AugmentingGraphWrapper() { }
2.799 + public:
2.800 + AugmentingGraphWrapper(_Graph1& _graph1, _Graph2& _graph2) {
2.801 + setGraph(_graph1);
2.802 + setGraph2(_graph2);
2.803 + }
2.804 + };
2.805 +
2.806 } //namespace lemon
2.807
2.808 #endif //LEMON_MERGE_NODE_GRAPH_WRAPPER_H
3.1 --- a/src/work/marci/merge_node_graph_wrapper_test.cc Sat Nov 20 11:10:56 2004 +0000
3.2 +++ b/src/work/marci/merge_node_graph_wrapper_test.cc Sat Nov 20 14:09:27 2004 +0000
3.3 @@ -4,6 +4,7 @@
3.4 #include <lemon/list_graph.h>
3.5 #include <lemon/smart_graph.h>
3.6 #include <lemon/dimacs.h>
3.7 +#include <lemon/full_graph.h>
3.8 #include <merge_node_graph_wrapper.h>
3.9
3.10 #include<lemon/concept_check.h>
3.11 @@ -21,165 +22,141 @@
3.12 class Edge { };
3.13 };
3.14
3.15 -int main() {
3.16 - typedef SmartGraph Graph1;
3.17 - typedef ListGraph Graph2;
3.18 -
3.19 - {
3.20 - checkConcept<StaticGraph, NewEdgeSetGraphWrapper<Graph1, Graph2> >();
3.21 - }
3.22 - {
3.23 - checkConcept<StaticGraph, MergeEdgeGraphWrapper<Graph1, Graph2> >();
3.24 - }
3.25 -
3.26 - Graph1 g;
3.27 - Graph2 h;
3.28 - typedef MergeEdgeGraphWrapper<Graph1, Graph2> GW;
3.29 - GW gw(g, h);
3.30 -
3.31 - std::ifstream f1("graph1.dim");
3.32 - std::ifstream f2("graph2.dim");
3.33 - readDimacs(f1, g);
3.34 - readDimacs(f2, h);
3.35 - {
3.36 -
3.37 -// Graph1::Node n1=g.addNode();
3.38 -// Graph1::Node n2=g.addNode();
3.39 -// Graph1::Node n3=g.addNode();
3.40 -// Graph2::Node n4=h.addNode();
3.41 -// Graph2::Node n5=h.addNode();
3.42 -// Graph2::Node n6=h.addNode();
3.43 -// Graph1::Edge e1=g.addEdge(n1, n2);
3.44 -// Graph1::Edge e2=g.addEdge(n1, n3);
3.45 -// Graph2::Edge e3=h.addEdge(n4, n5);
3.46 -// Graph2::Edge e4=h.addEdge(n4, n5);
3.47 - //GW::NodeIt n(gw)
3.48 - cout << "1st graph" << endl;
3.49 +template <typename Graph>
3.50 +void printGraph(const Graph& g) {
3.51 cout << " nodes:" << endl;
3.52 - for (Graph1::NodeIt n(g); n!=INVALID; ++n) {
3.53 + for (typename Graph::NodeIt n(g); n!=INVALID; ++n) {
3.54 cout << " " << g.id(n) << endl;
3.55 }
3.56 cout << " edges:" << endl;
3.57 - for (Graph1::EdgeIt n(g); n!=INVALID; ++n) {
3.58 + for (typename Graph::EdgeIt n(g); n!=INVALID; ++n) {
3.59 cout << " " << g.id(n) << ": "
3.60 << g.id(g.source(n)) << "->" << g.id(g.target(n)) << endl;
3.61 - }
3.62 - cout << "2nd graph" << endl;
3.63 - cout << " nodes:" << endl;
3.64 - for (Graph2::NodeIt n(h); n!=INVALID; ++n) {
3.65 - cout << " " << h.id(n) << endl;
3.66 - }
3.67 - cout << " edges:" << endl;
3.68 - for (Graph2::EdgeIt n(h); n!=INVALID; ++n) {
3.69 - cout << " " << h.id(n) << ": "
3.70 - << h.id(h.source(n)) << "->" << h.id(h.target(n)) << endl;
3.71 - }
3.72 - cout << "merged graph" << endl;
3.73 - cout << " nodes:" << endl;
3.74 - for (GW::NodeIt n(gw); n!=INVALID; ++n) {
3.75 - cout << " "<< gw.id(n) << endl;
3.76 - }
3.77 - cout << " edges:" << endl;
3.78 - for (GW::EdgeIt n(gw); n!=INVALID; ++n) {
3.79 - cout << " " << gw.id(n) << ": "
3.80 - << gw.id(gw.source(n)) << "->" << gw.id(gw.target(n)) << endl;
3.81 + }
3.82 +}
3.83 +
3.84 +int main() {
3.85 + {
3.86 + cout << "FIRST TEST" << endl;
3.87 + typedef SmartGraph Graph1;
3.88 + typedef ListGraph Graph2;
3.89 +
3.90 + {
3.91 + checkConcept<StaticGraph, MergeEdgeGraphWrapper<Graph1, Graph2> >();
3.92 + MergeEdgeGraphWrapper<Graph1, Graph2>::printNode();
3.93 + MergeEdgeGraphWrapper<Graph1, Graph2>::printEdge();
3.94 + checkConcept<StaticGraph, MergeEdgeGraphWrapper<Graph1, Graph1> >();
3.95 + MergeEdgeGraphWrapper<Graph1, Graph1>::printNode();
3.96 + MergeEdgeGraphWrapper<Graph1, Graph1>::printEdge();
3.97 + }
3.98 +
3.99 + Graph1 g1;
3.100 + Graph2 g2;
3.101 + typedef MergeEdgeGraphWrapper<Graph1, Graph2> GW;
3.102 + GW gw(g1, g2);
3.103 +
3.104 + std::ifstream f1("graph1.dim");
3.105 + std::ifstream f2("graph2.dim");
3.106 + readDimacs(f1, g1);
3.107 + readDimacs(f2, g2);
3.108 +
3.109 + cout << "1st graph" << endl;
3.110 + printGraph(g1);
3.111 +
3.112 + cout << "2nd graph" << endl;
3.113 + printGraph(g2);
3.114 +
3.115 + cout << "merged graph" << endl;
3.116 + printGraph(gw);
3.117 +
3.118 }
3.119
3.120 - GW::NodeMap<int> nm(gw);
3.121 - int i=0;
3.122 - for (GW::NodeIt n(gw); n!=INVALID; ++n) {
3.123 - ++i;
3.124 - nm.set(n, i);
3.125 - }
3.126 - for (Graph1::NodeIt n(g); n!=INVALID; ++n) {
3.127 - cout << nm[GW::Node(n,INVALID,false)] << endl;
3.128 - }
3.129 - for (Graph2::NodeIt n(h); n!=INVALID; ++n) {
3.130 - cout << nm[GW::Node(INVALID,n,true)] << endl;
3.131 +
3.132 + {
3.133 + cout << "SECOND TEST" << endl;
3.134 + typedef SmartGraph Graph1;
3.135 + {
3.136 + checkConcept<StaticGraph, Graph1>();
3.137 + }
3.138 +
3.139 + Graph1 g1;
3.140 +
3.141 + FullGraph pre_g2(2);
3.142 + ConstMap<FullGraph::Edge, bool> const_false_map(false);
3.143 + typedef EdgeSubGraphWrapper<FullGraph, ConstMap<FullGraph::Edge, bool> >
3.144 + Graph2;
3.145 + {
3.146 + checkConcept<StaticGraph, Graph2>();
3.147 + }
3.148 +
3.149 + Graph2 g2(pre_g2, const_false_map);
3.150 +
3.151 + typedef MergeEdgeGraphWrapper<Graph1, Graph2> GW;
3.152 + {
3.153 + checkConcept<StaticGraph, GW>();
3.154 + }
3.155 + GW gw(g1, g2);
3.156 + GW::Node sw;
3.157 + GW::Node tw;
3.158 + {
3.159 + Graph2::NodeIt k(g2);
3.160 + sw=GW::Node(INVALID, k, true);
3.161 + ++k;
3.162 + tw=GW::Node(INVALID, k, true);
3.163 + }
3.164 +
3.165 + std::ifstream f1("graph2.dim");
3.166 + readDimacs(f1, g1);
3.167 +
3.168 + cout << "1st graph" << endl;
3.169 + printGraph(g1);
3.170 +
3.171 + cout << "2nd graph" << endl;
3.172 + printGraph(g2);
3.173 +
3.174 + cout << "merged graph" << endl;
3.175 + printGraph(gw);
3.176 +
3.177 + typedef ListGraph Graph3;
3.178 + Graph3 g3;
3.179 + GW::NodeMap<Graph3::Node> gwn(gw);
3.180 + Graph3::NodeMap<GW::Node> g3n(g3);
3.181 + for (GW::NodeIt n(gw); n!=INVALID; ++n) {
3.182 + Graph3::Node m=g3.addNode();
3.183 + gwn.set(n, m);
3.184 + g3n.set(m, n);
3.185 + }
3.186 +
3.187 + typedef NewEdgeSetGraphWrapper<GW, Graph3> GWW;
3.188 + {
3.189 + checkConcept<StaticGraph, GWW>();
3.190 + }
3.191 +
3.192 + GWW gww(gw, g3, gwn, g3n);
3.193 +
3.194 + for (Graph1::NodeIt n(g1); n!=INVALID; ++n) {
3.195 + g3.addEdge(gwn[sw], gwn[GW::Node(n,INVALID,false)]);
3.196 + }
3.197 +
3.198 +// for (Graph1::NodeIt n(g1); n!=INVALID; ++n) {
3.199 +// gww.addEdge(sw, GW::Node(n,INVALID,false));
3.200 +// }
3.201 +
3.202 + cout << "new edges" << endl;
3.203 + printGraph(g3);
3.204 +
3.205 + cout << "new edges in the new graph" << endl;
3.206 + printGraph(gww);
3.207 +
3.208 + typedef AugmentingGraphWrapper<GW, GWW> GWWW;
3.209 + {
3.210 + checkConcept<StaticGraph, GWWW>();
3.211 + }
3.212 + GWWW gwww(gw, gww);
3.213 +
3.214 + cout << "new edges merged into the original graph" << endl;
3.215 + printGraph(gwww);
3.216 +
3.217 }
3.218
3.219 - gw.printNode();
3.220 -
3.221 - {
3.222 -// typedef SmartGraph Graph1;
3.223 - typedef ListGraph Graph1;
3.224 - typedef ListGraph Graph2;
3.225 - Graph1 g;
3.226 - Graph2 h;
3.227 - typedef MergeNodeGraphWrapper<Graph1, Graph2> GW;
3.228 - GW gw(g, h);
3.229 - gw.printNode();
3.230 - }
3.231 - {
3.232 -// typedef SmartGraph Graph1;
3.233 - typedef Graph3 Graph1;
3.234 - typedef ListGraph Graph2;
3.235 - Graph1 g;
3.236 - Graph2 h;
3.237 - typedef MergeNodeGraphWrapper<Graph1, Graph2> GW;
3.238 - GW gw(g, h);
3.239 - gw.printNode();
3.240 - }
3.241 - {
3.242 -// typedef SmartGraph Graph1;
3.243 - typedef ListGraph Graph1;
3.244 - typedef Graph3 Graph2;
3.245 - Graph1 g;
3.246 - Graph2 h;
3.247 - typedef MergeNodeGraphWrapper<Graph1, Graph2> GW;
3.248 - GW gw(g, h);
3.249 - gw.printNode();
3.250 - }
3.251 - }
3.252 - {
3.253 - Graph1 g;
3.254 - Graph2 h;
3.255 - typedef Graph1::Node Node1;
3.256 - typedef Graph2::Node Node2;
3.257 - typedef NewEdgeSetGraphWrapper<Graph1, Graph2> GW;
3.258 - Graph1::NodeMap<Graph2::Node> e_node(g);
3.259 - Graph2::NodeMap<Graph1::Node> n_node(h);
3.260 - GW gw(g, h, e_node, n_node);
3.261 - for (int i=0; i<4; ++i) {
3.262 - Node1 n=g.addNode();
3.263 - e_node.set(n, INVALID);
3.264 - }
3.265 - for (int i=0; i<4; ++i) {
3.266 - Graph1::Node n1=g.addNode();
3.267 - Graph2::Node n2=h.addNode();
3.268 - e_node.set(n1, n2);
3.269 - n_node.set(n2, n1);
3.270 - }
3.271 - for (Graph2::NodeIt n(h); n!=INVALID; ++n)
3.272 - for (Graph2::NodeIt m(h); m!=INVALID; ++m)
3.273 - if ((h.id(n)+h.id(m))%3==0) h.addEdge(n, m);
3.274 -// Graph1::NodeIt n(g);
3.275 -// Node1 n1=n;
3.276 -// Node1 n2=++n;
3.277 -// Node1 n3=++n;
3.278 -// Node1 n4=n;
3.279 -// gw.addEdge(n1, n2);
3.280 -// gw.addEdge(n1, n2);
3.281 -// for (EdgeIt(e))
3.282 -// Graph1::Node n1=g.addNode();
3.283 -// Graph1::Node n2=g.addNode();
3.284 -// Graph1::Node n3=g.addNode();
3.285 -// Graph2::Node n4=h.addNode();
3.286 -// Graph2::Node n5=h.addNode();
3.287 - for (GW::EdgeIt e(gw); e!=INVALID; ++e)
3.288 - cout << gw.id(e) << endl;
3.289 - for (GW::NodeIt n(gw); n!=INVALID; ++n) {
3.290 - if (e_node[n]==INVALID) {
3.291 - cout<<gw.id(n)<<" INVALID"<<endl;
3.292 - } else {
3.293 - cout <<gw.id(n)<<" "<<h.id(e_node[n])<<" out_edges: ";
3.294 - // cout << &e_node << endl;
3.295 - //cout << &n_node << endl;
3.296 - for (GW::OutEdgeIt e(gw, n); e!=INVALID; ++e) {
3.297 - cout<<gw.id(e)<<" ";
3.298 - }
3.299 - cout<< endl;
3.300 - }
3.301 - }
3.302 - }
3.303 }