[Lemon-commits] [lemon_svn] marci: r1415 - in hugo/trunk/src/work/marci: . lp
Lemon SVN
svn at lemon.cs.elte.hu
Mon Nov 6 20:45:15 CET 2006
Author: marci
Date: Mon Nov 29 18:55:46 2004
New Revision: 1415
Modified:
hugo/trunk/src/work/marci/lp/max_flow_by_lp.cc
hugo/trunk/src/work/marci/lp/min_cost_gen_flow.h
hugo/trunk/src/work/marci/merge_node_graph_wrapper.h
hugo/trunk/src/work/marci/merge_node_graph_wrapper_test.cc
Log:
MergeGraphWrapper bug fixes
Modified: hugo/trunk/src/work/marci/lp/max_flow_by_lp.cc
==============================================================================
--- hugo/trunk/src/work/marci/lp/max_flow_by_lp.cc (original)
+++ hugo/trunk/src/work/marci/lp/max_flow_by_lp.cc Mon Nov 29 18:55:46 2004
@@ -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<Graph, int, Excess, LCap>
min_cost(g, excess, lcap, cap, flow, cost);
+ min_cost.feasible();
min_cost.run();
std::cout << "elapsed time: " << ts << std::endl;
Modified: hugo/trunk/src/work/marci/lp/min_cost_gen_flow.h
==============================================================================
--- hugo/trunk/src/work/marci/lp/min_cost_gen_flow.h (original)
+++ hugo/trunk/src/work/marci/lp/min_cost_gen_flow.h Mon Nov 29 18:55:46 2004
@@ -1,17 +1,18 @@
// -*- c++ -*-
#ifndef LEMON_MIN_COST_GEN_FLOW_H
#define LEMON_MIN_COST_GEN_FLOW_H
-//#include <iostream>
+#include <iostream>
//#include <fstream>
-//#include <lemon/smart_graph.h>
-//#include <lemon/list_graph.h>
+#include <lemon/smart_graph.h>
+#include <lemon/list_graph.h>
//#include <lemon/dimacs.h>
//#include <lemon/time_measure.h>
//#include <graph_wrapper.h>
-//#include <lemon/preflow.h>
+#include <lemon/preflow.h>
//#include <augmenting_flow.h>
//#include <preflow_res.h>
+#include <../merge_node_graph_wrapper.h>
#include <lemon/../work/marci/lp/lp_solver_wrapper.h>
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<const Graph, Graph2> 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<GW, Graph3> GWW;
+// {
+// checkConcept<StaticGraph, GWW>();
+// }
+ GWW gww(gw);
+ typedef AugmentingGraphWrapper<GW, GWW> GWWW;
+ GWWW gwww(gw, gww);
+
+ // std::cout << "making new edges..." << std::endl;
+ typename GWWW::template EdgeMap<Num> 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]<a) {
+ typename GWW::Edge e=
+ gww.addEdge(s, typename GW::Node(n,INVALID,false));
+ translated_cap.set(typename GWWW::Edge(INVALID, e, true),
+ a-excess[n]);
+ expected+=a-excess[n];
+ }
+ }
+
+ // std::cout << "preflow..." << std::endl;
+ typename GWWW::template EdgeMap<Num> translated_flow(gwww, 0);
+ Preflow<GWWW, Num> 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();
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 Mon Nov 29 18:55:46 2004
@@ -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 <typename _Graph1, typename _Graph2, typename Enable=void>
- 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 <typename _Value> class NodeMap;
class Node : public Graph1Node, public Graph2Node {
- friend class MergeNodeGraphWrapperBase<_Graph1, _Graph2>;
- template <typename _Value> 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<Graph1Node*>(&i));
- i.backward=false;
- if (*static_cast<Graph1Node*>(&i)==INVALID) {
- Parent2::graph->first(*static_cast<Graph2Node*>(&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<Graph2Node*>(&i));
- i.backward=true;
- }
- } else {
- Parent2::graph->next(*static_cast<Graph2Node*>(&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[];
- };
-
+ 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 <typename _Graph1, typename _Graph2>
- class MergeNodeGraphWrapperBase<
+ class MergeNodeGraphWrapperBaseBase<
_Graph1, _Graph2, typename boost::enable_if<
boost::is_same<typename _Graph1::Node, typename _Graph2::Node> >::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 <typename _Value> class NodeMap;
class Node : public Graph1Node {
- friend class MergeNodeGraphWrapperBase<_Graph1, _Graph2>;
- template <typename _Value> 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<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[];
- };
-
+ 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 <typename _Graph1, typename _Graph2>
- class MergeNodeGraphWrapperBase<
+ class MergeNodeGraphWrapperBaseBase<
_Graph1, _Graph2, typename boost::enable_if<
boost::is_base_and_derived<typename _Graph1::Node, typename _Graph2::Node> >::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 <typename _Value> class NodeMap;
class Node : public Graph2Node {
- friend class MergeNodeGraphWrapperBase<_Graph1, _Graph2>;
- template <typename _Value> 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<Graph1Node*>(&i));
- i.backward=false;
- if (*static_cast<Graph1Node*>(&i)==INVALID) {
- Parent2::graph->first(*static_cast<Graph2Node*>(&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<Graph2Node*>(&i));
- i.backward=true;
- }
- } else {
- Parent2::graph->next(*static_cast<Graph2Node*>(&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[];
- };
-
+ 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.
- Specialized implementaton for the case when _Graph1::Node is derived
- from _Graph2::Node.
- */
template <typename _Graph1, typename _Graph2>
- class MergeNodeGraphWrapperBase<
+ class MergeNodeGraphWrapperBaseBase<
_Graph1, _Graph2, typename boost::enable_if<
boost::is_base_and_derived<typename _Graph2::Node, typename _Graph1::Node> >::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 <typename _Value> class NodeMap;
class Node : public Graph1Node {
- friend class MergeNodeGraphWrapperBase<_Graph1, _Graph2>;
- template <typename _Value> 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 <typename _Graph1, typename _Graph2>
+ 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<Graph1Node*>(&i));
- i.backward=false;
+ this->setForward(i);
if (*static_cast<Graph1Node*>(&i)==INVALID) {
Parent2::graph->first(*static_cast<Graph2Node*>(&i));
- i.backward=true;
+ this->setBackward(i);
}
}
void next(Node& i) const {
- if (!(i.backward)) {
+ if (this->forward(i)) {
Parent1::graph->next(*static_cast<Graph1Node*>(&i));
if (*static_cast<Graph1Node*>(&i)==INVALID) {
Parent2::graph->first(*static_cast<Graph2Node*>(&i));
- i.backward=true;
+ this->setBackward(i);
}
} else {
Parent2::graph->next(*static_cast<Graph2Node*>(&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 <typename _Graph1, typename _Graph2>
class MergeNodeGraphWrapper : public
IterableGraphExtender<MergeNodeGraphWrapperBase<_Graph1, _Graph2> > {
@@ -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<Graph1Edge*>(&i));
@@ -592,17 +422,25 @@
}
}
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) {
+ if (!backward(n)) {
+ Parent1::graph->firstIn(*static_cast<Graph1Edge*>(&i), n);
+ if (*static_cast<Graph1Edge*>(&i)==INVALID)
+ i=INVALID;
+ else
+ i.backward=false;
+ } else {
Parent2::graph->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) {
+ if (!backward(n)) {
+ Parent1::graph->firstOut(*static_cast<Graph1Edge*>(&i), n);
+ if (*static_cast<Graph1Edge*>(&i)==INVALID)
+ i=INVALID;
+ else
+ i.backward=false;
+ } else {
Parent2::graph->firstOut(*static_cast<Graph2Edge*>(&i), n);
i.backward=true;
}
@@ -623,10 +461,7 @@
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<Graph2Edge*>(&i));
- i.backward=true;
- }
+ if (*static_cast<Graph1Edge*>(&i)==INVALID) i=INVALID;
} else {
Parent2::graph->nextIn(*static_cast<Graph2Edge*>(&i));
}
@@ -634,10 +469,7 @@
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<Graph2Edge*>(&i));
- i.backward=true;
- }
+ if (*static_cast<Graph1Edge*>(&i)==INVALID) i=INVALID;
} else {
Parent2::graph->nextOut(*static_cast<Graph2Edge*>(&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<Graph1Edge*>(&i));
@@ -770,17 +607,25 @@
}
}
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) {
+ if (!backward(n)) {
+ Parent1::graph->firstIn(*static_cast<Graph1Edge*>(&i), n);
+ if (*static_cast<Graph1Edge*>(&i)==INVALID)
+ i=INVALID;
+ else
+ i.backward=false;
+ } else {
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) {
+ if (!backward(n)) {
+ Parent1::graph->firstOut(*static_cast<Graph1Edge*>(&i), n);
+ if (*static_cast<Graph1Edge*>(&i)==INVALID)
+ i=INVALID;
+ else
+ i.backward=false;
+ } else {
Parent2::graph->firstOut(*static_cast<Graph1Edge*>(&i), n);
i.backward=true;
}
@@ -801,10 +646,7 @@
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;
- }
+ if (*static_cast<Graph1Edge*>(&i)==INVALID) i=INVALID;
} else {
Parent2::graph->nextIn(*static_cast<Graph1Edge*>(&i));
}
@@ -812,10 +654,7 @@
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;
- }
+ if (*static_cast<Graph1Edge*>(&i)==INVALID) i=INVALID;
} else {
Parent2::graph->nextOut(*static_cast<Graph1Edge*>(&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<Graph1Edge*>(&i));
@@ -955,17 +799,25 @@
}
}
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) {
+ if (!backward(n)) {
+ Parent1::graph->firstIn(*static_cast<Graph1Edge*>(&i), n);
+ if (*static_cast<Graph1Edge*>(&i)==INVALID)
+ i=INVALID;
+ else
+ i.backward=false;
+ } else {
Parent2::graph->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) {
+ if (!backward(n)) {
+ Parent1::graph->firstOut(*static_cast<Graph1Edge*>(&i), n);
+ if (*static_cast<Graph1Edge*>(&i)==INVALID)
+ i=INVALID;
+ else
+ i.backward=false;
+ } else {
Parent2::graph->firstOut(*static_cast<Graph2Edge*>(&i), n);
i.backward=true;
}
@@ -986,10 +838,7 @@
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<Graph2Edge*>(&i));
- i.backward=true;
- }
+ if (*static_cast<Graph1Edge*>(&i)==INVALID) i=INVALID;
} else {
Parent2::graph->nextIn(*static_cast<Graph2Edge*>(&i));
}
@@ -997,10 +846,7 @@
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<Graph2Edge*>(&i));
- i.backward=true;
- }
+ if (*static_cast<Graph1Edge*>(&i)==INVALID) i=INVALID;
} else {
Parent2::graph->nextOut(*static_cast<Graph2Edge*>(&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<Graph1Edge*>(&i));
@@ -1139,17 +990,25 @@
}
}
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) {
+ if (!backward(n)) {
+ Parent1::graph->firstIn(*static_cast<Graph1Edge*>(&i), n);
+ if (*static_cast<Graph1Edge*>(&i)==INVALID)
+ i=INVALID;
+ else
+ i.backward=false;
+ } else {
Parent2::graph->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) {
+ if (!backward(n)) {
+ Parent1::graph->firstOut(*static_cast<Graph1Edge*>(&i), n);
+ if (*static_cast<Graph1Edge*>(&i)==INVALID)
+ i=INVALID;
+ else
+ i.backward=false;
+ } else {
Parent2::graph->firstOut(*static_cast<Graph2Edge*>(&i), n);
i.backward=true;
}
@@ -1170,10 +1029,7 @@
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<Graph2Edge*>(&i));
- i.backward=true;
- }
+ if (*static_cast<Graph1Edge*>(&i)==INVALID) i=INVALID;
} else {
Parent2::graph->nextIn(*static_cast<Graph2Edge*>(&i));
}
@@ -1181,10 +1037,7 @@
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<Graph2Edge*>(&i));
- i.backward=true;
- }
+ if (*static_cast<Graph1Edge*>(&i)==INVALID) i=INVALID;
} else {
Parent2::graph->nextOut(*static_cast<Graph2Edge*>(&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 <typename _Graph, typename _EdgeSetGraph>
+ 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<typename EdgeSetGraph::Node> _e_node;
+ typename EdgeSetGraph::template NodeMap<typename Graph::Node> _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 <typename _Graph1, typename _Graph2, typename Enable=void>
class AugmentingGraphWrapperBase :
@@ -1506,9 +1415,10 @@
}
void nextIn(Edge& i) const {
if (!(i.backward)) {
+ Node n=target(i);
Parent1::graph->nextIn(*static_cast<Graph1Edge*>(&i));
if (*static_cast<Graph1Edge*>(&i)==INVALID) {
- graph2->first(*static_cast<Graph2Edge*>(&i));
+ graph2->firstIn(*static_cast<Graph2Edge*>(&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<Graph1Edge*>(&i));
if (*static_cast<Graph1Edge*>(&i)==INVALID) {
- graph2->first(*static_cast<Graph2Edge*>(&i));
+ graph2->firstOut(*static_cast<Graph2Edge*>(&i), n);
i.backward=true;
}
} else {
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 Mon Nov 29 18:55:46 2004
@@ -4,6 +4,7 @@
#include <lemon/list_graph.h>
#include <lemon/smart_graph.h>
#include <lemon/dimacs.h>
+#include <lemon/preflow.h>
#include <lemon/full_graph.h>
#include <merge_node_graph_wrapper.h>
@@ -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<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();
- typedef ResGraphWrapper<Graph1, int,
- ConstMap<Graph1, int>, ConstMap<Graph1, int> > Graph4;
- checkConcept<StaticGraph, MergeEdgeGraphWrapper<Graph1, Graph4> >();
- MergeEdgeGraphWrapper<Graph1, Graph4>::printNode();
- MergeEdgeGraphWrapper<Graph1, Graph4>::printEdge();
- checkConcept<StaticGraph, MergeEdgeGraphWrapper<Graph4, Graph1> >();
- MergeEdgeGraphWrapper<Graph4, Graph1>::printNode();
- MergeEdgeGraphWrapper<Graph4, Graph1>::printEdge();
- }
+// {
+// 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();
+// typedef ResGraphWrapper<Graph1, int,
+// ConstMap<Graph1, int>, ConstMap<Graph1, int> > Graph4;
+// checkConcept<StaticGraph, MergeEdgeGraphWrapper<Graph1, Graph4> >();
+// MergeEdgeGraphWrapper<Graph1, Graph4>::printNode();
+// MergeEdgeGraphWrapper<Graph1, Graph4>::printEdge();
+// checkConcept<StaticGraph, MergeEdgeGraphWrapper<Graph4, Graph1> >();
+// MergeEdgeGraphWrapper<Graph4, Graph1>::printNode();
+// MergeEdgeGraphWrapper<Graph4, Graph1>::printEdge();
+// }
Graph1 g1;
Graph2 g2;
typedef MergeEdgeGraphWrapper<Graph1, Graph2> GW;
GW gw(g1, g2);
+ Graph1::Node s1, t1;
+ Graph2::Node s2, t2;
+ Graph1::EdgeMap<int> cap1(g1);
+ Graph2::EdgeMap<int> cap2(g2);
std::ifstream f1("graph1.dim");
std::ifstream f2("graph2.dim");
readDimacs(f1, g1);
readDimacs(f2, g2);
+
+// GW::NodeMap<int> ize(gw, 8);
+// for (GW::NodeIt n(gw); n!=INVALID; ++n) ize.set(n, 9);
+// GW::EdgeMap<int> 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<int> 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<int> flow(gw, 0);
+// Preflow<GW, int> 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<int> flow(gw, 0);
+// Preflow<GW, int> 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<int> flow(gw, 0);
+// Preflow<GW, int> 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<int> flow(gw, 0);
+// Preflow<GW, int> 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<GW, Graph3> GWW;
+// {
+// checkConcept<StaticGraph, GWW>();
+// }
+
+ 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<GW, GWW> GWWW;
+ // {
+ // checkConcept<StaticGraph, GWWW>();
+ // }
+ GWWW gwww(gw, gww);
+ cout << "fully merged graph" << endl;
+ printGraph(gwww);
}
{
cout << "SECOND TEST" << endl;
typedef SmartGraph Graph1;
- {
- checkConcept<StaticGraph, Graph1>();
- }
+// {
+// checkConcept<StaticGraph, Graph1>();
+// }
Graph1 g1;
@@ -93,16 +180,16 @@
ConstMap<FullGraph::Edge, bool> const_false_map(false);
typedef EdgeSubGraphWrapper<FullGraph, ConstMap<FullGraph::Edge, bool> >
Graph2;
- {
- checkConcept<StaticGraph, Graph2>();
- }
+// {
+// checkConcept<StaticGraph, Graph2>();
+// }
Graph2 g2(pre_g2, const_false_map);
typedef MergeEdgeGraphWrapper<Graph1, Graph2> GW;
- {
- checkConcept<StaticGraph, GW>();
- }
+// {
+// checkConcept<StaticGraph, GW>();
+// }
GW gw(g1, g2);
GW::Node sw;
GW::Node tw;
@@ -137,9 +224,9 @@
}
typedef NewEdgeSetGraphWrapper<GW, Graph3> GWW;
- {
- checkConcept<StaticGraph, GWW>();
- }
+// {
+// checkConcept<StaticGraph, GWW>();
+// }
GWW gww(gw, g3, gwn, g3n);
@@ -158,9 +245,9 @@
printGraph(gww);
typedef AugmentingGraphWrapper<GW, GWW> GWWW;
- {
- checkConcept<StaticGraph, GWWW>();
- }
+// {
+// checkConcept<StaticGraph, GWWW>();
+// }
GWWW gwww(gw, gww);
cout << "new edges merged into the original graph" << endl;
More information about the Lemon-commits
mailing list