/* findAugmentingPath.c */
#include "../Network.h"
/*--------------------------------------------------------------------*/
/*
-----------------------------------------------------------------
find an augmenting path from the source to the sink through node.
node -- (source, node) is an arc below capacity
delta -- capacity(source, node) - flow(source, node)
tag -- tag used to build this traversal tree
deq -- dequeue object to handle traversal,
out-nodes get put at head of list,
in-nodes get put at tail of list
tags -- tags vector for the nodes
deltas -- flow increment vector for the nodes
pred -- predecessor vector for the nodes
created -- 96jun08, cca
-----------------------------------------------------------------
*/
int
Network_findAugmentingPath (
Network *network,
int node,
int delta,
int tag,
Ideq *deq,
int tags[],
int deltas[],
int pred[]
) {
Arc *arc ;
Arc **inheads, **outheads ;
FILE *msgFile ;
int msglvl, nnode, resid, sink, source, v, w ;
/*
---------------
check the input
---------------
*/
if ( network == NULL || (nnode = network->nnode) <= 0
|| node <= 0 || node >= nnode -1
|| deq == NULL || tags == NULL || deltas == NULL || pred == NULL ) {
fprintf(stderr,
"\n fatal error in Network_findAugmentingPath(%p,%d,%d,%d,%p,%p,%p,%p)"
"\n bad input\n",
network, node, delta, tag, deq, tags, deltas, pred) ;
exit(-1) ;
}
inheads = network->inheads ;
outheads = network->outheads ;
msglvl = network->msglvl ;
msgFile = network->msgFile ;
if ( msglvl > 2 ) {
fprintf(msgFile,
"\n try to find augmenting path starting at node %d",
node) ;
fflush(msgFile) ;
}
/*
---------------------------------------
load the dequeue with the seed node and
set the tags, pred and delta fields
---------------------------------------
*/
Ideq_clear(deq) ;
Ideq_insertAtHead(deq, node) ;
source = 0 ;
sink = nnode - 1 ;
tags[source] = tags[node] = tag ;
deltas[node] = delta ;
pred[node] = source ;
/*
------------------------------------------
try to find an augmenting path to the sink
------------------------------------------
*/
while ( tags[sink] != tag ) {
v = Ideq_removeFromHead(deq) ;
if ( v < 0 ) {
/*
-----------------------------------
dequeue is empty, break out of loop
-----------------------------------
*/
break ;
}
if ( msglvl > 2 ) {
fprintf(msgFile, "\n node %d removed from head of dequeue", v) ;
}
/*
----------------------
check out the out-arcs
----------------------
*/
for ( arc = outheads[v] ; arc != NULL ; arc = arc->nextOut ) {
network->ntrav++ ;
w = arc->second ;
if ( msglvl > 2 ) {
fprintf(msgFile, "\n out-arc (%d,%d), flow %d, capacity %d",
arc->first, arc->second, arc->flow, arc->capacity) ;
}
if ( tags[w] != tag && (resid = arc->capacity - arc->flow) > 0 ) {
if ( resid > deltas[v] ) {
resid = deltas[v] ;
}
deltas[w] = resid ;
if ( msglvl > 2 ) {
fprintf(msgFile,
", now a tree arc, delta = %d", deltas[w]) ;
}
tags[w] = tag ;
pred[w] = v ;
if ( w == sink ) {
return(resid) ;
}
Ideq_insertAtHead(deq, w) ;
}
}
/*
---------------------
check out the in-arcs
---------------------
*/
for ( arc = inheads[v] ; arc != NULL ; arc = arc->nextIn ) {
network->ntrav++ ;
w = arc->first ;
if ( msglvl > 2 ) {
fprintf(msgFile, "\n in-arc (%d,%d), flow %d, capacity %d",
arc->first, arc->second, arc->flow, arc->capacity) ;
}
if ( tags[w] != tag && (resid = arc->flow) > 0 ) {
if ( resid > deltas[v] ) {
resid = deltas[v] ;
}
deltas[w] = resid ;
if ( msglvl > 2 ) {
fprintf(msgFile,
", now a tree arc, delta = %d", deltas[w]) ;
}
tags[w] = tag ;
pred[w] = v ;
Ideq_insertAtTail(deq, w) ;
}
}
}
/*
----------------------------------------------------
if we got to here the sink was not reached, return 0
----------------------------------------------------
*/
return(0) ; }
/*--------------------------------------------------------------------*/
syntax highlighted by Code2HTML, v. 0.9.1