void McRandomBisection(ctrl_t *ctrl, graph_t *graph, real_t *ntpwgts, idx_t niparts) { idx_t i, ii, j, k, nvtxs, ncon, from, bestcut=0, mincut, inbfs, qnum; idx_t *bestwhere, *where, *perm, *counts; idx_t *vwgt; WCOREPUSH; nvtxs = graph->nvtxs; ncon = graph->ncon; vwgt = graph->vwgt; Allocate2WayPartitionMemory(ctrl, graph); where = graph->where; bestwhere = iwspacemalloc(ctrl, nvtxs); perm = iwspacemalloc(ctrl, nvtxs); counts = iwspacemalloc(ctrl, ncon); for (inbfs=0; inbfs<2*niparts; inbfs++) { irandArrayPermute(nvtxs, perm, nvtxs/2, 1); iset(ncon, 0, counts); /* partition by spliting the queues randomly */ for (ii=0; ii<nvtxs; ii++) { i = perm[ii]; qnum = iargmax(ncon, vwgt+i*ncon); where[i] = (counts[qnum]++)%2; } Compute2WayPartitionParams(ctrl, graph); FM_2WayRefine(ctrl, graph, ntpwgts, ctrl->niter); Balance2Way(ctrl, graph, ntpwgts); FM_2WayRefine(ctrl, graph, ntpwgts, ctrl->niter); Balance2Way(ctrl, graph, ntpwgts); FM_2WayRefine(ctrl, graph, ntpwgts, ctrl->niter); if (inbfs == 0 || bestcut >= graph->mincut) { bestcut = graph->mincut; icopy(nvtxs, where, bestwhere); if (bestcut == 0) break; } } graph->mincut = bestcut; icopy(nvtxs, bestwhere, where); WCOREPOP; }
/************************************************************************* * This function is the entry point of refinement **************************************************************************/ void Refine2Way(CtrlType *ctrl, GraphType *orggraph, GraphType *graph, int *tpwgts, float ubfactor) { IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->UncoarsenTmr)); /* Compute the parameters of the coarsest graph */ Compute2WayPartitionParams(ctrl, graph); for (;;) { ASSERT(CheckBnd(graph)); IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->RefTmr)); switch (ctrl->RType) { case 1: Balance2Way(ctrl, graph, tpwgts, ubfactor); FM_2WayEdgeRefine(ctrl, graph, tpwgts, 8); break; default: errexit("Unknown refinement type: %d\n", ctrl->RType); } IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->RefTmr)); if (graph == orggraph) break; graph = graph->finer; IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ProjectTmr)); Project2WayPartition(ctrl, graph); IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ProjectTmr)); } IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->UncoarsenTmr)); }
void Refine2Way(ctrl_t *ctrl, graph_t *orggraph, graph_t *graph, real_t *tpwgts) { IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_startcputimer(ctrl->UncoarsenTmr)); /* Compute the parameters of the coarsest graph */ Compute2WayPartitionParams(ctrl, graph); for (;;) { ASSERT(CheckBnd(graph)); IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_startcputimer(ctrl->RefTmr)); Balance2Way(ctrl, graph, tpwgts); FM_2WayRefine(ctrl, graph, tpwgts, ctrl->niter); IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_stopcputimer(ctrl->RefTmr)); if (graph == orggraph) break; graph = graph->finer; IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_startcputimer(ctrl->ProjectTmr)); Project2WayPartition(ctrl, graph); IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_stopcputimer(ctrl->ProjectTmr)); } IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_stopcputimer(ctrl->UncoarsenTmr)); }
void McGrowBisection(ctrl_t *ctrl, graph_t *graph, real_t *ntpwgts, idx_t niparts) { idx_t i, j, k, nvtxs, ncon, from, bestcut=0, mincut, inbfs; idx_t *bestwhere, *where; WCOREPUSH; nvtxs = graph->nvtxs; Allocate2WayPartitionMemory(ctrl, graph); where = graph->where; bestwhere = iwspacemalloc(ctrl, nvtxs); for (inbfs=0; inbfs<2*niparts; inbfs++) { iset(nvtxs, 1, where); where[irandInRange(nvtxs)] = 0; Compute2WayPartitionParams(ctrl, graph); Balance2Way(ctrl, graph, ntpwgts); FM_2WayRefine(ctrl, graph, ntpwgts, ctrl->niter); Balance2Way(ctrl, graph, ntpwgts); FM_2WayRefine(ctrl, graph, ntpwgts, ctrl->niter); if (inbfs == 0 || bestcut >= graph->mincut) { bestcut = graph->mincut; icopy(nvtxs, where, bestwhere); if (bestcut == 0) break; } } graph->mincut = bestcut; icopy(nvtxs, bestwhere, where); WCOREPOP; }
/************************************************************************* * This function takes a graph and produces a bisection by using a region * growing algorithm. The resulting partition is returned in * graph->where **************************************************************************/ void GrowBisection(CtrlType *ctrl, GraphType *graph, int *tpwgts, float ubfactor) { int i, j, k, nvtxs, drain, nleft, first, last, pwgts[2], minpwgt[2], maxpwgt[2], from, bestcut, icut, mincut, me, pass, nbfs; idxtype *xadj, *vwgt, *adjncy, *adjwgt, *where; idxtype *queue, *touched, *gain, *bestwhere; nvtxs = graph->nvtxs; xadj = graph->xadj; vwgt = graph->vwgt; adjncy = graph->adjncy; adjwgt = graph->adjwgt; Allocate2WayPartitionMemory(ctrl, graph); where = graph->where; bestwhere = idxmalloc(nvtxs, "BisectGraph: bestwhere"); queue = idxmalloc(nvtxs, "BisectGraph: queue"); touched = idxmalloc(nvtxs, "BisectGraph: touched"); ASSERTP(tpwgts[0]+tpwgts[1] == idxsum(nvtxs, vwgt), ("%d %d\n", tpwgts[0]+tpwgts[1], idxsum(nvtxs, vwgt))); maxpwgt[0] = ubfactor*tpwgts[0]; maxpwgt[1] = ubfactor*tpwgts[1]; minpwgt[0] = (1.0/ubfactor)*tpwgts[0]; minpwgt[1] = (1.0/ubfactor)*tpwgts[1]; nbfs = (nvtxs <= ctrl->CoarsenTo ? SMALLNIPARTS : LARGENIPARTS); bestcut = idxsum(nvtxs, graph->adjwgtsum)+1; /* The +1 is for the 0 edges case */ for (; nbfs>0; nbfs--) { idxset(nvtxs, 0, touched); pwgts[1] = tpwgts[0]+tpwgts[1]; pwgts[0] = 0; idxset(nvtxs, 1, where); queue[0] = RandomInRange(nvtxs); touched[queue[0]] = 1; first = 0; last = 1; nleft = nvtxs-1; drain = 0; /* Start the BFS from queue to get a partition */ for (;;) { if (first == last) { /* Empty. Disconnected graph! */ if (nleft == 0 || drain) break; k = RandomInRange(nleft); for (i=0; i<nvtxs; i++) { if (touched[i] == 0) { if (k == 0) break; else k--; } } queue[0] = i; touched[i] = 1; first = 0; last = 1;; nleft--; } i = queue[first++]; if (pwgts[0] > 0 && pwgts[1]-vwgt[i] < minpwgt[1]) { drain = 1; continue; } where[i] = 0; INC_DEC(pwgts[0], pwgts[1], vwgt[i]); if (pwgts[1] <= maxpwgt[1]) break; drain = 0; for (j=xadj[i]; j<xadj[i+1]; j++) { k = adjncy[j]; if (touched[k] == 0) { queue[last++] = k; touched[k] = 1; nleft--; } } } /* Check to see if we hit any bad limiting cases */ if (pwgts[1] == 0) { i = RandomInRange(nvtxs); where[i] = 1; INC_DEC(pwgts[1], pwgts[0], vwgt[i]); } /************************************************************* * Do some partition refinement **************************************************************/ Compute2WayPartitionParams(ctrl, graph); /*printf("IPART: %3d [%5d %5d] [%5d %5d] %5d\n", graph->nvtxs, pwgts[0], pwgts[1], graph->pwgts[0], graph->pwgts[1], graph->mincut); */ Balance2Way(ctrl, graph, tpwgts, ubfactor); /*printf("BPART: [%5d %5d] %5d\n", graph->pwgts[0], graph->pwgts[1], graph->mincut);*/ FM_2WayEdgeRefine(ctrl, graph, tpwgts, 4); /*printf("RPART: [%5d %5d] %5d\n", graph->pwgts[0], graph->pwgts[1], graph->mincut);*/ if (bestcut > graph->mincut) { bestcut = graph->mincut; idxcopy(nvtxs, where, bestwhere); if (bestcut == 0) break; } } graph->mincut = bestcut; idxcopy(nvtxs, bestwhere, where); GKfree(&bestwhere, &queue, &touched, LTERM); }
/************************************************************************* * This function takes a graph and produces a bisection by using a region * growing algorithm. The resulting partition is returned in * graph->where **************************************************************************/ void RandomBisection(CtrlType *ctrl, GraphType *graph, int *tpwgts, float ubfactor) { int i, ii, j, k, nvtxs, pwgts[2], minpwgt[2], maxpwgt[2], from, bestcut, icut, mincut, me, pass, nbfs; idxtype *xadj, *vwgt, *adjncy, *adjwgt, *where; idxtype *perm, *bestwhere; nvtxs = graph->nvtxs; xadj = graph->xadj; vwgt = graph->vwgt; adjncy = graph->adjncy; adjwgt = graph->adjwgt; Allocate2WayPartitionMemory(ctrl, graph); where = graph->where; bestwhere = idxmalloc(nvtxs, "BisectGraph: bestwhere"); perm = idxmalloc(nvtxs, "BisectGraph: queue"); ASSERTP(tpwgts[0]+tpwgts[1] == idxsum(nvtxs, vwgt), ("%d %d\n", tpwgts[0]+tpwgts[1], idxsum(nvtxs, vwgt))); maxpwgt[0] = ubfactor*tpwgts[0]; maxpwgt[1] = ubfactor*tpwgts[1]; minpwgt[0] = (1.0/ubfactor)*tpwgts[0]; minpwgt[1] = (1.0/ubfactor)*tpwgts[1]; nbfs = (nvtxs <= ctrl->CoarsenTo ? SMALLNIPARTS : LARGENIPARTS); bestcut = idxsum(nvtxs, graph->adjwgtsum)+1; /* The +1 is for the 0 edges case */ for (; nbfs>0; nbfs--) { RandomPermute(nvtxs, perm, 1); idxset(nvtxs, 1, where); pwgts[1] = tpwgts[0]+tpwgts[1]; pwgts[0] = 0; if (nbfs != 1) { for (ii=0; ii<nvtxs; ii++) { i = perm[ii]; if (pwgts[0]+vwgt[i] < maxpwgt[0]) { where[i] = 0; pwgts[0] += vwgt[i]; pwgts[1] -= vwgt[i]; if (pwgts[0] > minpwgt[0]) break; } } } /************************************************************* * Do some partition refinement **************************************************************/ Compute2WayPartitionParams(ctrl, graph); /* printf("IPART: %3d [%5d %5d] [%5d %5d] %5d\n", graph->nvtxs, pwgts[0], pwgts[1], graph->pwgts[0], graph->pwgts[1], graph->mincut); */ Balance2Way(ctrl, graph, tpwgts, ubfactor); /* printf("BPART: [%5d %5d] %5d\n", graph->pwgts[0], graph->pwgts[1], graph->mincut); */ FM_2WayEdgeRefine(ctrl, graph, tpwgts, 4); /* printf("RPART: [%5d %5d] %5d\n", graph->pwgts[0], graph->pwgts[1], graph->mincut); */ if (bestcut > graph->mincut) { bestcut = graph->mincut; idxcopy(nvtxs, where, bestwhere); if (bestcut == 0) break; } } graph->mincut = bestcut; idxcopy(nvtxs, bestwhere, where); GKfree(&bestwhere, &perm, LTERM); }
/************************************************************************* * This function takes a graph and produces a bisection by using a region * growing algorithm. The resulting partition is returned in * graph->where **************************************************************************/ void GrowBisectionNode(CtrlType *ctrl, GraphType *graph, float ubfactor) { int i, j, k, nvtxs, drain, nleft, first, last, pwgts[2], tpwgts[2], minpwgt[2], maxpwgt[2], from, bestcut, icut, mincut, me, pass, nbfs; idxtype *xadj, *vwgt, *adjncy, *adjwgt, *where, *bndind; idxtype *queue, *touched, *gain, *bestwhere; nvtxs = graph->nvtxs; xadj = graph->xadj; vwgt = graph->vwgt; adjncy = graph->adjncy; adjwgt = graph->adjwgt; bestwhere = idxmalloc(nvtxs, "BisectGraph: bestwhere"); queue = idxmalloc(nvtxs, "BisectGraph: queue"); touched = idxmalloc(nvtxs, "BisectGraph: touched"); tpwgts[0] = idxsum(nvtxs, vwgt); tpwgts[1] = tpwgts[0]/2; tpwgts[0] -= tpwgts[1]; maxpwgt[0] = ubfactor*tpwgts[0]; maxpwgt[1] = ubfactor*tpwgts[1]; minpwgt[0] = (1.0/ubfactor)*tpwgts[0]; minpwgt[1] = (1.0/ubfactor)*tpwgts[1]; /* Allocate memory for graph->rdata. Allocate sufficient memory for both edge and node */ graph->rdata = idxmalloc(5*nvtxs+3, "GrowBisectionNode: graph->rdata"); graph->pwgts = graph->rdata; graph->where = graph->rdata + 3; graph->bndptr = graph->rdata + nvtxs + 3; graph->bndind = graph->rdata + 2*nvtxs + 3; graph->nrinfo = (NRInfoType *)(graph->rdata + 3*nvtxs + 3); graph->id = graph->rdata + 3*nvtxs + 3; graph->ed = graph->rdata + 4*nvtxs + 3; where = graph->where; bndind = graph->bndind; nbfs = (nvtxs <= ctrl->CoarsenTo ? SMALLNIPARTS : LARGENIPARTS); bestcut = tpwgts[0]+tpwgts[1]; for (nbfs++; nbfs>0; nbfs--) { idxset(nvtxs, 0, touched); pwgts[1] = tpwgts[0]+tpwgts[1]; pwgts[0] = 0; idxset(nvtxs, 1, where); queue[0] = RandomInRange(nvtxs); touched[queue[0]] = 1; first = 0; last = 1; nleft = nvtxs-1; drain = 0; /* Start the BFS from queue to get a partition */ if (nbfs >= 1) { for (;;) { if (first == last) { /* Empty. Disconnected graph! */ if (nleft == 0 || drain) break; k = RandomInRange(nleft); for (i=0; i<nvtxs; i++) { if (touched[i] == 0) { if (k == 0) break; else k--; } } queue[0] = i; touched[i] = 1; first = 0; last = 1;; nleft--; } i = queue[first++]; if (pwgts[1]-vwgt[i] < minpwgt[1]) { drain = 1; continue; } where[i] = 0; INC_DEC(pwgts[0], pwgts[1], vwgt[i]); if (pwgts[1] <= maxpwgt[1]) break; drain = 0; for (j=xadj[i]; j<xadj[i+1]; j++) { k = adjncy[j]; if (touched[k] == 0) { queue[last++] = k; touched[k] = 1; nleft--; } } } } /************************************************************* * Do some partition refinement **************************************************************/ Compute2WayPartitionParams(ctrl, graph); Balance2Way(ctrl, graph, tpwgts, ubfactor); FM_2WayEdgeRefine(ctrl, graph, tpwgts, 4); /* Construct and refine the vertex separator */ for (i=0; i<graph->nbnd; i++) where[bndind[i]] = 2; Compute2WayNodePartitionParams(ctrl, graph); FM_2WayNodeRefine(ctrl, graph, ubfactor, 6); /* printf("ISep: [%d %d %d] %d\n", graph->pwgts[0], graph->pwgts[1], graph->pwgts[2], bestcut); */ if (bestcut > graph->mincut) { bestcut = graph->mincut; idxcopy(nvtxs, where, bestwhere); } } graph->mincut = bestcut; idxcopy(nvtxs, bestwhere, where); Compute2WayNodePartitionParams(ctrl, graph); GKfree(&bestwhere, &queue, &touched, LTERM); }
void GrowBisectionNode(ctrl_t *ctrl, graph_t *graph, real_t *ntpwgts, idx_t niparts) { idx_t i, j, k, nvtxs, drain, nleft, first, last, pwgts[2], oneminpwgt, onemaxpwgt, from, me, bestcut=0, icut, mincut, inbfs; idx_t *xadj, *vwgt, *adjncy, *where, *bndind; idx_t *queue, *touched, *gain, *bestwhere; WCOREPUSH; nvtxs = graph->nvtxs; xadj = graph->xadj; vwgt = graph->vwgt; adjncy = graph->adjncy; // adjwgt = graph->adjwgt; bestwhere = iwspacemalloc(ctrl, nvtxs); queue = iwspacemalloc(ctrl, nvtxs); touched = iwspacemalloc(ctrl, nvtxs); onemaxpwgt = ctrl->ubfactors[0]*graph->tvwgt[0]*0.5; oneminpwgt = (1.0/ctrl->ubfactors[0])*graph->tvwgt[0]*0.5; /* Allocate refinement memory. Allocate sufficient memory for both edge and node */ graph->pwgts = imalloc(3, "GrowBisectionNode: pwgts"); graph->where = imalloc(nvtxs, "GrowBisectionNode: where"); graph->bndptr = imalloc(nvtxs, "GrowBisectionNode: bndptr"); graph->bndind = imalloc(nvtxs, "GrowBisectionNode: bndind"); graph->id = imalloc(nvtxs, "GrowBisectionNode: id"); graph->ed = imalloc(nvtxs, "GrowBisectionNode: ed"); graph->nrinfo = (nrinfo_t *)gk_malloc(nvtxs*sizeof(nrinfo_t), "GrowBisectionNode: nrinfo"); where = graph->where; bndind = graph->bndind; for (inbfs=0; inbfs<niparts; inbfs++) { iset(nvtxs, 1, where); iset(nvtxs, 0, touched); pwgts[1] = graph->tvwgt[0]; pwgts[0] = 0; queue[0] = irandInRange(nvtxs); touched[queue[0]] = 1; first = 0; last = 1; nleft = nvtxs-1; drain = 0; /* Start the BFS from queue to get a partition */ for (;;) { if (first == last) { /* Empty. Disconnected graph! */ if (nleft == 0 || drain) break; k = irandInRange(nleft); for (i=0; i<nvtxs; i++) { /* select the kth untouched vertex */ if (touched[i] == 0) { if (k == 0) break; else k--; } } queue[0] = i; touched[i] = 1; first = 0; last = 1; nleft--; } i = queue[first++]; if (pwgts[1]-vwgt[i] < oneminpwgt) { drain = 1; continue; } where[i] = 0; INC_DEC(pwgts[0], pwgts[1], vwgt[i]); if (pwgts[1] <= onemaxpwgt) break; drain = 0; for (j=xadj[i]; j<xadj[i+1]; j++) { k = adjncy[j]; if (touched[k] == 0) { queue[last++] = k; touched[k] = 1; nleft--; } } } /************************************************************* * Do some partition refinement **************************************************************/ Compute2WayPartitionParams(ctrl, graph); Balance2Way(ctrl, graph, ntpwgts); FM_2WayRefine(ctrl, graph, ntpwgts, 4); /* Construct and refine the vertex separator */ for (i=0; i<graph->nbnd; i++) { j = bndind[i]; if (xadj[j+1]-xadj[j] > 0) /* ignore islands */ where[j] = 2; } Compute2WayNodePartitionParams(ctrl, graph); FM_2WayNodeRefine2Sided(ctrl, graph, 1); FM_2WayNodeRefine1Sided(ctrl, graph, 4); /* printf("ISep: [%"PRIDX" %"PRIDX" %"PRIDX" %"PRIDX"] %"PRIDX"\n", inbfs, graph->pwgts[0], graph->pwgts[1], graph->pwgts[2], bestcut); */ if (inbfs == 0 || bestcut > graph->mincut) { bestcut = graph->mincut; icopy(nvtxs, where, bestwhere); } } graph->mincut = bestcut; icopy(nvtxs, bestwhere, where); WCOREPOP; }
void GrowBisection(ctrl_t *ctrl, graph_t *graph, real_t *ntpwgts, idx_t niparts) { idx_t i, j, k, nvtxs, drain, nleft, first, last, pwgts[2], oneminpwgt, onemaxpwgt, from, me, bestcut=0, icut, mincut, inbfs; idx_t *xadj, *vwgt, *adjncy, *where; idx_t *queue, *touched, *gain, *bestwhere; WCOREPUSH; nvtxs = graph->nvtxs; xadj = graph->xadj; vwgt = graph->vwgt; adjncy = graph->adjncy; // adjwgt = graph->adjwgt; Allocate2WayPartitionMemory(ctrl, graph); where = graph->where; bestwhere = iwspacemalloc(ctrl, nvtxs); queue = iwspacemalloc(ctrl, nvtxs); touched = iwspacemalloc(ctrl, nvtxs); onemaxpwgt = ctrl->ubfactors[0]*graph->tvwgt[0]*ntpwgts[1]; oneminpwgt = (1.0/ctrl->ubfactors[0])*graph->tvwgt[0]*ntpwgts[1]; for (inbfs=0; inbfs<niparts; inbfs++) { iset(nvtxs, 1, where); iset(nvtxs, 0, touched); pwgts[1] = graph->tvwgt[0]; pwgts[0] = 0; queue[0] = irandInRange(nvtxs); touched[queue[0]] = 1; first = 0; last = 1; nleft = nvtxs-1; drain = 0; /* Start the BFS from queue to get a partition */ for (;;) { if (first == last) { /* Empty. Disconnected graph! */ if (nleft == 0 || drain) break; k = irandInRange(nleft); for (i=0; i<nvtxs; i++) { if (touched[i] == 0) { if (k == 0) break; else k--; } } queue[0] = i; touched[i] = 1; first = 0; last = 1; nleft--; } i = queue[first++]; if (pwgts[0] > 0 && pwgts[1]-vwgt[i] < oneminpwgt) { drain = 1; continue; } where[i] = 0; INC_DEC(pwgts[0], pwgts[1], vwgt[i]); if (pwgts[1] <= onemaxpwgt) break; drain = 0; for (j=xadj[i]; j<xadj[i+1]; j++) { k = adjncy[j]; if (touched[k] == 0) { queue[last++] = k; touched[k] = 1; nleft--; } } } /* Check to see if we hit any bad limiting cases */ if (pwgts[1] == 0) where[irandInRange(nvtxs)] = 1; if (pwgts[0] == 0) where[irandInRange(nvtxs)] = 0; /************************************************************* * Do some partition refinement **************************************************************/ Compute2WayPartitionParams(ctrl, graph); /* printf("IPART: %3"PRIDX" [%5"PRIDX" %5"PRIDX"] [%5"PRIDX" %5"PRIDX"] %5"PRIDX"\n", graph->nvtxs, pwgts[0], pwgts[1], graph->pwgts[0], graph->pwgts[1], graph->mincut); */ Balance2Way(ctrl, graph, ntpwgts); /* printf("BPART: [%5"PRIDX" %5"PRIDX"] %5"PRIDX"\n", graph->pwgts[0], graph->pwgts[1], graph->mincut); */ FM_2WayRefine(ctrl, graph, ntpwgts, ctrl->niter); /* printf("RPART: [%5"PRIDX" %5"PRIDX"] %5"PRIDX"\n", graph->pwgts[0], graph->pwgts[1], graph->mincut); */ if (inbfs == 0 || bestcut > graph->mincut) { bestcut = graph->mincut; icopy(nvtxs, where, bestwhere); if (bestcut == 0) break; } } graph->mincut = bestcut; icopy(nvtxs, bestwhere, where); WCOREPOP; }
void RandomBisection(ctrl_t *ctrl, graph_t *graph, real_t *ntpwgts, idx_t niparts) { idx_t i, ii, j, k, nvtxs, pwgts[2], zeromaxpwgt, from, me, bestcut=0, icut, mincut, inbfs; idx_t *vwgt, *where; idx_t *perm, *bestwhere; WCOREPUSH; nvtxs = graph->nvtxs; // xadj = graph->xadj; vwgt = graph->vwgt; // adjncy = graph->adjncy; // adjwgt = graph->adjwgt; Allocate2WayPartitionMemory(ctrl, graph); where = graph->where; bestwhere = iwspacemalloc(ctrl, nvtxs); perm = iwspacemalloc(ctrl, nvtxs); zeromaxpwgt = ctrl->ubfactors[0]*graph->tvwgt[0]*ntpwgts[0]; for (inbfs=0; inbfs<niparts; inbfs++) { iset(nvtxs, 1, where); if (inbfs > 0) { irandArrayPermute(nvtxs, perm, nvtxs/2, 1); pwgts[1] = graph->tvwgt[0]; pwgts[0] = 0; for (ii=0; ii<nvtxs; ii++) { i = perm[ii]; if (pwgts[0]+vwgt[i] < zeromaxpwgt) { where[i] = 0; pwgts[0] += vwgt[i]; pwgts[1] -= vwgt[i]; if (pwgts[0] > zeromaxpwgt) break; } } } /* Do some partition refinement */ Compute2WayPartitionParams(ctrl, graph); /* printf("IPART: %3"PRIDX" [%5"PRIDX" %5"PRIDX"] [%5"PRIDX" %5"PRIDX"] %5"PRIDX"\n", graph->nvtxs, pwgts[0], pwgts[1], graph->pwgts[0], graph->pwgts[1], graph->mincut); */ Balance2Way(ctrl, graph, ntpwgts); /* printf("BPART: [%5"PRIDX" %5"PRIDX"] %5"PRIDX"\n", graph->pwgts[0], graph->pwgts[1], graph->mincut); */ FM_2WayRefine(ctrl, graph, ntpwgts, 4); /* printf("RPART: [%5"PRIDX" %5"PRIDX"] %5"PRIDX"\n", graph->pwgts[0], graph->pwgts[1], graph->mincut); */ if (inbfs==0 || bestcut > graph->mincut) { bestcut = graph->mincut; icopy(nvtxs, where, bestwhere); if (bestcut == 0) break; } } graph->mincut = bestcut; icopy(nvtxs, bestwhere, where); WCOREPOP; }