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;
}
Example #2
0
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
}