template <typename captype, typename tcaptype, typename flowtype> void IBFSGraph<captype, tcaptype, flowtype>::augment(arc *bridge, AugmentationInfo* augInfo) { node *x, *y; arc *a; captype bottleneck, flowCurr; #ifdef STATS statsNumAugs++; statsNumPushes++; int augLen=1; #endif // // Find Bottleneck In Source Tree // bottleneck = bridge->rCap; if (augInfo->remainingExcess == 0) { augInfo->remainingExcess = INT_MAX; for (x=bridge->sister->head; ; x=a->head) { #ifdef STATS augLen++; statsNumPushes++; #endif a = x->parent; if (a != PARENT_SRC_SINK) { if (augInfo->remainingExcess > a->sister->rCap) { augInfo->remainingExcess = a->sister->rCap; } } else { break; } } if (augInfo->remainingExcess > x->srcSinkCap) { augInfo->remainingExcess = x->srcSinkCap; } } if (bottleneck > augInfo->remainingExcess) { bottleneck = augInfo->remainingExcess; } // // Find Bottleneck In Sink Tree // if (augInfo->remainingDeficit == 0) { augInfo->remainingDeficit = INT_MAX; for (x=bridge->head; ; x=a->head) { #ifdef STATS augLen++; statsNumPushes++; #endif a = x->parent; if (a != PARENT_SRC_SINK) { if (augInfo->remainingDeficit > a->rCap) { augInfo->remainingDeficit = a->rCap; } } else { break; } } if (augInfo->remainingDeficit > (-x->srcSinkCap)) { augInfo->remainingDeficit = (-x->srcSinkCap); } } if (bottleneck > augInfo->remainingDeficit) { bottleneck = augInfo->remainingDeficit; } #ifdef STATS if (augLenMin > augLen) { augLenMin = augLen; } if (augLenMax < augLen) { augLenMax = augLen; } #endif // // Augment Sink Tree // augInfo->remainingDeficit -= bottleneck; augInfo->flowDeficit += bottleneck; if (augInfo->remainingDeficit == 0) { flowCurr = augInfo->flowDeficit; augInfo->flowDeficit = 0; for (x=bridge->head; ; x=a->head) { a = x->parent; if (a != PARENT_SRC_SINK) { a->sister->rCap += flowCurr; a->sister_rCap = 1; a->rCap -= flowCurr; if (a->rCap == 0) { a->sister->sister_rCap = 0; y=x->parent->head->firstSon; if (y == x) { x->parent->head->firstSon = NODE_INDEX_TO_PTR(x->nextSibling); } else { for (; y->nextSibling != (x-nodes); y = (nodes+y->nextSibling)); y->nextSibling = x->nextSibling; } ADD_ORPHAN_FRONT(x); } } else { break; } } x->srcSinkCap += flowCurr; if (x->srcSinkCap == 0) { ADD_ORPHAN_FRONT(x); } if (orphanFirst != END_OF_ORPHANS) { adoptionSink(); } } // // Augment Source Tree // bridge->sister->rCap += bottleneck; bridge->sister_rCap = 1; bridge->rCap -= bottleneck; if (bridge->rCap == 0) { bridge->sister->sister_rCap = 0; } augInfo->remainingExcess -= bottleneck; augInfo->flowExcess += bottleneck; if (augInfo->remainingExcess == 0) { flowCurr = augInfo->flowExcess; augInfo->flowExcess = 0; for (x=bridge->sister->head; ; x=a->head) { a = x->parent; if (a != PARENT_SRC_SINK) { a->rCap += flowCurr; a->sister->sister_rCap = 1; a->sister->rCap -= flowCurr; if (a->sister->rCap == 0) { a->sister_rCap = 0; y=x->parent->head->firstSon; if (y == x) { x->parent->head->firstSon = NODE_INDEX_TO_PTR(x->nextSibling); } else { for (; y->nextSibling != (x-nodes); y = (nodes+y->nextSibling)); y->nextSibling = x->nextSibling; } ADD_ORPHAN_FRONT(x); } } else { break; } } x->srcSinkCap -= flowCurr; if (x->srcSinkCap == 0) { ADD_ORPHAN_FRONT(x); } if (orphanFirst != END_OF_ORPHANS) { adoptionSrc(); } } flow += bottleneck; }
template <typename captype, typename tcaptype, typename flowtype> void IBFSGraph<captype, tcaptype, flowtype>::augment(arc *middle_arc, AugmentationInfo* augInfo) { node *i, *j; arc *a; captype bottleneck, flowCurr; #ifdef STATS statsNumAugs++; statsNumPushes++; int augLen=1; #endif // src tree bottleneck = middle_arc->rCap; if (augInfo->remainingExcess == 0) { augInfo->remainingExcess = INT_MAX; for (i=middle_arc->sister->head; ; i=a->head) { #ifdef STATS augLen++; statsNumPushes++; #endif a = i->parent; if (a == TERMINAL) break; if (augInfo->remainingExcess > a->sister->rCap) { augInfo->remainingExcess = a->sister->rCap; } } if (augInfo->remainingExcess > i->terminalCap) { augInfo->remainingExcess = i->terminalCap; } } if (bottleneck > augInfo->remainingExcess) { bottleneck = augInfo->remainingExcess; } // sink tree if (augInfo->remainingDeficit == 0) { augInfo->remainingDeficit = INT_MAX; for (i=middle_arc->head; ; i=a->head) { #ifdef STATS augLen++; statsNumPushes++; #endif a = i->parent; if (a == TERMINAL) break; if (augInfo->remainingDeficit > a->rCap) { augInfo->remainingDeficit = a->rCap; } } if (augInfo->remainingDeficit > (-i->terminalCap)) { augInfo->remainingDeficit = (-i->terminalCap); } } if (bottleneck > augInfo->remainingDeficit) { bottleneck = augInfo->remainingDeficit; } #ifdef STATS if (augLenMin > augLen) { augLenMin = augLen; } if (augLenMax < augLen) { augLenMax = augLen; } #endif // // augment sink tree // augInfo->remainingDeficit -= bottleneck; augInfo->flowDeficit += bottleneck; if (augInfo->remainingDeficit == 0) { flowCurr = augInfo->flowDeficit; augInfo->flowDeficit = 0; for (i=middle_arc->head; ; i=a->head) { a = i->parent; if (a == TERMINAL) break; a->sister->rCap += flowCurr; a->sister_rCap = 1; a->rCap -= flowCurr; if (a->rCap == 0) { a->sister->sister_rCap = 0; j=i->parent->head->firstSon; if (j == i) { i->parent->head->firstSon = NODE_INDEX_TO_PTR(i->nextSibling); } else { for (; j->nextSibling != (i-nodes); j = (nodes+j->nextSibling)); j->nextSibling = i->nextSibling; } ADD_ORPHAN_FRONT(i); } } i->terminalCap += flowCurr; if (i->terminalCap == 0) { ADD_ORPHAN_FRONT(i); } if (orphanFirst != END_OF_ORPHANS) { adoptionSink(); } } // // augment src tree // middle_arc->sister->rCap += bottleneck; middle_arc->sister_rCap = 1; middle_arc->rCap -= bottleneck; if (middle_arc->rCap == 0) { middle_arc->sister->sister_rCap = 0; } augInfo->remainingExcess -= bottleneck; augInfo->flowExcess += bottleneck; if (augInfo->remainingExcess == 0) { flowCurr = augInfo->flowExcess; augInfo->flowExcess = 0; for (i=middle_arc->sister->head; ; i=a->head) { a = i->parent; if (a == TERMINAL) break; a->rCap += flowCurr; a->sister->sister_rCap = 1; a->sister->rCap -= flowCurr; if (a->sister->rCap == 0) { a->sister_rCap = 0; j=i->parent->head->firstSon; if (j == i) { i->parent->head->firstSon = NODE_INDEX_TO_PTR(i->nextSibling); } else { for (; j->nextSibling != (i-nodes); j = (nodes+j->nextSibling)); j->nextSibling = i->nextSibling; } ADD_ORPHAN_FRONT(i); } } i->terminalCap -= flowCurr; if (i->terminalCap == 0) { ADD_ORPHAN_FRONT(i); } if (orphanFirst != END_OF_ORPHANS) { adoptionSrc(); } } flow += bottleneck; #ifdef STATS // for (int k=0; k<numOrphanPhaseNodes; k++) // { // int inc = orphanPhaseNodes[k]->label; // inc = (inc < 0) ? (-inc) : (inc); // inc = inc - orphanPhaseLabels[k]; // if (inc == 0) // { // numOrphans0++; // } // else if (inc == 1) // { // numOrphans1++; // } // else // { // numOrphans2++; // } // } #endif }