[Lemon-commits] [lemon_svn] marci: r629 - in hugo/trunk/src/work: jacint marci
Lemon SVN
svn at lemon.cs.elte.hu
Mon Nov 6 20:40:39 CET 2006
Author: marci
Date: Thu Apr 29 17:58:34 2004
New Revision: 629
Modified:
hugo/trunk/src/work/jacint/preflow.h
hugo/trunk/src/work/marci/edmonds_karp_demo.cc
Log:
preflow, maxflow
Modified: hugo/trunk/src/work/jacint/preflow.h
==============================================================================
--- hugo/trunk/src/work/jacint/preflow.h (original)
+++ hugo/trunk/src/work/jacint/preflow.h Thu Apr 29 17:58:34 2004
@@ -44,6 +44,11 @@
#include <stack>
#include <graph_wrapper.h>
+#include <bfs_iterator.h>
+#include <invalid.h>
+#include <maps.h>
+#include <for_each_macros.h>
+
namespace hugo {
@@ -111,9 +116,14 @@
bool augmentOnBlockingFlow2();
- //Returns the maximum value of a flow.
- Num flowValue() {
- return excess[t];
+ /// Returns the actual flow value.
+ /// More precisely, it returns the negative excess of s, thus
+ /// this works also for preflows.
+ Num flowValue() {
+ Num a=0;
+ FOR_EACH_INC_LOC(OutEdgeIt, e, *g, s) a+=(*flow)[e];
+ FOR_EACH_INC_LOC(InEdgeIt, e, *g, s) a-=(*flow)[e];
+ return a;
}
//should be used only between preflowPhase0 and preflowPhase1
@@ -433,7 +443,8 @@
void relabel(Node w, int newlevel, VecStack& active,
VecNode& level_list, NNMap& left,
- NNMap& right, int& b, int& k, bool what_heur ) {
+ NNMap& right, int& b, int& k, bool what_heur )
+ {
Num lev=level[w];
@@ -497,6 +508,28 @@
}
} //relabel
+
+
+ template<typename MapGraphWrapper>
+ class DistanceMap {
+ protected:
+ const MapGraphWrapper* g;
+ typename MapGraphWrapper::template NodeMap<int> dist;
+ public:
+ DistanceMap(MapGraphWrapper& _g) : g(&_g), dist(*g, g->nodeNum()) { }
+ void set(const typename MapGraphWrapper::Node& n, int a) {
+ dist.set(n, a);
+ }
+ int operator[](const typename MapGraphWrapper::Node& n)
+ { return dist[n]; }
+// int get(const typename MapGraphWrapper::Node& n) const {
+// return dist[n]; }
+// bool get(const typename MapGraphWrapper::Edge& e) const {
+// return (dist.get(g->tail(e))<dist.get(g->head(e))); }
+ bool operator[](const typename MapGraphWrapper::Edge& e) const {
+ return (dist[g->tail(e)]<dist[g->head(e)]);
+ }
+ };
};
@@ -674,7 +707,52 @@
+ template <typename Graph, typename Num, typename CapMap, typename FlowMap>
+ bool Preflow<Graph, Num, CapMap, FlowMap>::augmentOnShortestPath()
+ {
+ ResGW res_graph(*g, *capacity, *flow);
+ bool _augment=false;
+
+ //ReachedMap level(res_graph);
+ FOR_EACH_LOC(typename Graph::NodeIt, e, *g) level.set(e, 0);
+ BfsIterator<ResGW, ReachedMap> bfs(res_graph, level);
+ bfs.pushAndSetReached(s);
+
+ typename ResGW::template NodeMap<ResGWEdge> pred(res_graph);
+ pred.set(s, INVALID);
+
+ typename ResGW::template NodeMap<Num> free(res_graph);
+
+ //searching for augmenting path
+ while ( !bfs.finished() ) {
+ ResGWOutEdgeIt e=bfs;
+ if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
+ Node v=res_graph.tail(e);
+ Node w=res_graph.head(e);
+ pred.set(w, e);
+ if (res_graph.valid(pred[v])) {
+ free.set(w, std::min(free[v], res_graph.resCap(e)));
+ } else {
+ free.set(w, res_graph.resCap(e));
+ }
+ if (res_graph.head(e)==t) { _augment=true; break; }
+ }
+
+ ++bfs;
+ } //end of searching augmenting path
+
+ if (_augment) {
+ Node n=t;
+ Num augment_value=free[t];
+ while (res_graph.valid(pred[n])) {
+ ResGWEdge e=pred[n];
+ res_graph.augment(e, augment_value);
+ n=res_graph.tail(e);
+ }
+ }
+ return _augment;
+ }
@@ -683,6 +761,252 @@
+
+ template <typename Graph, typename Num, typename CapMap, typename FlowMap>
+ template<typename MutableGraph>
+ bool Preflow<Graph, Num, CapMap, FlowMap>::augmentOnBlockingFlow()
+ {
+ typedef MutableGraph MG;
+ bool _augment=false;
+
+ ResGW res_graph(*g, *capacity, *flow);
+
+ //bfs for distances on the residual graph
+ //ReachedMap level(res_graph);
+ FOR_EACH_LOC(typename Graph::NodeIt, e, *g) level.set(e, 0);
+ BfsIterator<ResGW, ReachedMap> bfs(res_graph, level);
+ bfs.pushAndSetReached(s);
+ typename ResGW::template NodeMap<int>
+ dist(res_graph); //filled up with 0's
+
+ //F will contain the physical copy of the residual graph
+ //with the set of edges which are on shortest paths
+ MG F;
+ typename ResGW::template NodeMap<typename MG::Node>
+ res_graph_to_F(res_graph);
+ {
+ typename ResGW::NodeIt n;
+ for(res_graph.first(n); res_graph.valid(n); res_graph.next(n)) {
+ res_graph_to_F.set(n, F.addNode());
+ }
+ }
+
+ typename MG::Node sF=res_graph_to_F[s];
+ typename MG::Node tF=res_graph_to_F[t];
+ typename MG::template EdgeMap<ResGWEdge> original_edge(F);
+ typename MG::template EdgeMap<Num> residual_capacity(F);
+
+ while ( !bfs.finished() ) {
+ ResGWOutEdgeIt e=bfs;
+ if (res_graph.valid(e)) {
+ if (bfs.isBNodeNewlyReached()) {
+ dist.set(res_graph.head(e), dist[res_graph.tail(e)]+1);
+ typename MG::Edge f=F.addEdge(res_graph_to_F[res_graph.tail(e)], res_graph_to_F[res_graph.head(e)]);
+ original_edge.update();
+ original_edge.set(f, e);
+ residual_capacity.update();
+ residual_capacity.set(f, res_graph.resCap(e));
+ } else {
+ if (dist[res_graph.head(e)]==(dist[res_graph.tail(e)]+1)) {
+ typename MG::Edge f=F.addEdge(res_graph_to_F[res_graph.tail(e)], res_graph_to_F[res_graph.head(e)]);
+ original_edge.update();
+ original_edge.set(f, e);
+ residual_capacity.update();
+ residual_capacity.set(f, res_graph.resCap(e));
+ }
+ }
+ }
+ ++bfs;
+ } //computing distances from s in the residual graph
+
+ bool __augment=true;
+
+ while (__augment) {
+ __augment=false;
+ //computing blocking flow with dfs
+ DfsIterator< MG, typename MG::template NodeMap<bool> > dfs(F);
+ typename MG::template NodeMap<typename MG::Edge> pred(F);
+ pred.set(sF, INVALID);
+ //invalid iterators for sources
+
+ typename MG::template NodeMap<Num> free(F);
+
+ dfs.pushAndSetReached(sF);
+ while (!dfs.finished()) {
+ ++dfs;
+ if (F.valid(/*typename MG::OutEdgeIt*/(dfs))) {
+ if (dfs.isBNodeNewlyReached()) {
+ typename MG::Node v=F.aNode(dfs);
+ typename MG::Node w=F.bNode(dfs);
+ pred.set(w, dfs);
+ if (F.valid(pred[v])) {
+ free.set(w, std::min(free[v], residual_capacity[dfs]));
+ } else {
+ free.set(w, residual_capacity[dfs]);
+ }
+ if (w==tF) {
+ __augment=true;
+ _augment=true;
+ break;
+ }
+
+ } else {
+ F.erase(/*typename MG::OutEdgeIt*/(dfs));
+ }
+ }
+ }
+
+ if (__augment) {
+ typename MG::Node n=tF;
+ Num augment_value=free[tF];
+ while (F.valid(pred[n])) {
+ typename MG::Edge e=pred[n];
+ res_graph.augment(original_edge[e], augment_value);
+ n=F.tail(e);
+ if (residual_capacity[e]==augment_value)
+ F.erase(e);
+ else
+ residual_capacity.set(e, residual_capacity[e]-augment_value);
+ }
+ }
+
+ }
+
+ return _augment;
+ }
+
+
+
+
+
+
+ template <typename Graph, typename Num, typename CapMap, typename FlowMap>
+ bool Preflow<Graph, Num, CapMap, FlowMap>::augmentOnBlockingFlow2()
+ {
+ bool _augment=false;
+
+ ResGW res_graph(*g, *capacity, *flow);
+
+ //ReachedMap level(res_graph);
+ FOR_EACH_LOC(typename Graph::NodeIt, e, *g) level.set(e, 0);
+ BfsIterator<ResGW, ReachedMap> bfs(res_graph, level);
+
+ bfs.pushAndSetReached(s);
+ DistanceMap<ResGW> dist(res_graph);
+ while ( !bfs.finished() ) {
+ ResGWOutEdgeIt e=bfs;
+ if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
+ dist.set(res_graph.head(e), dist[res_graph.tail(e)]+1);
+ }
+ ++bfs;
+ } //computing distances from s in the residual graph
+
+ //Subgraph containing the edges on some shortest paths
+ ConstMap<typename ResGW::Node, bool> true_map(true);
+ typedef SubGraphWrapper<ResGW, ConstMap<typename ResGW::Node, bool>,
+ DistanceMap<ResGW> > FilterResGW;
+ FilterResGW filter_res_graph(res_graph, true_map, dist);
+
+ //Subgraph, which is able to delete edges which are already
+ //met by the dfs
+ typename FilterResGW::template NodeMap<typename FilterResGW::OutEdgeIt>
+ first_out_edges(filter_res_graph);
+ typename FilterResGW::NodeIt v;
+ for(filter_res_graph.first(v); filter_res_graph.valid(v);
+ filter_res_graph.next(v))
+ {
+ typename FilterResGW::OutEdgeIt e;
+ filter_res_graph.first(e, v);
+ first_out_edges.set(v, e);
+ }
+ typedef ErasingFirstGraphWrapper<FilterResGW, typename FilterResGW::
+ template NodeMap<typename FilterResGW::OutEdgeIt> > ErasingResGW;
+ ErasingResGW erasing_res_graph(filter_res_graph, first_out_edges);
+
+ bool __augment=true;
+
+ while (__augment) {
+
+ __augment=false;
+ //computing blocking flow with dfs
+ DfsIterator< ErasingResGW,
+ typename ErasingResGW::template NodeMap<bool> >
+ dfs(erasing_res_graph);
+ typename ErasingResGW::
+ template NodeMap<typename ErasingResGW::OutEdgeIt>
+ pred(erasing_res_graph);
+ pred.set(s, INVALID);
+ //invalid iterators for sources
+
+ typename ErasingResGW::template NodeMap<Num>
+ free1(erasing_res_graph);
+
+ dfs.pushAndSetReached(
+ typename ErasingResGW::Node(
+ typename FilterResGW::Node(
+ typename ResGW::Node(s)
+ )
+ )
+ );
+ while (!dfs.finished()) {
+ ++dfs;
+ if (erasing_res_graph.valid(
+ typename ErasingResGW::OutEdgeIt(dfs)))
+ {
+ if (dfs.isBNodeNewlyReached()) {
+
+ typename ErasingResGW::Node v=erasing_res_graph.aNode(dfs);
+ typename ErasingResGW::Node w=erasing_res_graph.bNode(dfs);
+
+ pred.set(w, /*typename ErasingResGW::OutEdgeIt*/(dfs));
+ if (erasing_res_graph.valid(pred[v])) {
+ free1.set(w, std::min(free1[v], res_graph.resCap(
+ typename ErasingResGW::OutEdgeIt(dfs))));
+ } else {
+ free1.set(w, res_graph.resCap(
+ typename ErasingResGW::OutEdgeIt(dfs)));
+ }
+
+ if (w==t) {
+ __augment=true;
+ _augment=true;
+ break;
+ }
+ } else {
+ erasing_res_graph.erase(dfs);
+ }
+ }
+ }
+
+ if (__augment) {
+ typename ErasingResGW::Node n=typename FilterResGW::Node(typename ResGW::Node(t));
+// typename ResGW::NodeMap<Num> a(res_graph);
+// typename ResGW::Node b;
+// Num j=a[b];
+// typename FilterResGW::NodeMap<Num> a1(filter_res_graph);
+// typename FilterResGW::Node b1;
+// Num j1=a1[b1];
+// typename ErasingResGW::NodeMap<Num> a2(erasing_res_graph);
+// typename ErasingResGW::Node b2;
+// Num j2=a2[b2];
+ Num augment_value=free1[n];
+ while (erasing_res_graph.valid(pred[n])) {
+ typename ErasingResGW::OutEdgeIt e=pred[n];
+ res_graph.augment(e, augment_value);
+ n=erasing_res_graph.tail(e);
+ if (res_graph.resCap(e)==0)
+ erasing_res_graph.erase(e);
+ }
+ }
+
+ } //while (__augment)
+
+ return _augment;
+ }
+
+
+
+
} //namespace hugo
#endif //HUGO_PREFLOW_H
Modified: hugo/trunk/src/work/marci/edmonds_karp_demo.cc
==============================================================================
--- hugo/trunk/src/work/marci/edmonds_karp_demo.cc (original)
+++ hugo/trunk/src/work/marci/edmonds_karp_demo.cc Thu Apr 29 17:58:34 2004
@@ -5,11 +5,11 @@
#include <list_graph.h>
#include <smart_graph.h>
#include <dimacs.h>
-#include <edmonds_karp.h>
+//#include <edmonds_karp.h>
#include <time_measure.h>
//#include <graph_wrapper.h>
#include <preflow.h>
-#include <preflow_res.h>
+//#include <preflow_res.h>
#include <for_each_macros.h>
using namespace hugo;
@@ -72,12 +72,12 @@
Graph::EdgeMap<int> flow(G); //0 flow
Preflow<Graph, int, Graph::EdgeMap<int>, Graph::EdgeMap<int> >
pre_flow_test(G, s, t, cap, flow/*, true*/);
- Preflow<Graph, int, Graph::EdgeMap<int>, Graph::EdgeMap<int> >
- pre_flow_ize(G, s, t, cap, flow/*, false*/);
+ // Preflow<Graph, int, Graph::EdgeMap<int>, Graph::EdgeMap<int> >
+ // pre_flow_ize(G, s, t, cap, flow/*, false*/);
// PreflowRes<Graph, int, Graph::EdgeMap<int>, Graph::EdgeMap<int> >
// pre_flow_res(G, s, t, cap, flow/*, true*/);
- MaxFlow<Graph, int, Graph::EdgeMap<int>, Graph::EdgeMap<int> >
- max_flow_test(G, s, t, cap, flow);
+ //MaxFlow<Graph, int, Graph::EdgeMap<int>, Graph::EdgeMap<int> >
+ // max_flow_test(G, s, t, cap, flow);
{
std::cout << "preflow ..." << std::endl;
@@ -91,9 +91,9 @@
std::cout << "preflow ..." << std::endl;
FOR_EACH_LOC(Graph::EdgeIt, e, G) flow.set(e, 0);
ts.reset();
- pre_flow_ize.preflow(Preflow<Graph, int, Graph::EdgeMap<int>, Graph::EdgeMap<int> >::GEN_FLOW);
+ pre_flow_test.preflow(Preflow<Graph, int, Graph::EdgeMap<int>, Graph::EdgeMap<int> >::GEN_FLOW);
std::cout << "elapsed time: " << ts << std::endl;
- std::cout << "flow value: "<< pre_flow_ize.flowValue() << std::endl;
+ std::cout << "flow value: "<< pre_flow_test.flowValue() << std::endl;
}
// {
@@ -110,32 +110,32 @@
FOR_EACH_LOC(Graph::EdgeIt, e, G) flow.set(e, 0);
ts.reset();
int i=0;
- while (max_flow_test.augmentOnBlockingFlow<MutableGraph>()) { ++i; }
+ while (pre_flow_test.augmentOnBlockingFlow<MutableGraph>()) { ++i; }
std::cout << "elapsed time: " << ts << std::endl;
std::cout << "number of augmentation phases: " << i << std::endl;
- std::cout << "flow value: "<< max_flow_test.flowValue() << std::endl;
+ std::cout << "flow value: "<< pre_flow_test.flowValue() << std::endl;
}
- {
- std::cout << "faster physical blocking flow augmentation ..." << std::endl;
- FOR_EACH_LOC(Graph::EdgeIt, e, G) flow.set(e, 0);
- ts.reset();
- int i=0;
- while (max_flow_test.augmentOnBlockingFlow1<MutableGraph>()) { ++i; }
- std::cout << "elapsed time: " << ts << std::endl;
- std::cout << "number of augmentation phases: " << i << std::endl;
- std::cout << "flow value: "<< max_flow_test.flowValue() << std::endl;
- }
+// {
+// std::cout << "faster physical blocking flow augmentation ..." << std::endl;
+// FOR_EACH_LOC(Graph::EdgeIt, e, G) flow.set(e, 0);
+// ts.reset();
+// int i=0;
+// while (max_flow_test.augmentOnBlockingFlow1<MutableGraph>()) { ++i; }
+// std::cout << "elapsed time: " << ts << std::endl;
+// std::cout << "number of augmentation phases: " << i << std::endl;
+// std::cout << "flow value: "<< max_flow_test.flowValue() << std::endl;
+// }
{
std::cout << "on-the-fly blocking flow augmentation ..." << std::endl;
FOR_EACH_LOC(Graph::EdgeIt, e, G) flow.set(e, 0);
ts.reset();
int i=0;
- while (max_flow_test.augmentOnBlockingFlow2()) { ++i; }
+ while (pre_flow_test.augmentOnBlockingFlow2()) { ++i; }
std::cout << "elapsed time: " << ts << std::endl;
std::cout << "number of augmentation phases: " << i << std::endl;
- std::cout << "flow value: "<< max_flow_test.flowValue() << std::endl;
+ std::cout << "flow value: "<< pre_flow_test.flowValue() << std::endl;
}
{
@@ -143,10 +143,10 @@
FOR_EACH_LOC(Graph::EdgeIt, e, G) flow.set(e, 0);
ts.reset();
int i=0;
- while (max_flow_test.augmentOnShortestPath()) { ++i; }
+ while (pre_flow_test.augmentOnShortestPath()) { ++i; }
std::cout << "elapsed time: " << ts << std::endl;
std::cout << "number of augmentation phases: " << i << std::endl;
- std::cout << "flow value: "<< max_flow_test.flowValue() << std::endl;
+ std::cout << "flow value: "<< pre_flow_test.flowValue() << std::endl;
}
More information about the Lemon-commits
mailing list