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);
				}
			}
		}
	}
}
예제 #2
0
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;
}
예제 #4
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
}