/* -------------------------------------------------------------- mark the nodes 1 or 2 to define a min-cut, where source in X and sink in Y. start the search from the source node. for x in X and y in Y arc (x,y) is in the min-cut when flow(x,y) == capacity(x,y) arc (y,x) is in the min-cut when flow(y,x) == 0 on return, mark[*] is filled with 1 or 2, where the mark[source] = 1 and mark[sink] = 2 created -- 96jun08, cca -------------------------------------------------------------- */ void Network_findMincutFromSource ( Network *network, Ideq *deq, int mark[] ) { Arc *arc ; Arc **inheads, **outheads ; FILE *msgFile ; int msglvl, nnode, source, x, z ; /* --------------- check the input --------------- */ if ( network == NULL || (nnode = network->nnode) <= 0 || deq == NULL || mark == NULL ) { fprintf(stderr, "\n fatal error in Network_findMincutFromSource(%p,%p,%p)" "\n bad input\n", network, deq, mark) ; exit(-1) ; } source = 0 ; inheads = network->inheads ; outheads = network->outheads ; msglvl = network->msglvl ; msgFile = network->msgFile ; if ( msglvl > 2 ) { fprintf(msgFile, "\n Network_findMincutFromSource") ; fflush(msgFile) ; } /* ----------------------------------------------- load all the nodes into Y except for the source ----------------------------------------------- */ IVfill(nnode, mark, 2) ; mark[source] = 1 ; /* --------------------------------------------------------- do a breadth first traversal from the source visit x in X out edge (x,z), add z to X if flow(x,z) < capacity(x,z) in edge (z,x), add z to X if flow(z,x) > 0 --------------------------------------------------------- */ Ideq_clear(deq) ; Ideq_insertAtHead(deq, source) ; while ( (x = Ideq_removeFromHead(deq)) != -1 ) { if ( msglvl > 2 ) { fprintf(msgFile, "\n checking out node %d", x) ; fflush(msgFile) ; } for ( arc = outheads[x] ; arc != NULL ; arc = arc->nextOut ) { z = arc->second ; if ( mark[z] != 1 ) { if ( msglvl > 2 ) { fprintf(msgFile, "\n out-arc (%d,%d), flow %d, capacity %d", x, z, arc->flow, arc->capacity) ; fflush(msgFile) ; } if ( arc->flow < arc->capacity ) { if ( msglvl > 2 ) { fprintf(msgFile, ", adding %d to X", z) ; fflush(msgFile) ; } Ideq_insertAtTail(deq, z) ; mark[z] = 1 ; } } } for ( arc = inheads[x] ; arc != NULL ; arc = arc->nextIn ) { z = arc->first ; if ( mark[z] != 1 ) { if ( msglvl > 2 ) { fprintf(msgFile, "\n in-arc (%d,%d), flow %d", z, x, arc->flow) ; fflush(msgFile) ; } if ( arc->flow > 0 ) { if ( msglvl > 2 ) { fprintf(msgFile, ", adding %d to X", z) ; fflush(msgFile) ; } Ideq_insertAtTail(deq, z) ; mark[z] = 1 ; } } } } if ( msglvl > 2 ) { fprintf(msgFile, "\n leaving FindMincutFromSource") ; fflush(msgFile) ; } return ; }
/* ---------------------------------------------------- purpose -- worker method to factor the matrix created -- 98may29, cca ---------------------------------------------------- */ static void * FrontMtx_QR_workerFactor ( void *arg ) { char *status ; ChvList *updlist ; ChvManager *chvmanager ; double facops, t0, t1 ; double *cpus ; DV workDV ; FILE *msgFile ; FrontMtx *frontmtx ; Ideq *dequeue ; InpMtx *mtxA ; int J, K, myid, neqns, nfront, msglvl ; int *colmap, *firstnz, *nactiveChild, *owners, *par ; IVL *rowsIVL ; QR_factorData *data ; MARKTIME(t0) ; data = (QR_factorData *) arg ; mtxA = data->mtxA ; rowsIVL = data->rowsIVL ; firstnz = data->firstnz ; IV_sizeAndEntries(data->ownersIV, &nfront, &owners) ; frontmtx = data->frontmtx ; chvmanager = data->chvmanager ; updlist = data->updlist ; myid = data->myid ; cpus = data->cpus ; msglvl = data->msglvl ; msgFile = data->msgFile ; par = frontmtx->tree->par ; neqns = FrontMtx_neqns(frontmtx) ; /* -------------------------------------------------------- status[J] = 'F' --> J finished = 'W' --> J waiting to be finished create the Ideq object to handle the bottom-up traversal nactiveChild[K] = # of unfinished children of K, when zero, K can be placed on the dequeue -------------------------------------------------------- */ status = CVinit(nfront, 'F') ; dequeue = FrontMtx_setUpDequeue(frontmtx, owners, myid, status, NULL, 'W', 'F', msglvl, msgFile) ; FrontMtx_loadActiveLeaves(frontmtx, status, 'W', dequeue) ; nactiveChild = FrontMtx_nactiveChild(frontmtx, status, myid) ; colmap = IVinit(neqns, -1) ; DV_setDefaultFields(&workDV) ; facops = 0.0 ; if ( msglvl > 3 ) { fprintf(msgFile, "\n owners") ; IVfprintf(msgFile, nfront, owners) ; fprintf(msgFile, "\n Ideq") ; Ideq_writeForHumanEye(dequeue, msgFile) ; fflush(msgFile) ; } MARKTIME(t1) ; cpus[0] += t1 - t0 ; /* --------------------------- loop while a path is active --------------------------- */ while ( (J = Ideq_removeFromHead(dequeue)) != -1 ) { if ( msglvl > 1 ) { fprintf(msgFile, "\n\n ### checking out front %d, owner %d", J, owners[J]) ; } if ( owners[J] == myid ) { /* -------------------------------- front J is ready to be processed -------------------------------- */ FrontMtx_QR_factorVisit(frontmtx, J, mtxA, rowsIVL, firstnz, updlist, chvmanager, status, colmap, &workDV, cpus, &facops, msglvl, msgFile) ; if ( status[J] == 'F' ) { /* ------------------------------------------ front J is finished, put parent on dequeue if it exists or all children are finished ------------------------------------------ */ if ( (K = par[J]) != -1 && --nactiveChild[K] == 0 ) { Ideq_insertAtHead(dequeue, K) ; } } else { /* ----------------------------------------------- front J is not complete, put on tail of dequeue ----------------------------------------------- */ Ideq_insertAtTail(dequeue, J) ; } } else { /* ------------------------------------------- front J is not owned, put parent on dequeue if it exists and all children are finished ------------------------------------------- */ if ( (K = par[J]) != -1 && --nactiveChild[K] == 0 ) { Ideq_insertAtHead(dequeue, K) ; } } } data->facops = facops ; /* ------------------------ free the working storage ------------------------ */ CVfree(status) ; Ideq_free(dequeue) ; IVfree(nactiveChild) ; IVfree(colmap) ; DV_clearData(&workDV) ; MARKTIME(t1) ; cpus[6] = t1 - t0 ; cpus[5] = t1 - t0 - cpus[0] - cpus[1] - cpus[2] - cpus[3] - cpus[4] ; return(NULL) ; }