[Lemon-commits] [lemon_svn] marci: r58 - hugo/trunk/src/work
Lemon SVN
svn at lemon.cs.elte.hu
Mon Nov 6 20:37:04 CET 2006
Author: marci
Date: Fri Jan 30 15:49:04 2004
New Revision: 58
Added:
hugo/trunk/src/work/edmonds_karp.hh
Log:
marci_max_flow.hh in the new concept
Added: hugo/trunk/src/work/edmonds_karp.hh
==============================================================================
--- (empty file)
+++ hugo/trunk/src/work/edmonds_karp.hh Fri Jan 30 15:49:04 2004
@@ -0,0 +1,206 @@
+#ifndef MARCI_MAX_FLOW_HH
+#define MARCI_MAX_FLOW_HH
+
+#include <algorithm>
+
+#include <bfs_iterator.hh>
+
+namespace marci {
+
+ template<typename Graph, typename T>
+ class ResGraph {
+ typedef typename Graph::NodeIt NodeIt;
+ typedef typename Graph::EachNodeIt EachNodeIt;
+ typedef typename Graph::SymEdgeIt OldSymEdgeIt;
+ const Graph& G;
+ typename Graph::EdgeMap<T>& flow;
+ const typename Graph::EdgeMap<T>& capacity;
+ public:
+ ResGraph(const Graph& _G, typename Graph::EdgeMap<T>& _flow,
+ const typename Graph::EdgeMap<T>& _capacity) :
+ G(_G), flow(_flow), capacity(_capacity) { }
+
+ class EdgeIt;
+ class OutEdgeIt;
+ friend class EdgeIt;
+ friend class OutEdgeIt;
+
+ class EdgeIt {
+ friend class ResGraph<Graph, T>;
+ protected:
+ const ResGraph<Graph, T>* resG;
+ OldSymEdgeIt sym;
+ public:
+ EdgeIt() { }
+ //EdgeIt(const EdgeIt& e) : resG(e.resG), sym(e.sym) { }
+ T free() const {
+ if (resG->G.aNode(sym)==resG->G.tail(sym)) {
+ return (resG->capacity.get(sym)-resG->flow.get(sym));
+ } else {
+ return (resG->flow.get(sym));
+ }
+ }
+ bool valid() const { return sym.valid(); }
+ void augment(const T a) const {
+ if (resG->G.aNode(sym)==resG->G.tail(sym)) {
+ resG->flow.set(sym, resG->flow.get(sym)+a);
+ } else {
+ resG->flow.set(sym, resG->flow.get(sym)-a);
+ }
+ }
+ };
+
+ class OutEdgeIt : public EdgeIt {
+ friend class ResGraph<Graph, T>;
+ public:
+ OutEdgeIt() { }
+ //OutEdgeIt(const OutEdgeIt& e) { resG=e.resG; sym=e.sym; }
+ private:
+ OutEdgeIt(const ResGraph<Graph, T>& _resG, const NodeIt v) {
+ resG=&_resG;
+ sym=resG->G.template first<OldSymEdgeIt>(v);
+ while( sym.valid() && !(free()>0) ) { ++sym; }
+ }
+ public:
+ OutEdgeIt& operator++() {
+ ++sym;
+ while( sym.valid() && !(free()>0) ) { ++sym; }
+ return *this;
+ }
+ };
+
+ void getFirst(OutEdgeIt& e, const NodeIt v) const {
+ e=OutEdgeIt(*this, v);
+ }
+ void getFirst(EachNodeIt& v) const { G.getFirst(v); }
+
+ template< typename It >
+ It first() const {
+ It e;
+ getFirst(e);
+ return e;
+ }
+
+ template< typename It >
+ It first(const NodeIt v) const {
+ It e;
+ getFirst(e, v);
+ return e;
+ }
+
+ NodeIt tail(const EdgeIt e) const { return G.aNode(e.sym); }
+ NodeIt head(const EdgeIt e) const { return G.bNode(e.sym); }
+
+ NodeIt aNode(const OutEdgeIt e) const { return G.aNode(e.sym); }
+ NodeIt bNode(const OutEdgeIt e) const { return G.bNode(e.sym); }
+
+ int id(const NodeIt v) const { return G.id(v); }
+
+ template <typename ValueType>
+ class NodeMap {
+ //const ResGraph<Graph, T>& G;
+ typename Graph::NodeMap<ValueType> node_map;
+ public:
+ NodeMap(const ResGraph<Graph, T>& _G) : node_map(_G.G)/*: G(_G)*/ { }
+ NodeMap(const ResGraph<Graph, T>& _G, const ValueType a) : node_map(_G.G, a) /*: G(_G)*/ { }
+ void set(const NodeIt nit, const ValueType a) { node_map.set(nit, a); }
+ ValueType get(const NodeIt nit) const { return node_map.get(nit); }
+ };
+
+ };
+
+ template <typename Graph, typename T>
+ struct max_flow_type {
+ typedef typename Graph::NodeIt NodeIt;
+ typedef typename Graph::EdgeIt EdgeIt;
+ typedef typename Graph::EachEdgeIt EachEdgeIt;
+ typedef typename Graph::OutEdgeIt OutEdgeIt;
+ typedef typename Graph::InEdgeIt InEdgeIt;
+ const Graph& G;
+ NodeIt s;
+ NodeIt t;
+ typename Graph::EdgeMap<T> flow;
+ const typename Graph::EdgeMap<T>& capacity;
+
+ max_flow_type(const Graph& _G, NodeIt _s, NodeIt _t, const typename Graph::EdgeMap<T>& _capacity) : G(_G), s(_s), t(_t), flow(_G, 0), capacity(_capacity) { }
+ void run() {
+ typedef ResGraph<Graph, T> AugGraph;
+ AugGraph res_graph(G, flow, capacity);
+
+ bool augment;
+ do {
+ augment=false;
+
+ typedef typename AugGraph::OutEdgeIt AugOutEdgeIt;
+ typedef typename AugGraph::EdgeIt AugEdgeIt;
+ typedef std::queue<AugOutEdgeIt> BfsQueue;
+ BfsQueue bfs_queue;
+ bfs_queue.push(res_graph.template first<AugOutEdgeIt>(s));
+
+ typedef typename AugGraph::NodeMap<bool> ReachedMap;
+ ReachedMap reached(res_graph, false);
+ reached.set(s, true);
+
+ bfs_iterator1< AugGraph, ReachedMap >
+ res_bfs(res_graph, bfs_queue, reached);
+
+ typedef typename AugGraph::NodeMap<AugEdgeIt> PredMap;
+ PredMap pred(res_graph);
+ //typename AugGraph::EdgeIt a; //invalid
+ //a.makeInvalid();
+ //pred.set(s, a);
+
+ typedef typename AugGraph::NodeMap<int> FreeMap;
+ FreeMap free(res_graph);
+
+ //searching for augmenting path
+ while ( res_bfs.valid() ) {
+ //std::cout<<"KULSO ciklus itt jar: "<<G.id(res_graph.tail(res_bfs))<<"->"<<G.id(res_graph.head(res_bfs))<<std::endl;
+ if (res_bfs.newly_reached()) {
+ AugOutEdgeIt e=AugOutEdgeIt(res_bfs);
+ NodeIt v=res_graph.tail(e);
+ NodeIt w=res_graph.head(e);
+ //std::cout<<G.id(v)<<"->"<<G.id(w)<<", "<<G.id(w)<<" is newly reached";
+ pred.set(w, e);
+ if (pred.get(v).valid()) {
+ free.set(w, std::min(free.get(v), e.free()));
+ //std::cout <<" nem elso csucs: ";
+ //std::cout <<"szabad kap eddig: "<< free.get(w) << " ";
+ } else {
+ free.set(w, e.free());
+ //std::cout <<" elso csucs: ";
+ //std::cout <<"szabad kap eddig: "<< free.get(w) << " ";
+ }
+ //std::cout<<std::endl;
+ }
+
+ if (res_graph.head(res_bfs)==t) break;
+ ++res_bfs;
+ } //end searching augmenting path
+ if (reached.get(t)) {
+ augment=true;
+ NodeIt n=t;
+ T augment_value=free.get(t);
+ std::cout<<"augmentation: ";
+ while (pred.get(n).valid()) {
+ AugEdgeIt e=pred.get(n);
+ e.augment(augment_value);
+ std::cout<<"("<<res_graph.tail(e)<< "->"<<res_graph.head(e)<<") ";
+ n=res_graph.tail(e);
+ }
+ std::cout<<std::endl;
+ }
+
+ std::cout << "actual flow: "<< std::endl;
+ for(EachEdgeIt e=G.template first<EachEdgeIt>(); e.valid(); ++e) {
+ std::cout<<"("<<G.tail(e)<< "-"<<flow.get(e)<<"->"<<G.head(e)<<") ";
+ }
+ std::cout<<std::endl;
+
+ } while (augment);
+ }
+ };
+
+} // namespace marci
+
+#endif //MARCI_MAX_FLOW_HH
More information about the Lemon-commits
mailing list