void GrowBisectionNode2(ctrl_t *ctrl, graph_t *graph, real_t *ntpwgts, 
         idx_t niparts)
{
  idx_t i, j, k, nvtxs, bestcut=0, mincut, inbfs;
  idx_t *xadj, *where, *bndind, *bestwhere;

  WCOREPUSH;

  nvtxs  = graph->nvtxs;
  xadj   = graph->xadj;

  /* 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");
  
  bestwhere = iwspacemalloc(ctrl, nvtxs);

  where  = graph->where;
  bndind = graph->bndind;

  for (inbfs=0; inbfs<niparts; inbfs++) {
    iset(nvtxs, 1, where);
    if (inbfs > 0)
      where[irandInRange(nvtxs)] = 0;

    Compute2WayPartitionParams(ctrl, graph);
    General2WayBalance(ctrl, graph, ntpwgts);
    FM_2WayRefine(ctrl, graph, ntpwgts, ctrl->niter);

    /* 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, 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;
}
Пример #2
0
void Refine2WayNode(ctrl_t *ctrl, graph_t *orggraph, graph_t *graph)
{

  IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_startcputimer(ctrl->UncoarsenTmr));

  if (graph == orggraph) {
    Compute2WayNodePartitionParams(ctrl, graph);
  }
  else {
    do {
      graph = graph->finer;

      IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_startcputimer(ctrl->ProjectTmr));
      Project2WayNodePartition(ctrl, graph);
      IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_stopcputimer(ctrl->ProjectTmr));

      IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_startcputimer(ctrl->RefTmr));
      FM_2WayNodeBalance(ctrl, graph); 

      ASSERT(CheckNodePartitionParams(graph));

      switch (ctrl->rtype) {
        case METIS_RTYPE_SEP2SIDED:
          FM_2WayNodeRefine2Sided(ctrl, graph, ctrl->niter); 
          break;
        case METIS_RTYPE_SEP1SIDED:
          FM_2WayNodeRefine1Sided(ctrl, graph, ctrl->niter); 
          break;
        default:
          gk_errexit(SIGERR, "Unknown rtype of %d\n", ctrl->rtype);
      }
      IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_stopcputimer(ctrl->RefTmr));

    } while (graph != orggraph);
  }

  IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_stopcputimer(ctrl->UncoarsenTmr));
}
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;
}