src/work/edmonds_karp.hh
author marci
Fri, 06 Feb 2004 11:45:47 +0000
changeset 67 5f86199dcf3e
parent 59 41c7f9c09a12
child 69 24c2c2989e0f
permissions -rw-r--r--
.
marci@59
     1
#ifndef EDMONDS_KARP_HH
marci@59
     2
#define EDMONDS_KARP_HH
marci@43
     3
marci@43
     4
#include <algorithm>
marci@43
     5
marci@43
     6
#include <bfs_iterator.hh>
marci@43
     7
marci@43
     8
namespace marci {
marci@43
     9
marci@59
    10
  template<typename Graph, typename T, typename FlowMap, typename CapacityMap>
marci@43
    11
  class ResGraph {
marci@43
    12
    typedef typename Graph::NodeIt NodeIt;
marci@43
    13
    typedef typename Graph::EachNodeIt EachNodeIt;
marci@43
    14
    typedef typename Graph::SymEdgeIt OldSymEdgeIt;
marci@43
    15
    const Graph& G;
marci@59
    16
    FlowMap& flow;
marci@59
    17
    const CapacityMap& capacity;
marci@43
    18
  public:
marci@59
    19
    ResGraph(const Graph& _G, FlowMap& _flow, 
marci@59
    20
	     const CapacityMap& _capacity) : 
marci@43
    21
      G(_G), flow(_flow), capacity(_capacity) { }
marci@43
    22
marci@43
    23
    class EdgeIt; 
marci@43
    24
    class OutEdgeIt; 
marci@43
    25
    friend class EdgeIt; 
marci@43
    26
    friend class OutEdgeIt; 
marci@43
    27
marci@43
    28
    class EdgeIt {
marci@59
    29
      friend class ResGraph<Graph, T, FlowMap, CapacityMap>;
marci@43
    30
    protected:
marci@59
    31
      const ResGraph<Graph, T, FlowMap, CapacityMap>* resG;
marci@43
    32
      OldSymEdgeIt sym;
marci@43
    33
    public:
marci@43
    34
      EdgeIt() { } 
marci@43
    35
      //EdgeIt(const EdgeIt& e) : resG(e.resG), sym(e.sym) { }
marci@43
    36
      T free() const { 
marci@43
    37
	if (resG->G.aNode(sym)==resG->G.tail(sym)) { 
marci@43
    38
	  return (resG->capacity.get(sym)-resG->flow.get(sym)); 
marci@43
    39
	} else { 
marci@43
    40
	  return (resG->flow.get(sym)); 
marci@43
    41
	}
marci@43
    42
      }
marci@43
    43
      bool valid() const { return sym.valid(); }
marci@64
    44
      void augment(T a) const {
marci@43
    45
	if (resG->G.aNode(sym)==resG->G.tail(sym)) { 
marci@43
    46
	  resG->flow.set(sym, resG->flow.get(sym)+a);
marci@43
    47
	} else { 
marci@43
    48
	  resG->flow.set(sym, resG->flow.get(sym)-a);
marci@43
    49
	}
marci@43
    50
      }
marci@43
    51
    };
marci@43
    52
marci@43
    53
    class OutEdgeIt : public EdgeIt {
marci@59
    54
      friend class ResGraph<Graph, T, FlowMap, CapacityMap>;
marci@43
    55
    public:
marci@43
    56
      OutEdgeIt() { }
marci@43
    57
      //OutEdgeIt(const OutEdgeIt& e) { resG=e.resG; sym=e.sym; }
marci@43
    58
    private:
marci@64
    59
      OutEdgeIt(const ResGraph<Graph, T, FlowMap, CapacityMap>& _resG, NodeIt v) { 
marci@43
    60
      	resG=&_resG;
marci@43
    61
	sym=resG->G.template first<OldSymEdgeIt>(v);
marci@43
    62
	while( sym.valid() && !(free()>0) ) { ++sym; }
marci@43
    63
      }
marci@43
    64
    public:
marci@43
    65
      OutEdgeIt& operator++() { 
marci@43
    66
	++sym; 
marci@43
    67
	while( sym.valid() && !(free()>0) ) { ++sym; }
marci@43
    68
	return *this; 
marci@43
    69
      }
marci@43
    70
    };
marci@43
    71
marci@64
    72
    void getFirst(OutEdgeIt& e, NodeIt v) const { 
marci@43
    73
      e=OutEdgeIt(*this, v); 
marci@43
    74
    }
marci@43
    75
    void getFirst(EachNodeIt& v) const { G.getFirst(v); }
marci@43
    76
    
marci@43
    77
    template< typename It >
marci@43
    78
    It first() const { 
marci@43
    79
      It e;
marci@43
    80
      getFirst(e);
marci@43
    81
      return e; 
marci@43
    82
    }
marci@43
    83
marci@43
    84
    template< typename It >
marci@64
    85
    It first(NodeIt v) const { 
marci@43
    86
      It e;
marci@43
    87
      getFirst(e, v);
marci@43
    88
      return e; 
marci@43
    89
    }
marci@43
    90
marci@64
    91
    NodeIt tail(EdgeIt e) const { return G.aNode(e.sym); }
marci@64
    92
    NodeIt head(EdgeIt e) const { return G.bNode(e.sym); }
marci@43
    93
marci@64
    94
    NodeIt aNode(OutEdgeIt e) const { return G.aNode(e.sym); }
marci@64
    95
    NodeIt bNode(OutEdgeIt e) const { return G.bNode(e.sym); }
marci@43
    96
marci@64
    97
    int id(NodeIt v) const { return G.id(v); }
marci@43
    98
marci@43
    99
    template <typename ValueType>
marci@43
   100
    class NodeMap {
marci@43
   101
      typename Graph::NodeMap<ValueType> node_map; 
marci@43
   102
    public:
marci@59
   103
      NodeMap(const ResGraph<Graph, T, FlowMap, CapacityMap>& _G) : node_map(_G.G) { }
marci@64
   104
      NodeMap(const ResGraph<Graph, T, FlowMap, CapacityMap>& _G, ValueType a) : node_map(_G.G, a) { }
marci@64
   105
      void set(NodeIt nit, ValueType a) { node_map.set(nit, a); }
marci@64
   106
      ValueType get(NodeIt nit) const { return node_map.get(nit); }
marci@43
   107
    };
marci@43
   108
marci@43
   109
  };
marci@43
   110
marci@59
   111
  template <typename Graph, typename T, typename FlowMap, typename CapacityMap>
marci@59
   112
  class MaxFlow {
marci@43
   113
    typedef typename Graph::NodeIt NodeIt;
marci@43
   114
    typedef typename Graph::EdgeIt EdgeIt;
marci@43
   115
    typedef typename Graph::EachEdgeIt EachEdgeIt;
marci@43
   116
    typedef typename Graph::OutEdgeIt OutEdgeIt;
marci@43
   117
    typedef typename Graph::InEdgeIt InEdgeIt;
marci@43
   118
    const Graph& G;
marci@64
   119
    NodeIt s;
marci@64
   120
    NodeIt t;
marci@59
   121
    FlowMap& flow;
marci@59
   122
    const CapacityMap& capacity;
marci@59
   123
    typedef ResGraph<Graph, T, FlowMap, CapacityMap > AugGraph;
marci@59
   124
    typedef typename AugGraph::OutEdgeIt AugOutEdgeIt;
marci@59
   125
    typedef typename AugGraph::EdgeIt AugEdgeIt;
marci@59
   126
  public:
marci@64
   127
    MaxFlow(const Graph& _G, NodeIt _s, NodeIt _t, FlowMap& _flow, const CapacityMap& _capacity) : G(_G), s(_s), t(_t), flow(_flow), capacity(_capacity) { }
marci@59
   128
    bool augment() {
marci@59
   129
      AugGraph res_graph(G, flow, capacity);
marci@59
   130
      bool _augment=false;
marci@59
   131
      
marci@59
   132
      typedef typename AugGraph::NodeMap<bool> ReachedMap;
marci@59
   133
      BfsIterator2< AugGraph, AugOutEdgeIt, ReachedMap > res_bfs(res_graph);
marci@59
   134
      res_bfs.pushAndSetReached(s);
marci@59
   135
	
marci@59
   136
      typename AugGraph::NodeMap<AugEdgeIt> pred(res_graph); 
marci@59
   137
      //filled with invalid iterators
marci@59
   138
      
marci@59
   139
      typename AugGraph::NodeMap<int> free(res_graph);
marci@59
   140
	
marci@59
   141
      //searching for augmenting path
marci@59
   142
      while ( !res_bfs.finished() ) { 
marci@59
   143
	//std::queue<AugOutEdgeIt> bfs_copy(res_bfs.getBfsQueue());
marci@59
   144
	//while (!bfs_copy.empty()) {
marci@59
   145
	//  AugOutEdgeIt e=bfs_copy.front();
marci@59
   146
	//  bfs_copy.pop();
marci@59
   147
	//  if (e.valid()) {
marci@59
   148
	//    std::cout<<"queue:"<<res_graph.tail(e)<<"->"<<res_graph.head(e)<<" ";
marci@59
   149
	//  } else {
marci@59
   150
	//    std::cout<<"queue:"<<res_graph.aNode(e)<<"->"<<" ";
marci@59
   151
	//  }
marci@59
   152
	//}
marci@59
   153
	//std::cout<<std::endl;
marci@59
   154
	AugOutEdgeIt e=AugOutEdgeIt(res_bfs);
marci@59
   155
	//if (e.valid()) {
marci@59
   156
	//  std::cout<<"actual:"<<res_graph.tail(e)<<"->"<<res_graph.head(e)<<std::endl;
marci@59
   157
	//} else {
marci@59
   158
	//  std::cout<<"actual:"<<res_graph.aNode(e)<<"->"<<std::endl;
marci@59
   159
	//}
marci@59
   160
	if (e.valid() && res_bfs.isBNodeNewlyReached()) {
marci@59
   161
	  NodeIt v=res_graph.tail(e);
marci@59
   162
	  NodeIt w=res_graph.head(e);
marci@59
   163
	  //std::cout<<v<<"->"<<w<<std::endl;
marci@59
   164
	  pred.set(w, e);
marci@59
   165
	  if (pred.get(v).valid()) {
marci@59
   166
	    free.set(w, std::min(free.get(v), e.free()));
marci@59
   167
	  } else {
marci@59
   168
	    free.set(w, e.free()); 
marci@59
   169
	  }
marci@59
   170
	  if (res_graph.head(e)==t) { _augment=true; break; }
marci@59
   171
	}
marci@59
   172
	
marci@59
   173
	++res_bfs;
marci@59
   174
      } //end of searching augmenting path
marci@43
   175
marci@59
   176
      if (_augment) {
marci@59
   177
	NodeIt n=t;
marci@59
   178
	T augment_value=free.get(t);
marci@59
   179
	//std::cout<<"augmentation: ";
marci@59
   180
	while (pred.get(n).valid()) { 
marci@59
   181
	  AugEdgeIt e=pred.get(n);
marci@59
   182
	  e.augment(augment_value); 
marci@59
   183
	  //std::cout<<"("<<res_graph.tail(e)<< "->"<<res_graph.head(e)<<") ";
marci@59
   184
	  n=res_graph.tail(e);
marci@59
   185
	}
marci@59
   186
	//std::cout<<std::endl;
marci@59
   187
      }
marci@59
   188
      //std::cout << "actual flow: "<< std::endl;
marci@59
   189
      //for(EachEdgeIt e=G.template first<EachEdgeIt>(); e.valid(); ++e) { 
marci@59
   190
      //std::cout<<"("<<G.tail(e)<< "-"<<flow.get(e)<<"->"<<G.head(e)<<") ";
marci@59
   191
      //}
marci@59
   192
      //std::cout<<std::endl;
marci@59
   193
marci@59
   194
      return _augment;
marci@59
   195
    }
marci@43
   196
    void run() {
marci@59
   197
      while (augment()) { } 
marci@43
   198
    }
marci@43
   199
  };
marci@43
   200
marci@43
   201
} // namespace marci
marci@43
   202
marci@59
   203
#endif //EDMONDS_KARP_HH