[Lemon-commits] [lemon_svn] marci: r180 - in hugo/trunk/src/work: . marci
Lemon SVN
svn at lemon.cs.elte.hu
Mon Nov 6 20:37:58 CET 2006
Author: marci
Date: Fri Feb 27 13:39:15 2004
New Revision: 180
Modified:
hugo/trunk/src/work/bfs_iterator.hh
hugo/trunk/src/work/edmonds_karp.hh
hugo/trunk/src/work/marci/edmonds_karp_demo.cc
hugo/trunk/src/work/marci_graph_demo.cc
Log:
Dinits blocking flow added to edmonds_karp_demo.hh.
Modified: hugo/trunk/src/work/bfs_iterator.hh
==============================================================================
--- hugo/trunk/src/work/bfs_iterator.hh (original)
+++ hugo/trunk/src/work/bfs_iterator.hh Fri Feb 27 13:39:15 2004
@@ -644,6 +644,7 @@
//}
}
void pushAndSetReached(NodeIt s) {
+ actual_node=s;
reached.set(s, true);
dfs_stack.push(G.template first<OutEdgeIt>(s));
}
@@ -659,6 +660,7 @@
reached.set(w, true);
b_node_newly_reached=true;
} else {
+ actual_node=G.aNode(actual_edge);
++(dfs_stack.top());
b_node_newly_reached=false;
}
@@ -672,7 +674,7 @@
operator OutEdgeIt () const { return actual_edge; }
bool isBNodeNewlyReached() const { return b_node_newly_reached; }
bool isANodeExamined() const { return !(actual_edge.valid()); }
- NodeIt aNode() const { return actual_node; }
+ NodeIt aNode() const { return actual_node; /*FIXME*/}
NodeIt bNode() const { return G.bNode(actual_edge); }
const ReachedMap& getReachedMap() const { return reached; }
const std::stack<OutEdgeIt>& getDfsStack() const { return dfs_stack; }
Modified: hugo/trunk/src/work/edmonds_karp.hh
==============================================================================
--- hugo/trunk/src/work/edmonds_karp.hh (original)
+++ hugo/trunk/src/work/edmonds_karp.hh Fri Feb 27 13:39:15 2004
@@ -6,7 +6,7 @@
#include <iterator>
#include <bfs_iterator.hh>
-#include <time_measure.h>
+//#include <time_measure.h>
namespace hugo {
@@ -281,6 +281,7 @@
bool out_or_in; //1, iff out
public:
EdgeIt() : out_or_in(1) { }
+ //EdgeIt(const EdgeIt& e) : G(e.G), flow(e.flow), capacity(e.capacity), out(e.out), in(e.in), out_or_in(e.out_or_in) { }
Number free() const {
if (out_or_in) {
return (/*resG->*/capacity->get(out)-/*resG->*/flow->get(out));
@@ -297,6 +298,23 @@
/*resG->*/flow->set(in, /*resG->*/flow->get(in)-a);
}
}
+ void print() {
+ if (out_or_in) {
+ std::cout << "out ";
+ if (out.valid())
+ std::cout << G->id(G->tail(out)) << "--"<< G->id(out) <<"->"<< G->id(G->head(out));
+ else
+ std::cout << "invalid";
+ }
+ else {
+ std::cout << "in ";
+ if (in.valid())
+ std::cout << G->id(G->head(in)) << "<-"<< G->id(in) <<"--"<< G->id(G->tail(in));
+ else
+ std::cout << "invalid";
+ }
+ std::cout << std::endl;
+ }
};
class OutEdgeIt : public EdgeIt {
@@ -308,11 +326,13 @@
G=&_G;
flow=&_flow;
capacity=&_capacity;
- out=/*resG->*/G->template first<OldOutEdgeIt>(v);
+ //out=/*resG->*/G->template first<OldOutEdgeIt>(v);
+ G->getFirst(out, v);
while( out.valid() && !(free()>0) ) { ++out; }
if (!out.valid()) {
out_or_in=0;
- in=/*resG->*/G->template first<OldInEdgeIt>(v);
+ //in=/*resG->*/G->template first<OldInEdgeIt>(v);
+ G->getFirst(in, v);
while( in.valid() && !(free()>0) ) { ++in; }
}
}
@@ -324,7 +344,7 @@
while( out.valid() && !(free()>0) ) { ++out; }
if (!out.valid()) {
out_or_in=0;
- in=/*resG->*/G->template first<OldInEdgeIt>(v);
+ G->getFirst(in, v); //=/*resG->*/G->template first<OldInEdgeIt>(v);
while( in.valid() && !(free()>0) ) { ++in; }
}
} else {
@@ -335,9 +355,75 @@
}
};
+ class EachEdgeIt : public EdgeIt {
+ typename Graph::EachNodeIt v;
+ public:
+ EachEdgeIt() { }
+ //EachEdgeIt(const EachEdgeIt& e) : EdgeIt(e), v(e.v) { }
+ EachEdgeIt(const Graph& _G, FlowMap& _flow, const CapacityMap& _capacity) {
+ G=&_G;
+ flow=&_flow;
+ capacity=&_capacity;
+ out_or_in=1;
+ G->getFirst(v);
+ if (v.valid()) G->getFirst(out, v); else out=OldOutEdgeIt();
+ while (out.valid() && !(free()>0) ) { ++out; }
+ while (v.valid() && !out.valid()) {
+ ++v;
+ if (v.valid()) G->getFirst(out, v);
+ while (out.valid() && !(free()>0) ) { ++out; }
+ }
+ if (!out.valid()) {
+ out_or_in=0;
+ G->getFirst(v);
+ if (v.valid()) G->getFirst(in, v); else in=OldInEdgeIt();
+ while (in.valid() && !(free()>0) ) { ++in; }
+ while (v.valid() && !in.valid()) {
+ ++v;
+ if (v.valid()) G->getFirst(in, v);
+ while (in.valid() && !(free()>0) ) { ++in; }
+ }
+ }
+ }
+ EachEdgeIt& operator++() {
+ if (out_or_in) {
+ ++out;
+ while (out.valid() && !(free()>0) ) { ++out; }
+ while (v.valid() && !out.valid()) {
+ ++v;
+ if (v.valid()) G->getFirst(out, v);
+ while (out.valid() && !(free()>0) ) { ++out; }
+ }
+ if (!out.valid()) {
+ out_or_in=0;
+ G->getFirst(v);
+ if (v.valid()) G->getFirst(in, v); else in=OldInEdgeIt();
+ while (in.valid() && !(free()>0) ) { ++in; }
+ while (v.valid() && !in.valid()) {
+ ++v;
+ if (v.valid()) G->getFirst(in, v);
+ while (in.valid() && !(free()>0) ) { ++in; }
+ }
+ }
+ } else {
+ ++in;
+ while (in.valid() && !(free()>0) ) { ++in; }
+ while (v.valid() && !in.valid()) {
+ ++v;
+ if (v.valid()) G->getFirst(in, v);
+ while (in.valid() && !(free()>0) ) { ++in; }
+ }
+ }
+ return *this;
+ }
+ };
+
void getFirst(OutEdgeIt& e, NodeIt v) const {
e=OutEdgeIt(G, v, flow, capacity);
}
+ void getFirst(EachEdgeIt& e) const {
+ e=EachEdgeIt(G, flow, capacity);
+ }
void getFirst(EachNodeIt& v) const { G.getFirst(v); }
template< typename It >
@@ -401,13 +487,13 @@
//AugGraph res_graph;
//typedef typename AugGraph::NodeMap<bool> ReachedMap;
//typename AugGraph::NodeMap<AugEdgeIt> pred;
- //typename AugGraph::NodeMap<int> free;
+ //typename AugGraph::NodeMap<Number> free;
public:
MaxFlow(const Graph& _G, NodeIt _s, NodeIt _t, FlowMap& _flow, const CapacityMap& _capacity) :
G(_G), s(_s), t(_t), flow(_flow), capacity(_capacity) //,
//res_graph(G, flow, capacity), pred(res_graph), free(res_graph)
{ }
- bool augment() {
+ bool augmentOnShortestPath() {
AugGraph res_graph(G, flow, capacity);
bool _augment=false;
@@ -419,7 +505,7 @@
//filled up with invalid iterators
//pred.set(s, AugEdgeIt());
- typename AugGraph::NodeMap<int> free(res_graph);
+ typename AugGraph::NodeMap<Number> free(res_graph);
//searching for augmenting path
while ( !res_bfs.finished() ) {
@@ -451,48 +537,130 @@
return _augment;
}
- bool augmentWithBlockingFlow() {
- BfsIterator4< Graph, OutEdgeIt, typename Graph::NodeMap<bool> > bfs(G);
+ template<typename MutableGraph> bool augmentOnBlockingFlow() {
+ bool _augment=false;
+
+ AugGraph res_graph(G, flow, capacity);
+
+ typedef typename AugGraph::NodeMap<bool> ReachedMap;
+ BfsIterator4< AugGraph, AugOutEdgeIt, ReachedMap > bfs(res_graph);
+
bfs.pushAndSetReached(s);
- typename Graph::NodeMap<int> dist(G); //filled up with 0's
+ typename AugGraph::NodeMap<int> dist(res_graph); //filled up with 0's
while ( !bfs.finished() ) {
- OutEdgeIt e=OutEdgeIt(bfs);
+ AugOutEdgeIt e=AugOutEdgeIt(bfs);
if (e.valid() && bfs.isBNodeNewlyReached()) {
- dist.set(G.head(e), dist.get(G.tail(e))+1);
- //NodeIt v=res_graph.tail(e);
- //NodeIt w=res_graph.head(e);
- //pred.set(w, e);
- //if (pred.get(v).valid()) {
- // free.set(w, std::min(free.get(v), e.free()));
- //} else {
- // free.set(w, e.free());
- //}
- //if (res_graph.head(e)==t) { _augment=true; break; }
+ dist.set(res_graph.head(e), dist.get(res_graph.tail(e))+1);
}
++bfs;
- } //end of searching augmenting path
+ } //computing distances from s in the residual graph
- double pre_time_copy=currTime();
- typedef Graph MutableGraph;
MutableGraph F;
- typename Graph::NodeMap<NodeIt> G_to_F(G);
- for(typename Graph::EachNodeIt n=G.template first<typename Graph::EachNodeIt>(); n.valid(); ++n) {
- G_to_F.set(n, F.addNode());
+ typename AugGraph::NodeMap<NodeIt> res_graph_to_F(res_graph);
+ for(typename AugGraph::EachNodeIt n=res_graph.template first<typename AugGraph::EachNodeIt>(); n.valid(); ++n) {
+ res_graph_to_F.set(n, F.addNode());
}
- for(typename Graph::EachEdgeIt e=G.template first<typename Graph::EachEdgeIt>(); e.valid(); ++e) {
- if (dist.get(G.head(e))==dist.get(G.tail(e))+1) {
- F.addEdge(G_to_F.get(G.tail(e)), G_to_F.get(G.head(e)));
+
+ typename MutableGraph::NodeIt sF=res_graph_to_F.get(s);
+ typename MutableGraph::NodeIt tF=res_graph_to_F.get(t);
+
+ typename MutableGraph::EdgeMap<AugEdgeIt> original_edge(F);
+ typename MutableGraph::EdgeMap<Number> free_on_edge(F);
+
+ //Making F to the graph containing the edges of the residual graph
+ //which are in some shortest paths
+ for(typename AugGraph::EachEdgeIt e=res_graph.template first<typename AugGraph::EachEdgeIt>(); e.valid(); ++e) {
+ if (dist.get(res_graph.head(e))==dist.get(res_graph.tail(e))+1) {
+ typename MutableGraph::EdgeIt f=F.addEdge(res_graph_to_F.get(res_graph.tail(e)), res_graph_to_F.get(res_graph.head(e)));
+ original_edge.update();
+ original_edge.set(f, e);
+ free_on_edge.update();
+ free_on_edge.set(f, e.free());
+ }
+ }
+
+ bool __augment=true;
+
+ while (__augment) {
+ __augment=false;
+ //computing blocking flow with dfs
+ typedef typename MutableGraph::NodeMap<bool> BlockingReachedMap;
+ DfsIterator4< MutableGraph, typename MutableGraph::OutEdgeIt, BlockingReachedMap > dfs(F);
+ typename MutableGraph::NodeMap<EdgeIt> pred(F); //invalid iterators
+ typename MutableGraph::NodeMap<Number> free(F);
+
+ dfs.pushAndSetReached(sF);
+ while (!dfs.finished()) {
+ ++dfs;
+ if (typename MutableGraph::OutEdgeIt(dfs).valid()) {
+ //std::cout << "OutEdgeIt: " << dfs;
+ //std::cout << " aNode: " << F.aNode(dfs);
+ //std::cout << " bNode: " << F.bNode(dfs) << " ";
+
+ typename MutableGraph::NodeIt v=F.aNode(dfs);
+ typename MutableGraph::NodeIt w=F.bNode(dfs);
+ pred.set(w, dfs);
+ if (pred.get(v).valid()) {
+ free.set(w, std::min(free.get(v), free_on_edge.get(dfs)));
+ } else {
+ free.set(w, free_on_edge.get(dfs)/*original_edge.get(dfs).free()*/);
+ }
+ if (w==tF) {
+ //std::cout << "AUGMENTATION"<<std::endl;
+ __augment=true;
+ _augment=true;
+ break;
+ }
+ } else {
+ //std::cout << "OutEdgeIt: " << "invalid";
+ //std::cout << " aNode: " << dfs.aNode();
+ //std::cout << " bNode: " << "invalid" << " ";
+ }
+ if (dfs.isBNodeNewlyReached()) {
+ //std::cout << "bNodeIsNewlyReached ";
+ } else {
+ //std::cout << "bNodeIsNotNewlyReached ";
+ if (typename MutableGraph::OutEdgeIt(dfs).valid()) {
+ //std::cout << "DELETE ";
+ F.erase(typename MutableGraph::OutEdgeIt(dfs));
+ }
+ }
+ //if (dfs.isANodeExamined()) {
+ //std::cout << "aNodeIsExamined ";
+ //} else {
+ //std::cout << "aNodeIsNotExamined ";
+ //}
+ //std::cout<<std::endl;
+ }
+
+ if (__augment) {
+ typename MutableGraph::NodeIt n=tF;
+ Number augment_value=free.get(tF);
+ while (pred.get(n).valid()) {
+ typename MutableGraph::EdgeIt e=pred.get(n);
+ original_edge.get(e).augment(augment_value);
+ n=F.tail(e);
+ F.erase(e);
+ }
}
- }
- double post_time_copy=currTime();
- std::cout << "copy time: " << post_time_copy-pre_time_copy << " sec"<< std::endl;
- return 0;
+ }
+
+ return _augment;
}
void run() {
//int num_of_augmentations=0;
- while (augment()) {
+ while (augmentOnShortestPath()) {
+ //while (augmentOnBlockingFlow<MutableGraph>()) {
+ //std::cout << ++num_of_augmentations << " ";
+ //std::cout<<std::endl;
+ }
+ }
+ template<typename MutableGraph> void run() {
+ //int num_of_augmentations=0;
+ //while (augmentOnShortestPath()) {
+ while (augmentOnBlockingFlow<MutableGraph>()) {
//std::cout << ++num_of_augmentations << " ";
//std::cout<<std::endl;
}
@@ -599,7 +767,7 @@
typename AugGraph::NodeMap<AugEdgeIt> pred(res_graph);
//filled up with invalid iterators
- typename AugGraph::NodeMap<int> free(res_graph);
+ typename AugGraph::NodeMap<Number> free(res_graph);
//searching for augmenting path
while ( !res_bfs.finished() ) {
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 Fri Feb 27 13:39:15 2004
@@ -19,29 +19,35 @@
ListGraph::EdgeMap<int> cap(G);
readDimacsMaxFlow(std::cin, G, s, t, cap);
-/*
- double pre_time_copy=currTime();
- ListGraph F;
- ListGraph::NodeMap<NodeIt> G_to_F(G);
- typedef ListGraph::EachNodeIt EachNodeIt;
- for(EachNodeIt n=G.first<EachNodeIt>(); n.valid(); ++n) {
- G_to_F.set(n, F.addNode());
- }
- for(EachEdgeIt e=G.first<EachEdgeIt>(); e.valid(); ++e) {
- F.addEdge(G_to_F.get(G.tail(e)), G_to_F.get(G.head(e)));
+ {
+ std::cout << "edmonds karp demo (blocking flow augmentation)..." << std::endl;
+ ListGraph::EdgeMap<int> flow(G); //0 flow
+
+ double pre_time=currTime();
+ MaxFlow<ListGraph, int, ListGraph::EdgeMap<int>, ListGraph::EdgeMap<int> > max_flow_test(G, s, t, flow, cap);
+ //max_flow_test.augmentWithBlockingFlow<ListGraph>();
+ max_flow_test.run<ListGraph>();
+ double post_time=currTime();
+
+ //std::cout << "maximum flow: "<< std::endl;
+ //for(EachEdgeIt e=G.first<EachEdgeIt>(); e.valid(); ++e) {
+ // std::cout<<"("<<G.tail(e)<< "-"<<flow.get(e)<<"->"<<G.head(e)<<") ";
+ //}
+ //std::cout<<std::endl;
+ std::cout << "elapsed time: " << post_time-pre_time << " sec"<< std::endl;
+ std::cout << "flow value: "<< max_flow_test.flowValue() << std::endl;
}
- double post_time_copy=currTime();
- std::cout << "copy time: " << post_time_copy-pre_time_copy << " sec"<< std::endl;
-*/
- std::cout << "edmonds karp demo..." << std::endl;
+ {
+ std::cout << "edmonds karp demo (shortest path augmentation)..." << std::endl;
ListGraph::EdgeMap<int> flow(G); //0 flow
double pre_time=currTime();
MaxFlow<ListGraph, int, ListGraph::EdgeMap<int>, ListGraph::EdgeMap<int> > max_flow_test(G, s, t, flow, cap);
- max_flow_test.augmentWithBlockingFlow();
+ //max_flow_test.augmentWithBlockingFlow<ListGraph>();
max_flow_test.run();
double post_time=currTime();
+
//std::cout << "maximum flow: "<< std::endl;
//for(EachEdgeIt e=G.first<EachEdgeIt>(); e.valid(); ++e) {
// std::cout<<"("<<G.tail(e)<< "-"<<flow.get(e)<<"->"<<G.head(e)<<") ";
@@ -49,6 +55,7 @@
//std::cout<<std::endl;
std::cout << "elapsed time: " << post_time-pre_time << " sec"<< std::endl;
std::cout << "flow value: "<< max_flow_test.flowValue() << std::endl;
+ }
return 0;
}
Modified: hugo/trunk/src/work/marci_graph_demo.cc
==============================================================================
--- hugo/trunk/src/work/marci_graph_demo.cc (original)
+++ hugo/trunk/src/work/marci_graph_demo.cc Fri Feb 27 13:39:15 2004
@@ -225,6 +225,17 @@
{
ListGraph::EdgeMap<int> flow(flowG, 0);
MaxFlow<ListGraph, int, ListGraph::EdgeMap<int>, ListGraph::EdgeMap<int> > max_flow_test(flowG, s, t, flow, cap);
+ /*
+ max_flow_test.augmentOnBlockingFlow<ListGraph>();
+ for(EachEdgeIt e=flowG.template first<EachEdgeIt>(); e.valid(); ++e) {
+ std::cout<<"("<<flowG.tail(e)<< "-"<<flow.get(e)<<"->"<<flowG.head(e)<<") ";
+ }
+ std::cout<<std::endl;
+ max_flow_test.augmentOnBlockingFlow<ListGraph>();
+ for(EachEdgeIt e=flowG.template first<EachEdgeIt>(); e.valid(); ++e) {
+ std::cout<<"("<<flowG.tail(e)<< "-"<<flow.get(e)<<"->"<<flowG.head(e)<<") ";
+ }
+ std::cout<<std::endl;*/
max_flow_test.run();
std::cout << "maximum flow: "<< std::endl;
More information about the Lemon-commits
mailing list