⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mkwayfmh.c

📁 多层权核k均值算法
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * mkwayfmh.c * * This file contains code that implements the multilevel k-way refinement * * Started 7/28/97 * George * * $Id: mkwayfmh.c,v 1.1 1998/11/27 17:59:24 karypis Exp $ * */#include <metis.h>/************************************************************************** This function performs k-way refinement**************************************************************************/void MCRandom_KWayEdgeRefineHorizontal(CtrlType *ctrl, GraphType *graph, int nparts,        float *orgubvec, int npasses){  int i, ii, iii, j, jj, k, l, pass, nvtxs, ncon, nmoves, nbnd, myndegrees, same;   int from, me, to, oldcut, gain;  idxtype *xadj, *adjncy, *adjwgt;  idxtype *where, *perm, *bndptr, *bndind;  EDegreeType *myedegrees;  RInfoType *myrinfo;  float *npwgts, *nvwgt, *minwgt, *maxwgt, maxlb, minlb, ubvec[MAXNCON], tvec[MAXNCON];  nvtxs = graph->nvtxs;  ncon = graph->ncon;  xadj = graph->xadj;  adjncy = graph->adjncy;  adjwgt = graph->adjwgt;  bndptr = graph->bndptr;  bndind = graph->bndind;  where = graph->where;  npwgts = graph->npwgts;    /* Setup the weight intervals of the various subdomains */  minwgt =  fwspacemalloc(ctrl, nparts*ncon);  maxwgt = fwspacemalloc(ctrl, nparts*ncon);  /* See if the orgubvec consists of identical constraints */  maxlb = minlb = orgubvec[0];  for (i=1; i<ncon; i++) {    minlb = (orgubvec[i] < minlb ? orgubvec[i] : minlb);    maxlb = (orgubvec[i] > maxlb ? orgubvec[i] : maxlb);  }  same = (fabs(maxlb-minlb) < .01 ? 1 : 0);  /* Let's not get very optimistic. Let Balancing do the work */  ComputeHKWayLoadImbalance(ncon, nparts, npwgts, ubvec);  for (i=0; i<ncon; i++)    ubvec[i] = amax(ubvec[i], orgubvec[i]);  if (!same) {    for (i=0; i<nparts; i++) {      for (j=0; j<ncon; j++) {        maxwgt[i*ncon+j] = ubvec[j]/nparts;        minwgt[i*ncon+j] = 1.0/(ubvec[j]*nparts);      }    }  }  else {    maxlb = ubvec[0];    for (i=1; i<ncon; i++)       maxlb = (ubvec[i] > maxlb ? ubvec[i] : maxlb);    for (i=0; i<nparts; i++) {      for (j=0; j<ncon; j++) {        maxwgt[i*ncon+j] = maxlb/nparts;        minwgt[i*ncon+j] = 1.0/(maxlb*nparts);      }    }  }  perm = idxwspacemalloc(ctrl, nvtxs);  if (ctrl->dbglvl&DBG_REFINE) {    printf("Partitions: [%5.4f %5.4f], Nv-Nb[%6d %6d]. Cut: %6d, LB: ",            npwgts[samin(ncon*nparts, npwgts)], npwgts[samax(ncon*nparts, npwgts)],             graph->nvtxs, graph->nbnd, graph->mincut);    ComputeHKWayLoadImbalance(ncon, nparts, npwgts, tvec);    for (i=0; i<ncon; i++)      printf("%.3f ", tvec[i]);    printf("\n");  }  for (pass=0; pass<npasses; pass++) {    ASSERT(ComputeCut(graph, where) == graph->mincut);    oldcut = graph->mincut;    nbnd = graph->nbnd;    RandomPermute(nbnd, perm, 1);    for (nmoves=iii=0; iii<graph->nbnd; iii++) {      ii = perm[iii];      if (ii >= nbnd)        continue;      i = bndind[ii];      myrinfo = graph->rinfo+i;      if (myrinfo->ed >= myrinfo->id) { /* Total ED is too high */        from = where[i];        nvwgt = graph->nvwgt+i*ncon;        if (myrinfo->id > 0 && AreAllHVwgtsBelow(ncon, 1.0, npwgts+from*ncon, -1.0, nvwgt, minwgt+from*ncon))           continue;   /* This cannot be moved! */        myedegrees = myrinfo->edegrees;        myndegrees = myrinfo->ndegrees;        for (k=0; k<myndegrees; k++) {          to = myedegrees[k].pid;          gain = myedegrees[k].ed - myrinfo->id;           if (gain >= 0 &&               (AreAllHVwgtsBelow(ncon, 1.0, npwgts+to*ncon, 1.0, nvwgt, maxwgt+to*ncon) ||               IsHBalanceBetterFT(ncon, nparts, npwgts+from*ncon, npwgts+to*ncon, nvwgt, ubvec)))            break;        }        if (k == myndegrees)          continue;  /* break out if you did not find a candidate */        for (j=k+1; j<myndegrees; j++) {          to = myedegrees[j].pid;          if ((myedegrees[j].ed > myedegrees[k].ed &&               (AreAllHVwgtsBelow(ncon, 1.0, npwgts+to*ncon, 1.0, nvwgt, maxwgt+to*ncon) ||                IsHBalanceBetterFT(ncon, nparts, npwgts+from*ncon, npwgts+to*ncon, nvwgt, ubvec))) ||              (myedegrees[j].ed == myedegrees[k].ed &&                IsHBalanceBetterTT(ncon, nparts, npwgts+myedegrees[k].pid*ncon, npwgts+to*ncon, nvwgt, ubvec)))            k = j;        }        to = myedegrees[k].pid;        if (myedegrees[k].ed-myrinfo->id == 0             && !IsHBalanceBetterFT(ncon, nparts, npwgts+from*ncon, npwgts+to*ncon, nvwgt, ubvec)            && AreAllHVwgtsBelow(ncon, 1.0, npwgts+from*ncon, 0.0, npwgts+from*ncon, maxwgt+from*ncon))           continue;        /*=====================================================================        * If we got here, we can now move the vertex from 'from' to 'to'         *======================================================================*/        graph->mincut -= myedegrees[k].ed-myrinfo->id;        IFSET(ctrl->dbglvl, DBG_MOVEINFO, printf("\t\tMoving %6d to %3d. Gain: %4d. Cut: %6d\n", i, to, myedegrees[k].ed-myrinfo->id, graph->mincut));        /* Update where, weight, and ID/ED information of the vertex you moved */        saxpy(ncon, 1.0, nvwgt, 1, npwgts+to*ncon, 1);        saxpy(ncon, -1.0, nvwgt, 1, npwgts+from*ncon, 1);        where[i] = to;        myrinfo->ed += myrinfo->id-myedegrees[k].ed;        SWAP(myrinfo->id, myedegrees[k].ed, j);        if (myedegrees[k].ed == 0)           myedegrees[k] = myedegrees[--myrinfo->ndegrees];        else          myedegrees[k].pid = from;        if (myrinfo->ed-myrinfo->id < 0)          BNDDelete(nbnd, bndind, bndptr, i);        /* Update the degrees of adjacent vertices */        for (j=xadj[i]; j<xadj[i+1]; j++) {          ii = adjncy[j];          me = where[ii];          myrinfo = graph->rinfo+ii;          if (myrinfo->edegrees == NULL) {            myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree;            ctrl->wspace.cdegree += xadj[ii+1]-xadj[ii];          }          myedegrees = myrinfo->edegrees;          ASSERT(CheckRInfo(myrinfo));          if (me == from) {            INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]);            if (myrinfo->ed-myrinfo->id >= 0 && bndptr[ii] == -1)              BNDInsert(nbnd, bndind, bndptr, ii);          }          else if (me == to) {            INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]);            if (myrinfo->ed-myrinfo->id < 0 && bndptr[ii] != -1)              BNDDelete(nbnd, bndind, bndptr, ii);          }          /* Remove contribution from the .ed of 'from' */          if (me != from) {            for (k=0; k<myrinfo->ndegrees; k++) {              if (myedegrees[k].pid == from) {                if (myedegrees[k].ed == adjwgt[j])                  myedegrees[k] = myedegrees[--myrinfo->ndegrees];                else                  myedegrees[k].ed -= adjwgt[j];                break;              }            }          }          /* Add contribution to the .ed of 'to' */          if (me != to) {            for (k=0; k<myrinfo->ndegrees; k++) {              if (myedegrees[k].pid == to) {                myedegrees[k].ed += adjwgt[j];                break;              }            }            if (k == myrinfo->ndegrees) {              myedegrees[myrinfo->ndegrees].pid = to;              myedegrees[myrinfo->ndegrees++].ed = adjwgt[j];            }          }          ASSERT(myrinfo->ndegrees <= xadj[ii+1]-xadj[ii]);          ASSERT(CheckRInfo(myrinfo));        }        nmoves++;      }    }    graph->nbnd = nbnd;    if (ctrl->dbglvl&DBG_REFINE) {      printf("\t [%5.4f %5.4f], Nb: %6d, Nmoves: %5d, Cut: %6d, LB: ",              npwgts[samin(ncon*nparts, npwgts)], npwgts[samax(ncon*nparts, npwgts)],               nbnd, nmoves, graph->mincut);      ComputeHKWayLoadImbalance(ncon, nparts, npwgts, tvec);      for (i=0; i<ncon; i++)        printf("%.3f ", tvec[i]);      printf("\n");    }    if (graph->mincut == oldcut)      break;  }  fwspacefree(ctrl, ncon*nparts);  fwspacefree(ctrl, ncon*nparts);  idxwspacefree(ctrl, nvtxs);}/************************************************************************** This function performs k-way refinement**************************************************************************/void MCGreedy_KWayEdgeBalanceHorizontal(CtrlType *ctrl, GraphType *graph, int nparts,        float *ubvec, int npasses){  int i, ii, iii, j, jj, k, l, pass, nvtxs, ncon, nbnd, myndegrees, oldgain, gain, nmoves;   int from, me, to, oldcut;  idxtype *xadj, *adjncy, *adjwgt;  idxtype *where, *perm, *bndptr, *bndind, *moved;  EDegreeType *myedegrees;  RInfoType *myrinfo;  PQueueType queue;  float *npwgts, *nvwgt, *minwgt, *maxwgt, tvec[MAXNCON];  nvtxs = graph->nvtxs;  ncon = graph->ncon;  xadj = graph->xadj;  adjncy = graph->adjncy;  adjwgt = graph->adjwgt;  bndind = graph->bndind;  bndptr = graph->bndptr;  where = graph->where;  npwgts = graph->npwgts;    /* Setup the weight intervals of the various subdomains */  minwgt =  fwspacemalloc(ctrl, ncon*nparts);  maxwgt = fwspacemalloc(ctrl, ncon*nparts);  for (i=0; i<nparts; i++) {    for (j=0; j<ncon; j++) {      maxwgt[i*ncon+j] = ubvec[j]/nparts;      minwgt[i*ncon+j] = 1.0/(ubvec[j]*nparts);    }  }  perm = idxwspacemalloc(ctrl, nvtxs);  moved = idxwspacemalloc(ctrl, nvtxs);  PQueueInit(ctrl, &queue, nvtxs, graph->adjwgtsum[idxamax(nvtxs, graph->adjwgtsum)]);  if (ctrl->dbglvl&DBG_REFINE) {    printf("Partitions: [%5.4f %5.4f], Nv-Nb[%6d %6d]. Cut: %6d, LB: ",            npwgts[samin(ncon*nparts, npwgts)], npwgts[samax(ncon*nparts, npwgts)],             graph->nvtxs, graph->nbnd, graph->mincut);    ComputeHKWayLoadImbalance(ncon, nparts, npwgts, tvec);    for (i=0; i<ncon; i++)      printf("%.3f ", tvec[i]);    printf("[B]\n");  }  for (pass=0; pass<npasses; pass++) {    ASSERT(ComputeCut(graph, where) == graph->mincut);    /* Check to see if things are out of balance, given the tolerance */    if (MocIsHBalanced(ncon, nparts, npwgts, ubvec))      break;    PQueueReset(&queue);    idxset(nvtxs, -1, moved);    oldcut = graph->mincut;    nbnd = graph->nbnd;    RandomPermute(nbnd, perm, 1);    for (ii=0; ii<nbnd; ii++) {      i = bndind[perm[ii]];      PQueueInsert(&queue, i, graph->rinfo[i].ed - graph->rinfo[i].id);      moved[i] = 2;    }    nmoves = 0;    for (;;) {      if ((i = PQueueGetMax(&queue)) == -1)         break;      moved[i] = 1;      myrinfo = graph->rinfo+i;      from = where[i];      nvwgt = graph->nvwgt+i*ncon;      if (AreAllHVwgtsBelow(ncon, 1.0, npwgts+from*ncon, -1.0, nvwgt, minwgt+from*ncon))        continue;   /* This cannot be moved! */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -