Grafalgo
Library of useful data structures and algorithms
|
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 }