[Lemon-commits] [lemon_svn] marci: r744 - in hugo/trunk/src: hugo work/marci
Lemon SVN
svn at lemon.cs.elte.hu
Mon Nov 6 20:41:16 CET 2006
Author: marci
Date: Fri May 7 09:44:44 2004
New Revision: 744
Modified:
hugo/trunk/src/hugo/graph_wrapper.h
hugo/trunk/src/work/marci/iterator_bfs_demo.cc
Log:
BidirGraphWrapper<Graph>, the map values are different for the opposite edges.
Modified: hugo/trunk/src/hugo/graph_wrapper.h
==============================================================================
--- hugo/trunk/src/hugo/graph_wrapper.h (original)
+++ hugo/trunk/src/hugo/graph_wrapper.h Fri May 7 09:44:44 2004
@@ -218,6 +218,8 @@
};
};
+
+
/// A graph wrapper which reverses the orientation of the edges.
/// A graph wrapper which reverses the orientation of the edges.
@@ -292,6 +294,8 @@
};
+
+
/// Wrapper for hiding nodes and edges from a graph.
/// This wrapper shows a graph with filtered node-set and
@@ -463,6 +467,8 @@
bool hidden(const Edge& e) const { return !(*edge_filter_map)[e]; }
};
+
+
/// A wrapper for forgetting the orientation of a graph.
/// A wrapper for getting an undirected graph by forgetting
@@ -560,7 +566,321 @@
}
};
+
+
+ /// A wrapper for composing bidirected graph from a directed one.
+ /// experimental, for fezso's sake.
+ template<typename Graph>
+ class BidirGraphWrapper : public GraphWrapper<Graph> {
+ protected:
+ //const CapacityMap* capacity;
+ //FlowMap* flow;
+
+ BidirGraphWrapper() : GraphWrapper<Graph>()/*,
+ capacity(0), flow(0)*/ { }
+// void setCapacityMap(const CapacityMap& _capacity) {
+// capacity=&_capacity;
+// }
+// void setFlowMap(FlowMap& _flow) {
+// flow=&_flow;
+// }
+
+ public:
+
+ BidirGraphWrapper(Graph& _graph/*, const CapacityMap& _capacity,
+ FlowMap& _flow*/) :
+ GraphWrapper<Graph>(_graph)/*, capacity(&_capacity), flow(&_flow)*/ { }
+
+ class Edge;
+ class OutEdgeIt;
+ friend class Edge;
+ friend class OutEdgeIt;
+
+ typedef typename GraphWrapper<Graph>::Node Node;
+ typedef typename GraphWrapper<Graph>::NodeIt NodeIt;
+ class Edge : public Graph::Edge {
+ friend class BidirGraphWrapper<Graph>;
+ protected:
+ bool backward; //true, iff backward
+// typename Graph::Edge e;
+ public:
+ Edge() { }
+ Edge(const typename Graph::Edge& _e, bool _backward) :
+ Graph::Edge(_e), backward(_backward) { }
+ Edge(const Invalid& i) : Graph::Edge(i), backward(true) { }
+//the unique invalid iterator
+ friend bool operator==(const Edge& u, const Edge& v) {
+ return (v.backward==u.backward &&
+ static_cast<typename Graph::Edge>(u)==
+ static_cast<typename Graph::Edge>(v));
+ }
+ friend bool operator!=(const Edge& u, const Edge& v) {
+ return (v.backward!=u.backward ||
+ static_cast<typename Graph::Edge>(u)!=
+ static_cast<typename Graph::Edge>(v));
+ }
+ };
+
+ class OutEdgeIt {
+ friend class BidirGraphWrapper<Graph>;
+ protected:
+ typename Graph::OutEdgeIt out;
+ typename Graph::InEdgeIt in;
+ bool backward;
+ public:
+ OutEdgeIt() { }
+ //FIXME
+// OutEdgeIt(const Edge& e) : Edge(e) { }
+ OutEdgeIt(const Invalid& i) : out(i), in(i), backward(true) { }
+//the unique invalid iterator
+ OutEdgeIt(const BidirGraphWrapper<Graph>& _G, Node v) {
+ backward=false;
+ _G.graph->first(out, v);
+ while(_G.graph->valid(out) && !_G.enabled(*this)) { _G.graph->next(out); }
+ if (!_G.graph->valid(out)) {
+ backward=true;
+ _G.graph->first(in, v);
+ while(_G.graph->valid(in) && !_G.enabled(*this)) { _G.graph->next(in); }
+ }
+ }
+ operator Edge() const {
+// Edge e;
+// e.forward=this->forward;
+// if (this->forward) e=out; else e=in;
+// return e;
+ if (this->backward)
+ return Edge(in, this->backward);
+ else
+ return Edge(out, this->backward);
+ }
+ };
+
+ class InEdgeIt {
+ friend class BidirGraphWrapper<Graph>;
+ protected:
+ typename Graph::OutEdgeIt out;
+ typename Graph::InEdgeIt in;
+ bool backward;
+ public:
+ InEdgeIt() { }
+ //FIXME
+// OutEdgeIt(const Edge& e) : Edge(e) { }
+ InEdgeIt(const Invalid& i) : out(i), in(i), backward(true) { }
+//the unique invalid iterator
+ InEdgeIt(const BidirGraphWrapper<Graph>& _G, Node v) {
+ backward=false;
+ _G.graph->first(in, v);
+ while(_G.graph->valid(in) && !_G.enabled(*this)) { _G.graph->next(in); }
+ if (!_G.graph->valid(in)) {
+ backward=true;
+ _G.graph->first(out, v);
+ while(_G.graph->valid(out) && !_G.enabled(*this)) { _G.graph->next(out); }
+ }
+ }
+ operator Edge() const {
+// Edge e;
+// e.forward=this->forward;
+// if (this->forward) e=out; else e=in;
+// return e;
+ if (this->backward)
+ return Edge(out, this->backward);
+ else
+ return Edge(in, this->backward);
+ }
+ };
+
+ class EdgeIt {
+ friend class BidirGraphWrapper<Graph>;
+ protected:
+ typename Graph::EdgeIt e;
+ bool backward;
+ public:
+ EdgeIt() { }
+ EdgeIt(const Invalid& i) : e(i), backward(true) { }
+ EdgeIt(const BidirGraphWrapper<Graph>& _G) {
+ backward=false;
+ _G.graph->first(e);
+ while (_G.graph->valid(e) && !_G.enabled(*this)) _G.graph->next(e);
+ if (!_G.graph->valid(e)) {
+ backward=true;
+ _G.graph->first(e);
+ while (_G.graph->valid(e) && !_G.enabled(*this)) _G.graph->next(e);
+ }
+ }
+ operator Edge() const {
+ return Edge(e, this->backward);
+ }
+ };
+
+ using GraphWrapper<Graph>::first;
+// NodeIt& first(NodeIt& i) const {
+// i=NodeIt(*this); return i;
+// }
+ OutEdgeIt& first(OutEdgeIt& i, const Node& p) const {
+ i=OutEdgeIt(*this, p); return i;
+ }
+// FIXME not tested
+ InEdgeIt& first(InEdgeIt& i, const Node& p) const {
+ i=InEdgeIt(*this, p); return i;
+ }
+ EdgeIt& first(EdgeIt& i) const {
+ i=EdgeIt(*this); return i;
+ }
+ using GraphWrapper<Graph>::next;
+// NodeIt& next(NodeIt& n) const { GraphWrapper<Graph>::next(n); return n; }
+ OutEdgeIt& next(OutEdgeIt& e) const {
+ if (!e.backward) {
+ Node v=this->graph->aNode(e.out);
+ this->graph->next(e.out);
+ while(this->graph->valid(e.out) && !enabled(e)) {
+ this->graph->next(e.out); }
+ if (!this->graph->valid(e.out)) {
+ e.backward=true;
+ this->graph->first(e.in, v);
+ while(this->graph->valid(e.in) && !enabled(e)) {
+ this->graph->next(e.in); }
+ }
+ } else {
+ this->graph->next(e.in);
+ while(this->graph->valid(e.in) && !enabled(e)) {
+ this->graph->next(e.in); }
+ }
+ return e;
+ }
+// FIXME Not tested
+ InEdgeIt& next(InEdgeIt& e) const {
+ if (!e.backward) {
+ Node v=this->graph->aNode(e.in);
+ this->graph->next(e.in);
+ while(this->graph->valid(e.in) && !enabled(e)) {
+ this->graph->next(e.in); }
+ if (!this->graph->valid(e.in)) {
+ e.backward=true;
+ this->graph->first(e.out, v);
+ while(this->graph->valid(e.out) && !enabled(e)) {
+ this->graph->next(e.out); }
+ }
+ } else {
+ this->graph->next(e.out);
+ while(this->graph->valid(e.out) && !enabled(e)) {
+ this->graph->next(e.out); }
+ }
+ return e;
+ }
+ EdgeIt& next(EdgeIt& e) const {
+ if (!e.backward) {
+ this->graph->next(e.e);
+ while(this->graph->valid(e.e) && !enabled(e)) {
+ this->graph->next(e.e); }
+ if (!this->graph->valid(e.e)) {
+ e.backward=true;
+ this->graph->first(e.e);
+ while(this->graph->valid(e.e) && !enabled(e)) {
+ this->graph->next(e.e); }
+ }
+ } else {
+ this->graph->next(e.e);
+ while(this->graph->valid(e.e) && !enabled(e)) {
+ this->graph->next(e.e); }
+ }
+ return e;
+ }
+
+ Node tail(Edge e) const {
+ return ((!e.backward) ? this->graph->tail(e) : this->graph->head(e)); }
+ Node head(Edge e) const {
+ return ((!e.backward) ? this->graph->head(e) : this->graph->tail(e)); }
+
+ Node aNode(OutEdgeIt e) const {
+ return ((!e.backward) ? this->graph->aNode(e.out) :
+ this->graph->aNode(e.in)); }
+ Node bNode(OutEdgeIt e) const {
+ return ((!e.backward) ? this->graph->bNode(e.out) :
+ this->graph->bNode(e.in)); }
+
+ Node aNode(InEdgeIt e) const {
+ return ((!e.backward) ? this->graph->aNode(e.in) :
+ this->graph->aNode(e.out)); }
+ Node bNode(InEdgeIt e) const {
+ return ((!e.backward) ? this->graph->bNode(e.in) :
+ this->graph->bNode(e.out)); }
+
+// int nodeNum() const { return graph->nodeNum(); }
+ //FIXME
+ void edgeNum() const { }
+ //int edgeNum() const { return graph->edgeNum(); }
+
+
+// int id(Node v) const { return graph->id(v); }
+
+ bool valid(Node n) const { return GraphWrapper<Graph>::valid(n); }
+ bool valid(Edge e) const {
+ return this->graph->valid(e);
+ //return e.forward ? graph->valid(e.out) : graph->valid(e.in);
+ }
+
+ bool forward(const Edge& e) const { return !e.backward; }
+ bool backward(const Edge& e) const { return e.backward; }
+
+// void augment(const Edge& e, Number a) const {
+// if (!e.backward)
+// // flow->set(e.out, flow->get(e.out)+a);
+// flow->set(e, (*flow)[e]+a);
+// else
+// // flow->set(e.in, flow->get(e.in)-a);
+// flow->set(e, (*flow)[e]-a);
+// }
+
+ bool enabled(const Edge& e) const {
+ if (!e.backward)
+// return (capacity->get(e.out)-flow->get(e.out));
+ //return ((*capacity)[e]-(*flow)[e]);
+ return true;
+ else
+// return (flow->get(e.in));
+ //return ((*flow)[e]);
+ return true;
+ }
+
+// Number enabled(typename Graph::OutEdgeIt out) const {
+// // return (capacity->get(out)-flow->get(out));
+// return ((*capacity)[out]-(*flow)[out]);
+// }
+
+// Number enabled(typename Graph::InEdgeIt in) const {
+// // return (flow->get(in));
+// return ((*flow)[in]);
+// }
+
+ template <typename T>
+ class EdgeMap {
+ typename Graph::template EdgeMap<T> forward_map, backward_map;
+ public:
+ EdgeMap(const BidirGraphWrapper<Graph>& _G) : forward_map(*(_G.graph)), backward_map(*(_G.graph)) { }
+ EdgeMap(const BidirGraphWrapper<Graph>& _G, T a) : forward_map(*(_G.graph), a), backward_map(*(_G.graph), a) { }
+ void set(Edge e, T a) {
+ if (!e.backward)
+ forward_map.set(e.out, a);
+ else
+ backward_map.set(e.in, a);
+ }
+ T operator[](Edge e) const {
+ if (!e.backward)
+ return forward_map[e.out];
+ else
+ return backward_map[e.in];
+ }
+// T get(Edge e) const {
+// if (e.out_or_in)
+// return forward_map.get(e.out);
+// else
+// return backward_map.get(e.in);
+// }
+ };
+ };
+
+
/// A wrapper for composing the residual graph for directed flow and circulation problems.
@@ -629,14 +949,14 @@
// OutEdgeIt(const Edge& e) : Edge(e) { }
OutEdgeIt(const Invalid& i) : out(i), in(i), backward(true) { }
//the unique invalid iterator
- OutEdgeIt(const ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>& resG, Node v) {
+ OutEdgeIt(const ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>& _G, Node v) {
backward=false;
- resG.graph->first(out, v);
- while( resG.graph->valid(out) && !(resG.resCap(*this)>0) ) { resG.graph->next(out); }
- if (!resG.graph->valid(out)) {
+ _G.graph->first(out, v);
+ while( _G.graph->valid(out) && !(_G.resCap(*this)>0) ) { _G.graph->next(out); }
+ if (!_G.graph->valid(out)) {
backward=true;
- resG.graph->first(in, v);
- while( resG.graph->valid(in) && !(resG.resCap(*this)>0) ) { resG.graph->next(in); }
+ _G.graph->first(in, v);
+ while( _G.graph->valid(in) && !(_G.resCap(*this)>0) ) { _G.graph->next(in); }
}
}
operator Edge() const {
@@ -663,14 +983,14 @@
// OutEdgeIt(const Edge& e) : Edge(e) { }
InEdgeIt(const Invalid& i) : out(i), in(i), backward(true) { }
//the unique invalid iterator
- InEdgeIt(const ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>& resG, Node v) {
+ InEdgeIt(const ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>& _G, Node v) {
backward=false;
- resG.graph->first(in, v);
- while( resG.graph->valid(in) && !(resG.resCap(*this)>0) ) { resG.graph->next(in); }
- if (!resG.graph->valid(in)) {
+ _G.graph->first(in, v);
+ while( _G.graph->valid(in) && !(_G.resCap(*this)>0) ) { _G.graph->next(in); }
+ if (!_G.graph->valid(in)) {
backward=true;
- resG.graph->first(out, v);
- while( resG.graph->valid(out) && !(resG.resCap(*this)>0) ) { resG.graph->next(out); }
+ _G.graph->first(out, v);
+ while( _G.graph->valid(out) && !(_G.resCap(*this)>0) ) { _G.graph->next(out); }
}
}
operator Edge() const {
@@ -693,14 +1013,14 @@
public:
EdgeIt() { }
EdgeIt(const Invalid& i) : e(i), backward(true) { }
- EdgeIt(const ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>& resG) {
+ EdgeIt(const ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>& _G) {
backward=false;
- resG.graph->first(e);
- while (resG.graph->valid(e) && !(resG.resCap(*this)>0)) resG.graph->next(e);
- if (!resG.graph->valid(e)) {
+ _G.graph->first(e);
+ while (_G.graph->valid(e) && !(_G.resCap(*this)>0)) _G.graph->next(e);
+ if (!_G.graph->valid(e)) {
backward=true;
- resG.graph->first(e);
- while (resG.graph->valid(e) && !(resG.resCap(*this)>0)) resG.graph->next(e);
+ _G.graph->first(e);
+ while (_G.graph->valid(e) && !(_G.resCap(*this)>0)) _G.graph->next(e);
}
}
operator Edge() const {
@@ -874,6 +1194,8 @@
};
};
+
+
/// ErasingFirstGraphWrapper for blocking flows.
/// ErasingFirstGraphWrapper for blocking flows.
Modified: hugo/trunk/src/work/marci/iterator_bfs_demo.cc
==============================================================================
--- hugo/trunk/src/work/marci/iterator_bfs_demo.cc (original)
+++ hugo/trunk/src/work/marci/iterator_bfs_demo.cc Fri May 7 09:44:44 2004
@@ -314,5 +314,88 @@
}
}
+
+
+ {
+ typedef BidirGraphWrapper<const Graph> GW;
+ GW gw(G);
+
+ EdgeNameMap< GW, Graph::NodeMap<string> > edge_name(gw, node_name);
+
+ cout << "bfs and dfs iterator demo on the undirected graph" << endl;
+ for(GW::NodeIt n(gw); gw.valid(n); gw.next(n)) {
+ cout << node_name[GW::Node(n)] << ": ";
+ cout << "out edges: ";
+ for(GW::OutEdgeIt e(gw, n); gw.valid(e); gw.next(e))
+ cout << edge_name[e] << " ";
+ cout << "in edges: ";
+ for(GW::InEdgeIt e(gw, n); gw.valid(e); gw.next(e))
+ cout << edge_name[e] << " ";
+ cout << endl;
+ }
+// for(GW::EdgeIt e=gw.first<GW::EdgeIt>(); gw.valid(e); gw.next(e)) {
+// cout << edge_name.get(e) << " ";
+// }
+// cout << endl;
+
+ cout << "bfs from t ..." << endl;
+ BfsIterator< GW, GW::NodeMap<bool> > bfs(gw);
+ bfs.pushAndSetReached(t);
+ while (!bfs.finished()) {
+ //cout << "edge: ";
+ if (gw.valid(GW::OutEdgeIt(bfs))) {
+ cout << edge_name[GW::OutEdgeIt(bfs)] << /*endl*/", " <<
+ node_name[gw.aNode(bfs)] <<
+ (bfs.isANodeExamined() ? ": is examined, " : ": is not examined, ") <<
+ node_name[gw.bNode(bfs)] <<
+ (bfs.isBNodeNewlyReached() ? ": is newly reached." :
+ ": is not newly reached.");
+ } else {
+ cout << "invalid" << /*endl*/", " <<
+ node_name[bfs.aNode()] <<
+ (bfs.isANodeExamined() ? ": is examined, " : ": is not examined, ") <<
+
+ "invalid.";
+ }
+ cout << endl;
+ ++bfs;
+ }
+
+ cout << " /--> -------------> "<< endl;
+ cout << " / /-- v1 <-\\ /---- v3-\\ "<< endl;
+ cout << " / | | / /-> \\ "<< endl;
+ cout << " / | | / | ^ \\ "<< endl;
+ cout << "s | | / | | \\-> t "<< endl;
+ cout << " \\ | | / | | /-> "<< endl;
+ cout << " \\ | --/ / | | / "<< endl;
+ cout << " \\ \\-> v2 <--/ \\-- v4 -/ "<< endl;
+ cout << " \\--> -------------> "<< endl;
+
+ cout << "dfs from t ..." << endl;
+ DfsIterator< GW, GW::NodeMap<bool> > dfs(gw);
+ dfs.pushAndSetReached(t);
+ while (!dfs.finished()) {
+ ++dfs;
+ //cout << "edge: ";
+ if (gw.valid(GW::OutEdgeIt(dfs))) {
+ cout << edge_name[GW::OutEdgeIt(dfs)] << /*endl*/", " <<
+ node_name[gw.aNode(dfs)] <<
+ (dfs.isANodeExamined() ? ": is examined, " : ": is not examined, ") <<
+ node_name[gw.bNode(dfs)] <<
+ (dfs.isBNodeNewlyReached() ? ": is newly reached." :
+ ": is not newly reached.");
+ } else {
+ cout << "invalid" << /*endl*/", " <<
+ node_name[dfs.aNode()] <<
+ (dfs.isANodeExamined() ? ": is examined, " : ": is not examined, ") <<
+
+ "invalid.";
+ }
+ cout << endl;
+ }
+ }
+
+
+
return 0;
}
More information about the Lemon-commits
mailing list