Path: blob/devel/elmergrid/src/metis-5.1.0/libmetis/separator.c
3206 views
/*1* Copyright 1997, Regents of the University of Minnesota2*3* separator.c4*5* This file contains code for separator extraction6*7* Started 8/1/978* George9*10* $Id: separator.c 10481 2011-07-05 18:01:23Z karypis $11*12*/1314#include "metislib.h"1516/*************************************************************************17* This function takes a bisection and constructs a minimum weight vertex18* separator out of it. It uses the node-based separator refinement for it.19**************************************************************************/20void ConstructSeparator(ctrl_t *ctrl, graph_t *graph)21{22idx_t i, j, k, nvtxs, nbnd;23idx_t *xadj, *where, *bndind;2425WCOREPUSH;2627nvtxs = graph->nvtxs;28xadj = graph->xadj;29nbnd = graph->nbnd;30bndind = graph->bndind;3132where = icopy(nvtxs, graph->where, iwspacemalloc(ctrl, nvtxs));3334/* Put the nodes in the boundary into the separator */35for (i=0; i<nbnd; i++) {36j = bndind[i];37if (xadj[j+1]-xadj[j] > 0) /* Ignore islands */38where[j] = 2;39}4041FreeRData(graph);4243Allocate2WayNodePartitionMemory(ctrl, graph);44icopy(nvtxs, where, graph->where);4546WCOREPOP;4748ASSERT(IsSeparable(graph));4950Compute2WayNodePartitionParams(ctrl, graph);5152ASSERT(CheckNodePartitionParams(graph));5354FM_2WayNodeRefine2Sided(ctrl, graph, 1);55FM_2WayNodeRefine1Sided(ctrl, graph, 4);5657ASSERT(IsSeparable(graph));5859}60616263/*************************************************************************64* This function takes a bisection and constructs a minimum weight vertex65* separator out of it. It uses an unweighted minimum-cover algorithm66* followed by node-based separator refinement.67**************************************************************************/68void ConstructMinCoverSeparator(ctrl_t *ctrl, graph_t *graph)69{70idx_t i, ii, j, jj, k, l, nvtxs, nbnd, bnvtxs[3], bnedges[2], csize;71idx_t *xadj, *adjncy, *bxadj, *badjncy;72idx_t *where, *bndind, *bndptr, *vmap, *ivmap, *cover;7374WCOREPUSH;7576nvtxs = graph->nvtxs;77xadj = graph->xadj;78adjncy = graph->adjncy;7980nbnd = graph->nbnd;81bndind = graph->bndind;82bndptr = graph->bndptr;83where = graph->where;8485vmap = iwspacemalloc(ctrl, nvtxs);86ivmap = iwspacemalloc(ctrl, nbnd);87cover = iwspacemalloc(ctrl, nbnd);8889if (nbnd > 0) {90/* Go through the boundary and determine the sizes of the bipartite graph */91bnvtxs[0] = bnvtxs[1] = bnedges[0] = bnedges[1] = 0;92for (i=0; i<nbnd; i++) {93j = bndind[i];94k = where[j];95if (xadj[j+1]-xadj[j] > 0) {96bnvtxs[k]++;97bnedges[k] += xadj[j+1]-xadj[j];98}99}100101bnvtxs[2] = bnvtxs[0]+bnvtxs[1];102bnvtxs[1] = bnvtxs[0];103bnvtxs[0] = 0;104105bxadj = iwspacemalloc(ctrl, bnvtxs[2]+1);106badjncy = iwspacemalloc(ctrl, bnedges[0]+bnedges[1]+1);107108/* Construct the ivmap and vmap */109ASSERT(iset(nvtxs, -1, vmap) == vmap);110for (i=0; i<nbnd; i++) {111j = bndind[i];112k = where[j];113if (xadj[j+1]-xadj[j] > 0) {114vmap[j] = bnvtxs[k];115ivmap[bnvtxs[k]++] = j;116}117}118119/* OK, go through and put the vertices of each part starting from 0 */120bnvtxs[1] = bnvtxs[0];121bnvtxs[0] = 0;122bxadj[0] = l = 0;123for (k=0; k<2; k++) {124for (ii=0; ii<nbnd; ii++) {125i = bndind[ii];126if (where[i] == k && xadj[i] < xadj[i+1]) {127for (j=xadj[i]; j<xadj[i+1]; j++) {128jj = adjncy[j];129if (where[jj] != k) {130ASSERT(bndptr[jj] != -1);131ASSERTP(vmap[jj] != -1, ("%"PRIDX" %"PRIDX" %"PRIDX"\n", jj, vmap[jj], graph->bndptr[jj]));132badjncy[l++] = vmap[jj];133}134}135bxadj[++bnvtxs[k]] = l;136}137}138}139140ASSERT(l <= bnedges[0]+bnedges[1]);141142MinCover(bxadj, badjncy, bnvtxs[0], bnvtxs[1], cover, &csize);143144IFSET(ctrl->dbglvl, METIS_DBG_SEPINFO,145printf("Nvtxs: %6"PRIDX", [%5"PRIDX" %5"PRIDX"], Cut: %6"PRIDX", SS: [%6"PRIDX" %6"PRIDX"], Cover: %6"PRIDX"\n", nvtxs, graph->pwgts[0], graph->pwgts[1], graph->mincut, bnvtxs[0], bnvtxs[1]-bnvtxs[0], csize));146147for (i=0; i<csize; i++) {148j = ivmap[cover[i]];149where[j] = 2;150}151}152else {153IFSET(ctrl->dbglvl, METIS_DBG_SEPINFO,154printf("Nvtxs: %6"PRIDX", [%5"PRIDX" %5"PRIDX"], Cut: %6"PRIDX", SS: [%6"PRIDX" %6"PRIDX"], Cover: %6"PRIDX"\n", nvtxs, graph->pwgts[0], graph->pwgts[1], graph->mincut, (idx_t)0, (idx_t)0, (idx_t)0));155}156157/* Prepare to refine the vertex separator */158icopy(nvtxs, graph->where, vmap);159160FreeRData(graph);161162Allocate2WayNodePartitionMemory(ctrl, graph);163icopy(nvtxs, vmap, graph->where);164165WCOREPOP;166167Compute2WayNodePartitionParams(ctrl, graph);168169ASSERT(CheckNodePartitionParams(graph));170171FM_2WayNodeRefine1Sided(ctrl, graph, ctrl->niter);172173ASSERT(IsSeparable(graph));174}175176177178