# HG changeset patch # User marci # Date 1101750946 0 # Node ID 3b1ad8bc21da8ea5c81a9b410ab9df20f9655384 # Parent 28e117c5bddf829834f704c07b0f576ad78ecb3b MergeGraphWrapper bug fixes diff -r 28e117c5bddf -r 3b1ad8bc21da src/work/marci/lp/max_flow_by_lp.cc --- a/src/work/marci/lp/max_flow_by_lp.cc Mon Nov 29 16:11:51 2004 +0000 +++ b/src/work/marci/lp/max_flow_by_lp.cc Mon Nov 29 17:55:46 2004 +0000 @@ -21,7 +21,7 @@ int main(int, char **) { typedef ListGraph MutableGraph; - typedef SmartGraph Graph; + typedef ListGraph Graph; typedef Graph::Node Node; typedef Graph::Edge Edge; typedef Graph::EdgeIt EdgeIt; @@ -178,6 +178,7 @@ MinCostGenFlow min_cost(g, excess, lcap, cap, flow, cost); + min_cost.feasible(); min_cost.run(); std::cout << "elapsed time: " << ts << std::endl; diff -r 28e117c5bddf -r 3b1ad8bc21da src/work/marci/lp/min_cost_gen_flow.h --- a/src/work/marci/lp/min_cost_gen_flow.h Mon Nov 29 16:11:51 2004 +0000 +++ b/src/work/marci/lp/min_cost_gen_flow.h Mon Nov 29 17:55:46 2004 +0000 @@ -1,17 +1,18 @@ // -*- c++ -*- #ifndef LEMON_MIN_COST_GEN_FLOW_H #define LEMON_MIN_COST_GEN_FLOW_H -//#include +#include //#include -//#include -//#include +#include +#include //#include //#include //#include -//#include +#include //#include //#include +#include <../merge_node_graph_wrapper.h> #include namespace lemon { @@ -51,6 +52,71 @@ const CostMap& _cost) : g(_g), excess(_excess), lcapacity(_lcapacity), capacity(_capacity), flow(_flow), cost(_cost) { } + bool feasible() { + // std::cout << "making new vertices..." << std::endl; + typedef ListGraph Graph2; + Graph2 g2; + typedef MergeEdgeGraphWrapper GW; + // std::cout << "merging..." << std::endl; + GW gw(g, g2); + typename GW::Node s(INVALID, g2.addNode(), true); + typename GW::Node t(INVALID, g2.addNode(), true); + typedef SmartGraph Graph3; + // std::cout << "making extender graph..." << std::endl; + typedef NewEdgeSetGraphWrapper2 GWW; +// { +// checkConcept(); +// } + GWW gww(gw); + typedef AugmentingGraphWrapper GWWW; + GWWW gwww(gw, gww); + + // std::cout << "making new edges..." << std::endl; + typename GWWW::template EdgeMap translated_cap(gwww); + + for (typename GW::EdgeIt e(gw); e!=INVALID; ++e) + translated_cap.set(typename GWWW::Edge(e,INVALID,false), + capacity[e]-lcapacity[e]); + + Num expected=0; + + // std::cout << "making new edges 2..." << std::endl; + for (typename Graph::NodeIt n(g); n!=INVALID; ++n) { + Num a=0; + for (typename Graph::InEdgeIt e(g, n); e!=INVALID; ++e) + a+=lcapacity[e]; + for (typename Graph::OutEdgeIt e(g, n); e!=INVALID; ++e) + a-=lcapacity[e]; + if (excess[n]>a) { + typename GWW::Edge e= + gww.addEdge(typename GW::Node(n,INVALID,false), t); + translated_cap.set(typename GWWW::Edge(INVALID, e, true), + excess[n]-a); + } + if (excess[n] translated_flow(gwww, 0); + Preflow preflow(gwww, s, t, + translated_cap, translated_flow); + preflow.run(); + // std::cout << "fv: " << preflow.flowValue() << std::endl; + // std::cout << "expected: " << expected << std::endl; + + for (typename Graph::EdgeIt e(g); e!=INVALID; ++e) { + typename GW::Edge ew(e, INVALID, false); + typename GWWW::Edge ewww(ew, INVALID, false); + flow.set(e, translated_flow[ewww]+lcapacity[e]); + } + return (expected>=preflow.flowValue()); + } void run() { LPSolverWrapper lp; lp.setMinimize(); diff -r 28e117c5bddf -r 3b1ad8bc21da src/work/marci/merge_node_graph_wrapper.h --- a/src/work/marci/merge_node_graph_wrapper.h Mon Nov 29 16:11:51 2004 +0000 +++ b/src/work/marci/merge_node_graph_wrapper.h Mon Nov 29 17:55:46 2004 +0000 @@ -40,13 +40,8 @@ }; - /*! 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 : + class MergeNodeGraphWrapperBaseBase : public P1<_Graph1>, public P2<_Graph2> { public: static void printNode() { std::cout << "node: generic" << std::endl; } @@ -57,13 +52,11 @@ typedef typename Parent1::Node Graph1Node; typedef typename Parent2::Node Graph2Node; protected: - MergeNodeGraphWrapperBase() { } + MergeNodeGraphWrapperBaseBase() { } public: - template class NodeMap; class Node : public Graph1Node, public Graph2Node { - friend class MergeNodeGraphWrapperBase<_Graph1, _Graph2>; - template friend class NodeMap; + friend class MergeNodeGraphWrapperBaseBase<_Graph1, _Graph2>; protected: bool backward; //true, iff backward public: @@ -88,79 +81,15 @@ } }; - //typedef void Edge; - class Edge { }; - - 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[]; - }; - + static bool forward(const Node& n) { return !n.backward; } + static bool backward(const Node& n) { return n.backward; } + static void setForward(Node& n) { n.backward=false; } + static void setBackward(Node& n) { n.backward=true; } }; - /*! 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< + class MergeNodeGraphWrapperBaseBase< _Graph1, _Graph2, typename boost::enable_if< boost::is_same >::type> : public P1<_Graph1>, public P2<_Graph2> { @@ -173,13 +102,11 @@ typedef typename Parent1::Node Graph1Node; typedef typename Parent2::Node Graph2Node; protected: - MergeNodeGraphWrapperBase() { } + MergeNodeGraphWrapperBaseBase() { } public: - template class NodeMap; class Node : public Graph1Node { - friend class MergeNodeGraphWrapperBase<_Graph1, _Graph2>; - template friend class NodeMap; + friend class MergeNodeGraphWrapperBaseBase<_Graph1, _Graph2>; protected: bool backward; //true, iff backward public: @@ -189,7 +116,7 @@ /// original one, otherwise its oppositely directed pair is obtained. Node(const Graph1Node& n1, const Graph2Node& n2, bool _backward) : - Graph1Node(!backward ? n1 : n2), backward(_backward) { } + Graph1Node(!_backward ? n1 : n2), backward(_backward) { } Node(Invalid i) : Graph1Node(i), backward(true) { } bool operator==(const Node& v) const { return (backward==v.backward && @@ -200,80 +127,15 @@ } }; - //typedef void Edge; - class Edge { }; - - 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[]; - }; - + static bool forward(const Node& n) { return !n.backward; } + static bool backward(const Node& n) { return n.backward; } + static void setForward(Node& n) { n.backward=false; } + static void setBackward(Node& n) { n.backward=true; } }; - /*! 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 is a base class and _Graph2::Node is derived from it. - */ template - class MergeNodeGraphWrapperBase< + class MergeNodeGraphWrapperBaseBase< _Graph1, _Graph2, typename boost::enable_if< boost::is_base_and_derived >::type> : public P1<_Graph1>, public P2<_Graph2> { @@ -286,13 +148,11 @@ typedef typename Parent1::Node Graph1Node; typedef typename Parent2::Node Graph2Node; protected: - MergeNodeGraphWrapperBase() { } + MergeNodeGraphWrapperBaseBase() { } public: - template class NodeMap; class Node : public Graph2Node { - friend class MergeNodeGraphWrapperBase<_Graph1, _Graph2>; - template friend class NodeMap; + friend class MergeNodeGraphWrapperBaseBase<_Graph1, _Graph2>; protected: bool backward; //true, iff backward public: @@ -319,80 +179,15 @@ } }; - //typedef void Edge; - class Edge { }; - - 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)); - } - } + static bool forward(const Node& n) { return !n.backward; } + static bool backward(const Node& n) { return n.backward; } + static void setForward(Node& n) { n.backward=false; } + static void setBackward(Node& n) { n.backward=true; } + }; + - 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[]; - }; - - }; - - - /*! A graph wrapper base class - for merging the node-set of two node-disjoint graphs - into the node-set of one graph. - Specialized implementaton for the case when _Graph1::Node is derived - from _Graph2::Node. - */ template - class MergeNodeGraphWrapperBase< + class MergeNodeGraphWrapperBaseBase< _Graph1, _Graph2, typename boost::enable_if< boost::is_base_and_derived >::type> : public P1<_Graph1>, public P2<_Graph2> { @@ -405,13 +200,11 @@ typedef typename Parent1::Node Graph1Node; typedef typename Parent2::Node Graph2Node; protected: - MergeNodeGraphWrapperBase() { } + MergeNodeGraphWrapperBaseBase() { } public: - template class NodeMap; class Node : public Graph1Node { - friend class MergeNodeGraphWrapperBase<_Graph1, _Graph2>; - template friend class NodeMap; + friend class MergeNodeGraphWrapperBaseBase<_Graph1, _Graph2>; protected: bool backward; //true, iff backward public: @@ -438,23 +231,42 @@ } }; - //typedef void Edge; + static bool forward(const Node& n) { return !n.backward; } + static bool backward(const Node& n) { return n.backward; } + static void setForward(Node& n) { n.backward=false; } + static void setBackward(Node& n) { n.backward=true; } + }; + + + template + class MergeNodeGraphWrapperBase : + public MergeNodeGraphWrapperBaseBase<_Graph1, _Graph2> { + public: + typedef MergeNodeGraphWrapperBaseBase<_Graph1, _Graph2> Parent; + typedef _Graph1 Graph1; + typedef _Graph2 Graph2; + typedef P1<_Graph1> Parent1; + typedef P2<_Graph2> Parent2; + typedef typename Parent1::Node Graph1Node; + typedef typename Parent2::Node Graph2Node; + + typedef typename Parent::Node Node; class Edge { }; void first(Node& i) const { Parent1::graph->first(*static_cast(&i)); - i.backward=false; + this->setForward(i); if (*static_cast(&i)==INVALID) { Parent2::graph->first(*static_cast(&i)); - i.backward=true; + this->setBackward(i); } } void next(Node& i) const { - if (!(i.backward)) { + if (this->forward(i)) { Parent1::graph->next(*static_cast(&i)); if (*static_cast(&i)==INVALID) { Parent2::graph->first(*static_cast(&i)); - i.backward=true; + this->setBackward(i); } } else { Parent2::graph->next(*static_cast(&i)); @@ -462,7 +274,7 @@ } int id(const Node& n) const { - if (!n.backward) + if (this->forward(n)) return this->Parent1::graph->id(n); else return this->Parent2::graph->id(n); @@ -486,13 +298,13 @@ forward_map(*(gw.Parent1::graph), value), backward_map(*(gw.Parent2::graph), value) { } _Value operator[](const Node& n) const { - if (!n.backward) + if (Parent::forward(n)) return forward_map[n]; else return backward_map[n]; } void set(const Node& n, const _Value& value) { - if (!n.backward) + if (Parent::forward(n)) forward_map.set(n, value); else backward_map.set(n, value); @@ -505,11 +317,24 @@ /*! A graph wrapper class - fors merging the node-set of two node-disjoint graphs - into one node-set. It does not satisfy + for merging the node-set of two node-disjoint graphs + into the node-set of one graph. + Different implementations are according to the relation of + _Graph1::Node and _Graph2::Node. + If _Graph1::Node and _Graph2::Node are unrelated, then + MergeNodeGraphWrapper<_Graph1, _Graph2>::Node + is derived from both. + If _Graph1::Node and _Graph2::Node are the same type, then + MergeNodeGraphWrapper<_Graph1, _Graph2>::Node + is derived from _Graph1::Node. + If one of _Graph1::Node and _Graph2::Node + is derived from the other one, then + MergeNodeGraphWrapper<_Graph1, _Graph2>::Node + is derived from the derived type. + It does not satisfy StaticGraph concept as it has no edge-set which works together with the node-set. - */ + */ template class MergeNodeGraphWrapper : public IterableGraphExtender > { @@ -582,6 +407,11 @@ } }; + using Parent::forward; + using Parent::backward; + bool forward(const Edge& e) const { return !e.backward; } + bool backward(const Edge& e) const { return e.backward; } + using Parent::first; void first(Edge& i) const { Parent1::graph->first(*static_cast(&i)); @@ -592,17 +422,25 @@ } } void firstIn(Edge& i, const Node& n) const { - Parent1::graph->firstIn(*static_cast(&i), n); - i.backward=false; - if (*static_cast(&i)==INVALID) { + if (!backward(n)) { + Parent1::graph->firstIn(*static_cast(&i), n); + if (*static_cast(&i)==INVALID) + i=INVALID; + else + i.backward=false; + } else { 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) { + if (!backward(n)) { + Parent1::graph->firstOut(*static_cast(&i), n); + if (*static_cast(&i)==INVALID) + i=INVALID; + else + i.backward=false; + } else { Parent2::graph->firstOut(*static_cast(&i), n); i.backward=true; } @@ -623,10 +461,7 @@ 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; - } + if (*static_cast(&i)==INVALID) i=INVALID; } else { Parent2::graph->nextIn(*static_cast(&i)); } @@ -634,10 +469,7 @@ 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; - } + if (*static_cast(&i)==INVALID) i=INVALID; } else { Parent2::graph->nextOut(*static_cast(&i)); } @@ -749,7 +581,7 @@ /// original one, otherwise its oppositely directed pair is obtained. Edge(const Graph1Edge& n1, const Graph2Edge& n2, bool _backward) : - Graph1Edge(!backward ? n1 : n2), backward(_backward) { } + Graph1Edge(!_backward ? n1 : n2), backward(_backward) { } Edge(Invalid i) : Graph1Edge(i), backward(true) { } bool operator==(const Edge& v) const { return (backward==v.backward && @@ -760,6 +592,11 @@ } }; + using Parent::forward; + using Parent::backward; + bool forward(const Edge& e) const { return !e.backward; } + bool backward(const Edge& e) const { return e.backward; } + using Parent::first; void first(Edge& i) const { Parent1::graph->first(*static_cast(&i)); @@ -770,17 +607,25 @@ } } void firstIn(Edge& i, const Node& n) const { - Parent1::graph->firstIn(*static_cast(&i), n); - i.backward=false; - if (*static_cast(&i)==INVALID) { + if (!backward(n)) { + Parent1::graph->firstIn(*static_cast(&i), n); + if (*static_cast(&i)==INVALID) + i=INVALID; + else + i.backward=false; + } else { 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) { + if (!backward(n)) { + Parent1::graph->firstOut(*static_cast(&i), n); + if (*static_cast(&i)==INVALID) + i=INVALID; + else + i.backward=false; + } else { Parent2::graph->firstOut(*static_cast(&i), n); i.backward=true; } @@ -801,10 +646,7 @@ 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; - } + if (*static_cast(&i)==INVALID) i=INVALID; } else { Parent2::graph->nextIn(*static_cast(&i)); } @@ -812,10 +654,7 @@ 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; - } + if (*static_cast(&i)==INVALID) i=INVALID; } else { Parent2::graph->nextOut(*static_cast(&i)); } @@ -945,6 +784,11 @@ } }; + using Parent::forward; + using Parent::backward; + bool forward(const Edge& e) const { return !e.backward; } + bool backward(const Edge& e) const { return e.backward; } + using Parent::first; void first(Edge& i) const { Parent1::graph->first(*static_cast(&i)); @@ -955,17 +799,25 @@ } } void firstIn(Edge& i, const Node& n) const { - Parent1::graph->firstIn(*static_cast(&i), n); - i.backward=false; - if (*static_cast(&i)==INVALID) { + if (!backward(n)) { + Parent1::graph->firstIn(*static_cast(&i), n); + if (*static_cast(&i)==INVALID) + i=INVALID; + else + i.backward=false; + } else { 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) { + if (!backward(n)) { + Parent1::graph->firstOut(*static_cast(&i), n); + if (*static_cast(&i)==INVALID) + i=INVALID; + else + i.backward=false; + } else { Parent2::graph->firstOut(*static_cast(&i), n); i.backward=true; } @@ -986,10 +838,7 @@ 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; - } + if (*static_cast(&i)==INVALID) i=INVALID; } else { Parent2::graph->nextIn(*static_cast(&i)); } @@ -997,10 +846,7 @@ 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; - } + if (*static_cast(&i)==INVALID) i=INVALID; } else { Parent2::graph->nextOut(*static_cast(&i)); } @@ -1129,6 +975,11 @@ } }; + using Parent::forward; + using Parent::backward; + bool forward(const Edge& e) const { return !e.backward; } + bool backward(const Edge& e) const { return e.backward; } + using Parent::first; void first(Edge& i) const { Parent1::graph->first(*static_cast(&i)); @@ -1139,17 +990,25 @@ } } void firstIn(Edge& i, const Node& n) const { - Parent1::graph->firstIn(*static_cast(&i), n); - i.backward=false; - if (*static_cast(&i)==INVALID) { + if (!backward(n)) { + Parent1::graph->firstIn(*static_cast(&i), n); + if (*static_cast(&i)==INVALID) + i=INVALID; + else + i.backward=false; + } else { 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) { + if (!backward(n)) { + Parent1::graph->firstOut(*static_cast(&i), n); + if (*static_cast(&i)==INVALID) + i=INVALID; + else + i.backward=false; + } else { Parent2::graph->firstOut(*static_cast(&i), n); i.backward=true; } @@ -1170,10 +1029,7 @@ 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; - } + if (*static_cast(&i)==INVALID) i=INVALID; } else { Parent2::graph->nextIn(*static_cast(&i)); } @@ -1181,10 +1037,7 @@ 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; - } + if (*static_cast(&i)==INVALID) i=INVALID; } else { Parent2::graph->nextOut(*static_cast(&i)); } @@ -1347,6 +1200,14 @@ int edgeNum() const { return edge_set_graph->edgeNum(); } +// NNode addOldNode() { +// return Parent::addNode(); +// } + +// ENode addNewNode() { +// return edge_set_graph->addNode(); +// } + Edge addEdge(const Node& u, const Node& v) { return edge_set_graph->addEdge((*e_node)[u], (*e_node)[v]); } @@ -1392,7 +1253,7 @@ typedef _Graph Graph; typedef _EdgeSetGraph EdgeSetGraph; typedef IterableGraphExtender< - NewEdgeSetGraphWrapper<_Graph, _EdgeSetGraph> > Parent; + NewEdgeSetGraphWrapperBase<_Graph, _EdgeSetGraph> > Parent; protected: NewEdgeSetGraphWrapper() { } public: @@ -1409,6 +1270,51 @@ } }; + /*! A graph wrapper class for the following functionality. + The same as NewEdgeSetGrapWrapper, but the bijection and the graph of + new edges is andled inthe class. + */ + template + class NewEdgeSetGraphWrapper2 : + public IterableGraphExtender< + NewEdgeSetGraphWrapperBase<_Graph, _EdgeSetGraph> > { + public: + typedef _Graph Graph; + typedef _EdgeSetGraph EdgeSetGraph; + typedef IterableGraphExtender< + NewEdgeSetGraphWrapperBase<_Graph, _EdgeSetGraph> > Parent; + protected: + _EdgeSetGraph _edge_set_graph; + typename Graph::template NodeMap _e_node; + typename EdgeSetGraph::template NodeMap _n_node; + NewEdgeSetGraphWrapper2() { } + public: + typedef typename Graph::Node Node; + // typedef typename Parent::Edge Edge; + + NewEdgeSetGraphWrapper2(_Graph& _graph) : + _edge_set_graph(), + _e_node(_graph), _n_node(_edge_set_graph) { + setGraph(_graph); + setEdgeSetGraph(_edge_set_graph); + setNodeMap(_n_node); setENodeMap(_e_node); + Node n; + for (this->first(n); n!=INVALID; this->next(n)) { + typename EdgeSetGraph::Node e=_edge_set_graph.addNode(); + _e_node.set(n, e); + _n_node.set(e, n); + } + } + +// Node addNode() { +// Node n=(*this).Parent::addNode(); +// typename EdgeSetGraph::Node e=_edge_set_graph.addNode(); +// _e_node.set(n, e); +// _n_node.set(e, n); +// return n; +// } + + }; /*! A graph wrapper base class for merging graphs of type _Graph1 and _Graph2 @@ -1417,6 +1323,9 @@ into one graph. In an other point of view, _Graph1 is extended with the edge-set of _Graph2. + \warning we need specialize dimplementations + \todo we need specialize dimplementations + \bug we need specialize dimplementations */ template class AugmentingGraphWrapperBase : @@ -1506,9 +1415,10 @@ } void nextIn(Edge& i) const { if (!(i.backward)) { + Node n=target(i); Parent1::graph->nextIn(*static_cast(&i)); if (*static_cast(&i)==INVALID) { - graph2->first(*static_cast(&i)); + graph2->firstIn(*static_cast(&i), n); i.backward=true; } } else { @@ -1517,9 +1427,10 @@ } void nextOut(Edge& i) const { if (!(i.backward)) { + Node n=source(i); Parent1::graph->nextOut(*static_cast(&i)); if (*static_cast(&i)==INVALID) { - graph2->first(*static_cast(&i)); + graph2->firstOut(*static_cast(&i), n); i.backward=true; } } else { diff -r 28e117c5bddf -r 3b1ad8bc21da src/work/marci/merge_node_graph_wrapper_test.cc --- a/src/work/marci/merge_node_graph_wrapper_test.cc Mon Nov 29 16:11:51 2004 +0000 +++ b/src/work/marci/merge_node_graph_wrapper_test.cc Mon Nov 29 17:55:46 2004 +0000 @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -26,66 +27,152 @@ void printGraph(const Graph& g) { cout << " nodes:" << endl; for (typename Graph::NodeIt n(g); n!=INVALID; ++n) { - cout << " " << g.id(n) << endl; + cout << " " << g.id(n) << ": out edges:" << endl; + for (typename Graph::OutEdgeIt e(g, n); e!=INVALID; ++e) + cout << " " << g.id(g.source(e)) << "->" << g.id(g.target(e)) << endl; } cout << " edges:" << endl; - for (typename Graph::EdgeIt n(g); n!=INVALID; ++n) { - cout << " " << g.id(n) << ": " - << g.id(g.source(n)) << "->" << g.id(g.target(n)) << endl; + for (typename Graph::EdgeIt e(g); e!=INVALID; ++e) { + cout << " " << g.id(e) << ": " + << g.id(g.source(e)) << "->" << g.id(g.target(e)) << endl; } } int main() { { cout << "FIRST TEST" << endl; - typedef SmartGraph Graph1; + //typedef SmartGraph Graph1; + typedef ListGraph Graph1; typedef ListGraph Graph2; + typedef SmartGraph Graph3; - { - checkConcept >(); - MergeEdgeGraphWrapper::printNode(); - MergeEdgeGraphWrapper::printEdge(); - checkConcept >(); - MergeEdgeGraphWrapper::printNode(); - MergeEdgeGraphWrapper::printEdge(); - typedef ResGraphWrapper, ConstMap > Graph4; - checkConcept >(); - MergeEdgeGraphWrapper::printNode(); - MergeEdgeGraphWrapper::printEdge(); - checkConcept >(); - MergeEdgeGraphWrapper::printNode(); - MergeEdgeGraphWrapper::printEdge(); - } +// { +// checkConcept >(); +// MergeEdgeGraphWrapper::printNode(); +// MergeEdgeGraphWrapper::printEdge(); +// checkConcept >(); +// MergeEdgeGraphWrapper::printNode(); +// MergeEdgeGraphWrapper::printEdge(); +// typedef ResGraphWrapper, ConstMap > Graph4; +// checkConcept >(); +// MergeEdgeGraphWrapper::printNode(); +// MergeEdgeGraphWrapper::printEdge(); +// checkConcept >(); +// MergeEdgeGraphWrapper::printNode(); +// MergeEdgeGraphWrapper::printEdge(); +// } Graph1 g1; Graph2 g2; typedef MergeEdgeGraphWrapper GW; GW gw(g1, g2); + Graph1::Node s1, t1; + Graph2::Node s2, t2; + Graph1::EdgeMap cap1(g1); + Graph2::EdgeMap cap2(g2); std::ifstream f1("graph1.dim"); std::ifstream f2("graph2.dim"); readDimacs(f1, g1); readDimacs(f2, g2); + +// GW::NodeMap ize(gw, 8); +// for (GW::NodeIt n(gw); n!=INVALID; ++n) ize.set(n, 9); +// GW::EdgeMap mize(gw, 8); +// for (GW::EdgeIt n(gw); n!=INVALID; ++n) mize.set(n, 7); + +// std::ifstream f1("flow-1.dim"); +// std::ifstream f2("flow2.dim"); +// readDimacs(f1, g1, cap1, s1, t1); +// readDimacs(f2, g2, cap2, s2, t2); - cout << "1st graph" << endl; - printGraph(g1); +// GW::EdgeMap cap(gw); +// for (GW::EdgeIt e(gw); e!=INVALID; ++e) { +// if (gw.forward(e)) cap.set(e, cap1[e]); +// if (gw.backward(e)) cap.set(e, cap2[e]); +// } - cout << "2nd graph" << endl; - printGraph(g2); +// { +// GW::EdgeMap flow(gw, 0); +// Preflow preflow(gw, GW::Node(s1, INVALID, false), +// GW::Node(t1, INVALID, false), cap, flow); +// preflow.run(); +// std::cout << "s1->t1: " << preflow.flowValue() << std::endl; +// } +// { +// GW::EdgeMap flow(gw, 0); +// Preflow preflow(gw, GW::Node(INVALID, s2, true), +// GW::Node(INVALID, t2, true), cap, flow); +// preflow.run(); +// std::cout << "s2->t2: " << preflow.flowValue() << std::endl; +// } +// { +// GW::EdgeMap flow(gw, 0); +// Preflow preflow(gw, GW::Node(s1, INVALID, false), +// GW::Node(INVALID, t2, true), cap, flow); +// preflow.run(); +// std::cout << "s1->t2: " << preflow.flowValue() << std::endl; +// } +// { +// GW::EdgeMap flow(gw, 0); +// Preflow preflow(gw, GW::Node(INVALID, s2, true), +// GW::Node(s1, INVALID, false), cap, flow); +// preflow.run(); +// std::cout << "s2->t1: " << preflow.flowValue() << std::endl; +// } + cout << "1st graph" << endl; + printGraph(g1); - cout << "merged graph" << endl; - printGraph(gw); + cout << "2nd graph" << endl; + printGraph(g2); + cout << "merged graph" << endl; + printGraph(gw); + +// for (GW::NodeIt n(gw); n!=INVALID; ++n) +// std::cout << ize[n] << std::endl; +// for (GW::EdgeIt n(gw); n!=INVALID; ++n) +// std::cout << mize[n] << std::endl; + + typedef NewEdgeSetGraphWrapper2 GWW; +// { +// checkConcept(); +// } + + GWW gww(gw); + + cout << "new edges graph" << endl; + printGraph(gww); + + GWW::NodeIt n(gww); + GWW::Node n1=n; + ++n; + GWW::Node n2=n; + gww.addEdge(n1, n2); + // gww.addNode(); + // gww.addNode(); + + cout << "new edges graph" << endl; + printGraph(gww); + + typedef AugmentingGraphWrapper GWWW; + // { + // checkConcept(); + // } + GWWW gwww(gw, gww); + + cout << "fully merged graph" << endl; + printGraph(gwww); } { cout << "SECOND TEST" << endl; typedef SmartGraph Graph1; - { - checkConcept(); - } +// { +// checkConcept(); +// } Graph1 g1; @@ -93,16 +180,16 @@ ConstMap const_false_map(false); typedef EdgeSubGraphWrapper > Graph2; - { - checkConcept(); - } +// { +// checkConcept(); +// } Graph2 g2(pre_g2, const_false_map); typedef MergeEdgeGraphWrapper GW; - { - checkConcept(); - } +// { +// checkConcept(); +// } GW gw(g1, g2); GW::Node sw; GW::Node tw; @@ -137,9 +224,9 @@ } typedef NewEdgeSetGraphWrapper GWW; - { - checkConcept(); - } +// { +// checkConcept(); +// } GWW gww(gw, g3, gwn, g3n); @@ -158,9 +245,9 @@ printGraph(gww); typedef AugmentingGraphWrapper GWWW; - { - checkConcept(); - } +// { +// checkConcept(); +// } GWWW gwww(gw, gww); cout << "new edges merged into the original graph" << endl;