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

📄 subdomains.c

📁 多层权核k均值算法
💻 C
📖 第 1 页 / 共 3 页
字号:
        if (pwgts[to]+vwgt <= maxwgt[to] || itpwgts[from]*(pwgts[to]+vwgt) <= itpwgts[to]*pwgts[from])           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 (!phtable[to])          continue;        if (itpwgts[myedegrees[k].pid]*pwgts[to] < itpwgts[to]*pwgts[myedegrees[k].pid])           k = j;      }      to = myedegrees[k].pid;      if (pwgts[from] < maxwgt[from] && pwgts[to] > minwgt[to] && myedegrees[k].ed-myrinfo->id < 0)         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 pmat to reflect the move of 'i' */      pmat[from*nparts+to] += (myrinfo->id-myedegrees[k].ed);      pmat[to*nparts+from] += (myrinfo->id-myedegrees[k].ed);      if (pmat[from*nparts+to] == 0) {        ndoms[from]--;        if (ndoms[from]+1 == maxndoms)          maxndoms = ndoms[idxamax(nparts, ndoms)];      }      if (pmat[to*nparts+from] == 0) {        ndoms[to]--;        if (ndoms[to]+1 == maxndoms)          maxndoms = ndoms[idxamax(nparts, ndoms)];      }      /* Update where, weight, and ID/ED information of the vertex you moved */      where[i] = to;      INC_DEC(pwgts[to], pwgts[from], vwgt);      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 == 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));        oldgain = (myrinfo->ed-myrinfo->id);        if (me == from) {          INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]);          if (myrinfo->ed > 0 && bndptr[ii] == -1)            BNDInsert(nbnd, bndind, bndptr, ii);        }        else if (me == to) {          INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]);          if (myrinfo->ed == 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];          }        }        /* Update pmat to reflect the move of 'i' for domains other than 'from' and 'to' */        if (me != from && me != to) {          pmat[me*nparts+from] -= adjwgt[j];          pmat[from*nparts+me] -= adjwgt[j];          if (pmat[me*nparts+from] == 0) {            ndoms[me]--;            if (ndoms[me]+1 == maxndoms)              maxndoms = ndoms[idxamax(nparts, ndoms)];          }          if (pmat[from*nparts+me] == 0) {            ndoms[from]--;            if (ndoms[from]+1 == maxndoms)              maxndoms = ndoms[idxamax(nparts, ndoms)];          }          if (pmat[me*nparts+to] == 0) {            ndoms[me]++;            if (ndoms[me] > maxndoms) {              printf("You just increased the maxndoms: %d %d\n", ndoms[me], maxndoms);              maxndoms = ndoms[me];            }          }          if (pmat[to*nparts+me] == 0) {            ndoms[to]++;            if (ndoms[to] > maxndoms) {              printf("You just increased the maxndoms: %d %d\n", ndoms[to], maxndoms);              maxndoms = ndoms[to];            }          }          pmat[me*nparts+to] += adjwgt[j];          pmat[to*nparts+me] += adjwgt[j];        }        /* Update the queue */        if (me == to || me == from) {           gain = myrinfo->ed-myrinfo->id;          if (moved[ii] == 2) {            if (myrinfo->ed > 0)              PQueueUpdate(&queue, ii, oldgain, gain);            else {              PQueueDelete(&queue, ii, oldgain);              moved[ii] = -1;            }          }          else if (moved[ii] == -1 && myrinfo->ed > 0) {            PQueueInsert(&queue, ii, gain);            moved[ii] = 2;          }        }         ASSERT(myrinfo->ndegrees <= xadj[ii+1]-xadj[ii]);        ASSERT(CheckRInfo(myrinfo));      }      nmoves++;    }    graph->nbnd = nbnd;    IFSET(ctrl->dbglvl, DBG_REFINE,       printf("\t[%6d %6d], Balance: %5.3f, Nb: %6d. Nmoves: %5d, Cut: %6d, %d\n",               pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)],               1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nbnd, nmoves, graph->mincut,idxsum(nparts, ndoms)));  }  PQueueFree(ctrl, &queue);  idxwspacefree(ctrl, nparts);  idxwspacefree(ctrl, nparts);  idxwspacefree(ctrl, nparts);  idxwspacefree(ctrl, nparts);  idxwspacefree(ctrl, nparts);  idxwspacefree(ctrl, nvtxs);  idxwspacefree(ctrl, nvtxs);}/************************************************************************** This function computes the subdomain graph**************************************************************************/void PrintSubDomainGraph(GraphType *graph, int nparts, idxtype *where){  int i, j, k, me, nvtxs, total, max;  idxtype *xadj, *adjncy, *adjwgt, *pmat;  nvtxs = graph->nvtxs;  xadj = graph->xadj;  adjncy = graph->adjncy;  adjwgt = graph->adjwgt;  pmat = idxsmalloc(nparts*nparts, 0, "ComputeSubDomainGraph: pmat");  for (i=0; i<nvtxs; i++) {    me = where[i];    for (j=xadj[i]; j<xadj[i+1]; j++) {      k = adjncy[j];      if (where[k] != me)         pmat[me*nparts+where[k]] += adjwgt[j];    }  }  /* printf("Subdomain Info\n"); */  total = max = 0;  for (i=0; i<nparts; i++) {    for (k=0, j=0; j<nparts; j++) {      if (pmat[i*nparts+j] > 0)        k++;    }    total += k;    if (k > max)      max = k;/*    printf("%2d -> %2d  ", i, k);    for (j=0; j<nparts; j++) {      if (pmat[i*nparts+j] > 0)        printf("[%2d %4d] ", j, pmat[i*nparts+j]);    }    printf("\n");*/  }  printf("Total adjacent subdomains: %d, Max: %d\n", total, max);  free(pmat);}/************************************************************************** This function computes the subdomain graph**************************************************************************/void ComputeSubDomainGraph(GraphType *graph, int nparts, idxtype *pmat, idxtype *ndoms){  int i, j, k, me, nvtxs, ndegrees;  idxtype *xadj, *adjncy, *adjwgt, *where;  RInfoType *rinfo;  EDegreeType *edegrees;  nvtxs = graph->nvtxs;  xadj = graph->xadj;  adjncy = graph->adjncy;  adjwgt = graph->adjwgt;  where = graph->where;  rinfo = graph->rinfo;  idxset(nparts*nparts, 0, pmat);  for (i=0; i<nvtxs; i++) {    if (rinfo[i].ed > 0) {      me = where[i];      ndegrees = rinfo[i].ndegrees;      edegrees = rinfo[i].edegrees;      k = me*nparts;      for (j=0; j<ndegrees; j++)         pmat[k+edegrees[j].pid] += edegrees[j].ed;    }  }  for (i=0; i<nparts; i++) {    ndoms[i] = 0;    for (j=0; j<nparts; j++) {      if (pmat[i*nparts+j] > 0)        ndoms[i]++;    }  }}/************************************************************************** This function computes the subdomain graph**************************************************************************/void EliminateSubDomainEdges(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts){  int i, ii, j, k, me, other, nvtxs, total, max, avg, totalout, nind, ncand, ncand2, target, target2, nadd;  int min, move, cpwgt, tvwgt;  idxtype *xadj, *adjncy, *vwgt, *adjwgt, *pwgts, *where, *maxpwgt, *pmat, *ndoms, *mypmat, *otherpmat, *ind;  KeyValueType *cand, *cand2;  nvtxs = graph->nvtxs;  xadj = graph->xadj;  adjncy = graph->adjncy;  vwgt = graph->vwgt;  adjwgt = graph->adjwgt;  where = graph->where;  pwgts = graph->pwgts;  /* We assume that this is properly initialized */  maxpwgt = idxwspacemalloc(ctrl, nparts);  ndoms = idxwspacemalloc(ctrl, nparts);  otherpmat = idxwspacemalloc(ctrl, nparts);  ind = idxwspacemalloc(ctrl, nvtxs);  pmat = ctrl->wspace.pmat;  cand = (KeyValueType *)GKmalloc(nparts*sizeof(KeyValueType), "EliminateSubDomainEdges: cand");  cand2 = (KeyValueType *)GKmalloc(nparts*sizeof(KeyValueType), "EliminateSubDomainEdges: cand");  /* Compute the pmat matrix and ndoms */  ComputeSubDomainGraph(graph, nparts, pmat, ndoms);  /* Compute the maximum allowed weight for each domain */  tvwgt = idxsum(nparts, pwgts);  for (i=0; i<nparts; i++)    maxpwgt[i] = 1.25*tpwgts[i]*tvwgt;  /* Get into the loop eliminating subdomain connections */  for (;;) {    total = idxsum(nparts, ndoms);    avg = total/nparts;    max = ndoms[idxamax(nparts, ndoms)];    /* printf("Adjacent Subdomain Stats: Total: %3d, Max: %3d, Avg: %3d [%5d]\n", total, max, avg, idxsum(nparts*nparts, pmat)); */    if (max < 1.4*avg)      break;    me = idxamax(nparts, ndoms);    mypmat = pmat + me*nparts;    totalout = idxsum(nparts, mypmat);    /*printf("Me: %d, TotalOut: %d,\n", me, totalout);*/    /* Sort the connections according to their cut */    for (ncand2=0, i=0; i<nparts; i++) {      if (mypmat[i] > 0) {        cand2[ncand2].key = mypmat[i];        cand2[ncand2++].val = i;      }    }    ikeysort(ncand2, cand2);    move = 0;    for (min=0; min<ncand2; min++) {      if (cand2[min].key > totalout/(2*ndoms[me]))         break;      other = cand2[min].val;      /*printf("\tMinOut: %d to %d\n", mypmat[other], other);*/      idxset(nparts, 0, otherpmat);      /* Go and find the vertices in 'other' that are connected in 'me' */      for (nind=0, i=0; i<nvtxs; i++) {        if (where[i] == other) {          for (j=xadj[i]; j<xadj[i+1]; j++) {            if (where[adjncy[j]] == me) {              ind[nind++] = i;              break;            }          }        }      }      /* Go and construct the otherpmat to see where these nind vertices are connected to */      for (cpwgt=0, ii=0; ii<nind; ii++) {        i = ind[ii];        cpwgt += vwgt[i];        for (j=xadj[i]; j<xadj[i+1]; j++)           otherpmat[where[adjncy[j]]] += adjwgt[j];      }      otherpmat[other] = 0;      for (ncand=0, i=0; i<nparts; i++) {        if (otherpmat[i] > 0) {          cand[ncand].key = -otherpmat[i];          cand[ncand++].val = i;        }      }      ikeysort(ncand, cand);      /*        * Go through and the select the first domain that is common with 'me', and       * does not increase the ndoms[target] higher than my ndoms, subject to the       * maxpwgt constraint. Traversal is done from the mostly connected to the least.       */      target = target2 = -1;      for (i=0; i<ncand; i++) {        k = cand[i].val;        if (mypmat[k] > 0) {          if (pwgts[k] + cpwgt > maxpwgt[k])  /* Check if balance will go off */            continue;          for (j=0; j<nparts; j++) {            if (otherpmat[j] > 0 && ndoms[j] >= ndoms[me]-1 && pmat[nparts*j+k] == 0)              break;          }          if (j == nparts) { /* No bad second level effects */            for (nadd=0, j=0; j<nparts; j++) {              if (otherpmat[j] > 0 && pmat[nparts*k+j] == 0)                nadd++;            }            /*printf("\t\tto=%d, nadd=%d, %d\n", k, nadd, ndoms[k]);*/            if (target2 == -1 && ndoms[k]+nadd < ndoms[me]) {              target2 = k;            }            if (nadd == 0) {              target = k;              break;            }          }        }      }      if (target == -1 && target2 != -1)        target = target2;      if (target == -1) {        /* printf("\t\tCould not make the move\n");*/        continue;      }

⌨️ 快捷键说明

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