template <typename captype, typename tcaptype, typename flowtype> void IBFSGraph<captype, tcaptype, flowtype>::adoptionSink() { node *x, *y; arc *a, *aEnd; arc aTmp; int minLabel; while (orphanFirst != END_OF_ORPHANS) { x = orphanFirst; orphanFirst = x->nextOrphan; // we need PREVIOUSLY_ORPHAN vs NULL // in order to establish whether the node // has already started a "new parent" scan // while in this level or not (used in ADD_ORPHAN) x->nextOrphan = PREVIOUSLY_ORPHAN; a = x->parent; x->parent = NULL; aEnd = (x+1)->firstArc; // check for rehook if (x->label != -1) { minLabel = x->label + 1; for (; a != aEnd; a++) { #ifdef STATS orphanArcs1++; #endif y = a->head; if (a->rCap != 0 && y->parent != NULL && y->label == minLabel) { x->parent = a; x->nextSibling = NODE_PTR_TO_INDEX(y->firstSon); y->firstSon = x; break; } } } // give up on node - relabel it! if (x->parent == NULL) { minLabel = -(activeLevel+1); for (a=x->firstArc; a != aEnd; a++) { #ifdef STATS orphanArcs2++; #endif y = a->head; if (a->rCap != 0 && y->parent != NULL && y->label < 0 && y->label > minLabel) { minLabel = y->label; x->parent = a; if (minLabel == x->label) break; } } // create orphan sons for (y=x->firstSon; y; y=NODE_INDEX_TO_PTR(y->nextSibling)) { #ifdef STATS orphanArcs3++; #endif if (minLabel == x->label && y->parent != y->firstArc) { aTmp = *(y->parent); *(y->parent) = *(y->firstArc); *(y->firstArc) = aTmp; y->parent->sister->sister = y->parent; y->firstArc->sister->sister = y->firstArc; } ADD_ORPHAN_BACK(y); } x->firstSon = NULL; if (x->parent == NULL) { x->nextOrphan = NULL; } else { x->label = (minLabel-1); x->nextSibling = NODE_PTR_TO_INDEX(x->parent->head->firstSon); x->parent->head->firstSon = x; if (minLabel == -activeLevel) { SET_ACTIVE(x); } } } } }
template <typename captype, typename tcaptype, typename flowtype> void IBFSGraph<captype, tcaptype, flowtype>::adoptionSink() { node *i, *j; arc *a, *a_end; arc tmp_a; int min_label; while (orphanFirst != END_OF_ORPHANS) { // terminalCap is used as a next pointer for the orphans list i = orphanFirst; orphanFirst = i->nextOrphan; #ifdef STATS statsNumOrphans++; // if (orphanPhaseNodesHash[i-nodes] == false) // { // orphanPhaseNodesHash[i-nodes] = true; // orphanPhaseLabels[numOrphanPhaseNodes] = -(i->label); // orphanPhaseNodes[numOrphanPhaseNodes] = i; // numOrphanPhaseNodes++; // } #endif // we need PREVIOUSLY_ORPHAN vs NULL // in order to establish whether the node // has already started a "new parent" scan // while in this level or not (used in ADD_ORPHAN) i->nextOrphan = PREVIOUSLY_ORPHAN; a = i->parent; i->parent = NULL; a_end = (i+1)->firstArc; #ifdef COUNT_RELABELS if (scans[i-nodes] == 0) { scanIndices.push_back(i-nodes); } if ((scans[i-nodes]%2) == 0) { scans[i-nodes]++; } #endif // check for rehook if (i->label != -1) { min_label = i->label + 1; for (; a != a_end; a++) { #ifdef STATS orphanArcs1++; #endif j = a->head; if (a->rCap != 0 && j->parent != NULL && j->label == min_label) { i->parent = a; i->nextSibling = NODE_PTR_TO_INDEX(j->firstSon); j->firstSon = i; break; } } } // give up on node - relabel it! if (i->parent == NULL) { #ifdef COUNT_RELABELS scans[i-nodes]++; #endif min_label = -(activeLevel+1); for (a=i->firstArc; a != a_end; a++) { #ifdef STATS orphanArcs2++; #endif j = a->head; if (a->rCap != 0 && j->parent != NULL && j->label < 0 && j->label > min_label) { min_label = j->label; i->parent = a; if (min_label == i->label) break; } } for (j=i->firstSon; j; j=NODE_INDEX_TO_PTR(j->nextSibling)) { #ifdef STATS orphanArcs3++; #endif if (min_label == i->label && j->parent != j->firstArc) { tmp_a = *(j->parent); *(j->parent) = *(j->firstArc); *(j->firstArc) = tmp_a; j->parent->sister->sister = j->parent; j->firstArc->sister->sister = j->firstArc; } ADD_ORPHAN_BACK(j); } i->firstSon = NULL; if (i->parent == NULL) { i->nextOrphan = NULL; } else { i->label = (min_label-1); i->nextSibling = NODE_PTR_TO_INDEX(i->parent->head->firstSon); i->parent->head->firstSon = i; if (min_label == -activeLevel) { SET_ACTIVE(i); } } } } }
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 }