Grafalgo
Library of useful data structures and algorithms
/Users/jst/src/grafalgo/cpp/graphAlgorithms/maxFlo/dinic.cpp
00001 #include "dinic.h"
00002 
00003 using namespace grafalgo;
00004 
00005 dinic::dinic(Flograph& fg1, int& floVal) : augPath(fg1,floVal) {
00006         level = new int[fg->n()+1];
00007         nextEdge = new edge[fg->n()+1];
00008 
00009         floVal = 0;
00010         while (newPhase()) {
00011                 while (findPath()) floVal += augment();
00012         }
00013         delete [] level; delete [] nextEdge;
00014 }
00015 
00016 dinic::dinic(Flograph& fg1, int& floVal, string& stats) : augPath(fg1,floVal) {
00017         level = new int[fg->n()+1];
00018         nextEdge = new edge[fg->n()+1];
00019 
00020         floVal = 0;
00021         numPhase = 0; numPaths = 0; avgPathLength = 0;
00022         phaseTime = 0; pathTime = 0;
00023         uint32_t t1, t2, t3;
00024         t1 = Util::getTime();
00025         while (newPhase()) {
00026                 t2 = Util::getTime(); phaseTime += (t2-t1);
00027                 numPhase++;
00028                 while (findPath(fg->src())) {
00029                         t3 = Util::getTime(); pathTime += (t3-t2);
00030                         numPaths++; avgPathLength += level[fg->snk()];
00031 
00032                         floVal += augment();
00033                         t2 = Util::getTime();
00034                 }
00035                 t3 = Util::getTime(); pathTime += (t3-t2);
00036                 t1 = Util::getTime();
00037         }
00038         t2 = Util::getTime(); phaseTime += (t2-t1);
00039         avgPathLength /= numPaths;
00040         stringstream ss;
00041         ss << numPhase << " " << numPaths << " " << avgPathLength 
00042            << " " << phaseTime << " " << pathTime;
00043         stats = ss.str();
00044 
00045         delete [] level; delete [] nextEdge;
00046 }
00047 
00048 bool dinic::newPhase() {
00049 // Prepare for new phase. Return true if there is a source/sink path.
00050         vertex u,v; edge e;
00051         List q(fg->n());
00052 
00053         for (u = 1; u <= fg->n(); u++) {
00054                 level[u] = fg->n(); nextEdge[u] = fg->firstAt(u);
00055         }
00056         q.addLast(fg->src()); level[fg->src()] = 0;
00057         while (!q.empty()) {
00058                 u = q.first(); q.removeFirst();
00059                 for (e = fg->firstAt(u); e != 0; e = fg->nextAt(u,e)) {
00060                         v = fg->mate(u,e);
00061                         if (fg->res(u,e) > 0 && level[v] == fg->n()) {
00062                                 level[v] = level[u] + 1; 
00063                                 if (v == fg->snk()) return true;
00064                                 q.addLast(v);
00065                         }
00066                 }
00067         }
00068         return false;
00069 }
00070 
00071 bool dinic::findPath(vertex u) {
00072 // Find a shortest path with unused residual capacity.
00073         vertex v; edge e;
00074 
00075         for (e = nextEdge[u]; e != 0; e = fg->nextAt(u,e)) {
00076                 v = fg->mate(u,e);
00077                 if (fg->res(u,e) == 0 || level[v] != level[u] + 1) continue;
00078                 if (v == fg->snk() || findPath(v)) {
00079                         pEdge[v] = e; nextEdge[u] = e; return true;
00080                 }
00081         }
00082         nextEdge[u] = 0; return false;
00083 }
 All Classes Files Functions Variables Typedefs Friends