Beispiel #1
0
void
improveDDSep(domdec_t *dd)
{ bucket_t *b_bucket, *w_bucket;
  PORD_INT      *xadj, *adjncy, *vwght, *vtype, *color, *cwght;
  PORD_INT      *tmp_color, *deltaS, *deltaB, *deltaW;
  PORD_INT      nvtx, weight, tmp_S, tmp_B, tmp_W;
  PORD_INT      pos, bestglobalpos, badflips, b_domain, w_domain, domain, nxtdomain;
  PORD_INT      fhead, ftail, u, v, i, istart, istop;
  FLOAT    bestglobalvalue, b_value, w_value, value;

  /* ======================================================================
     vtype[u]: (u domain)
         1 => color of domain u has not been changed
       < 0 => points to next domain in flipping list
              (fhead points to first, ftail points to last domain in list)
       = 0 => domain is last domain in flipping list
     ====================================================================== */

  nvtx = dd->G->nvtx;
  xadj = dd->G->xadj;
  adjncy = dd->G->adjncy;
  vwght = dd->G->vwght;
  vtype = dd->vtype;
  color = dd->color;
  cwght = dd->cwght;

  mymalloc(tmp_color, nvtx, PORD_INT);
  mymalloc(deltaS, nvtx, PORD_INT);
  mymalloc(deltaB, nvtx, PORD_INT);
  mymalloc(deltaW, nvtx, PORD_INT);

OUTER_LOOP_START:

  /* ----------------------------------------------------------------------
     copy data of actual bisection and initialize buckets and flipping list
     ---------------------------------------------------------------------- */
  tmp_S = cwght[GRAY];
  tmp_B = cwght[BLACK];
  tmp_W = cwght[WHITE];
  bestglobalpos = badflips = 0;
  bestglobalvalue = F(tmp_S, tmp_B, tmp_W);

  b_bucket = setupBucket(nvtx, nvtx, (nvtx >> 1));
  w_bucket = setupBucket(nvtx, nvtx, (nvtx >> 1));

  fhead = 0; ftail = -1;
  pos = 0;

  /* ----------------------------------------------------------
     initialize tmp_color, deltaB, and deltaW for all multisecs
     ---------------------------------------------------------- */
  for (u = 0; u < nvtx; u++)
    if (vtype[u] == 2)
     { deltaB[u] = deltaW[u] = 0;
       istart = xadj[u];
       istop = xadj[u+1];
       for (i = istart; i < istop; i++)
        { v = adjncy[i];
          if (color[v] == BLACK) deltaB[u]++;
          else deltaW[u]++;
        }
       if ((deltaB[u] > 0) && (deltaW[u] > 0))  /* update multisec coloring */
         tmp_color[u] = GRAY;
       else if (deltaB[u] > 0) tmp_color[u] = BLACK;
       else tmp_color[u] = WHITE;
       color[u] = tmp_color[u];
     }

  /* -----------------------------------------------------------------
     initialize tmp_color, deltaS,B,W for all domains and fill buckets
     ----------------------------------------------------------------- */
  for (u = 0; u < nvtx; u++)
    if (vtype[u] == 1)
     { tmp_color[u] = color[u];
       if (tmp_color[u] == BLACK)          /* domain may be flipped to WHITE */
        { deltaW[u] = vwght[u]; deltaB[u] = -deltaW[u]; deltaS[u] = 0;
          istart = xadj[u];
          istop = xadj[u+1];
          for (i = istart; i < istop; i++)
           { v = adjncy[i];                /* tmp_color[v] e {GRAY, BLACK} */
             weight = vwght[v];
             if (tmp_color[v] == BLACK)    /* multisec v will move into S */
              { deltaB[u] -= weight;
                deltaS[u] += weight;
              }
             else if (deltaB[v] == 1)      /* multisec v will move into W */
              { deltaW[u] += weight;
                deltaS[u] -= weight;
                deltaB[v] = -(u+1);
              }
           }
          insertBucket(b_bucket, deltaS[u], u);
        }
       if (tmp_color[u] == WHITE)          /* domain may be flipped to BLACK */
        { deltaB[u] = vwght[u]; deltaW[u] = -deltaB[u]; deltaS[u] = 0;
          istart = xadj[u];
          istop = xadj[u+1];
          for (i = istart; i < istop; i++)
           { v = adjncy[i];                /* tmp_color[v] e {GRAY, WHITE} */
             weight = vwght[v];
             if (tmp_color[v] == WHITE)    /* multisec v will move into S */
              { deltaW[u] -= weight;
                deltaS[u] += weight;
              }
             else if (deltaW[v] == 1)      /* multisec v will move into B */
              { deltaB[u] += weight;
                deltaS[u] -= weight;
                deltaW[v] = -(u+1);
              }
           }
          insertBucket(w_bucket, deltaS[u], u);
        }
     }

#ifdef DEBUG
  printf("starting inner loop: b_bucket->nobj %d, w_bucket->nobj %d\n",
         b_bucket->nobj, w_bucket->nobj);
  waitkey();
#endif

INNER_LOOP_START:

  /* -------------------------------------------
     extract best domain from b_bucket, w_bucket
     ------------------------------------------- */
  b_value = w_value = MAX_FLOAT;
  if ((b_domain = minBucket(b_bucket)) != -1)
   { b_value = F((tmp_S+deltaS[b_domain]), (tmp_B+deltaB[b_domain]),
                 (tmp_W+deltaW[b_domain]));

#ifdef DEBUG
     printf("best black domain: %d, deltaS %d, deltaB %d, deltaW %d, "
            "cost %7.2f\n", b_domain, deltaS[b_domain], deltaB[b_domain],
            deltaW[b_domain], b_value);
#endif
   }
  if ((w_domain = minBucket(w_bucket)) != -1)
   { w_value = F((tmp_S+deltaS[w_domain]), (tmp_B+deltaB[w_domain]),
                 (tmp_W+deltaW[w_domain]));

#ifdef DEBUG
     printf("best white domain: %d, deltaS %d, deltaB %d, deltaW %d, "
            "cost %7.2f\n", w_domain, deltaS[w_domain], deltaB[w_domain],
            deltaW[w_domain], w_value);
#endif
   }

  if ((b_domain == ERR) && (w_domain == ERR)) goto INNER_LOOP_END;

  if (b_value + EPS < w_value)
   { domain = b_domain; value = b_value;
     removeBucket(b_bucket, domain);
   }
  else
   { domain = w_domain; value = w_value;
     removeBucket(w_bucket, domain);
   }

#ifdef DEBUG
  printf(" domain %d removed from bucket\n", domain);
#endif

  /* -------------------------------------------------------------------
     flip the color of domain and put it in list of log. flipped domains
     ------------------------------------------------------------------- */
  if (ftail != -1)
    vtype[ftail] = -(domain+1);   /* append domain */
  else fhead = -(domain+1);       /* list starts with domain */
  vtype[domain] = 0;              /* mark end of list */
  ftail = domain;                 /* domain is last element in list */

  if (tmp_color[domain] == BLACK)
   { tmp_color[domain] = WHITE;
     updateB2W(w_bucket,b_bucket,dd,domain,tmp_color,deltaW,deltaB,deltaS);
   }
  else if (tmp_color[domain] == WHITE)
   { tmp_color[domain] = BLACK;
     updateW2B(w_bucket,b_bucket,dd,domain,tmp_color,deltaW,deltaB,deltaS);
   }
  tmp_S += deltaS[domain];
  tmp_B += deltaB[domain];
  tmp_W += deltaW[domain];

  pos++;
  if (value + EPS < bestglobalvalue)
   { bestglobalvalue = value;
     bestglobalpos = pos;
     badflips = 0;
   }
  else badflips++;
  if (badflips < MAX_BAD_FLIPS) goto INNER_LOOP_START;

INNER_LOOP_END:

  /* --------------------------------------------
     end of inner loop: now do the physical flips
     -------------------------------------------- */
  pos = 0;
  nxtdomain = fhead;
  while (nxtdomain != 0)
   { domain = -nxtdomain - 1;
     if (pos < bestglobalpos)
      { if (color[domain] == BLACK) color[domain] = WHITE;
        else color[domain] = BLACK;
        cwght[GRAY] += deltaS[domain];
        cwght[BLACK] += deltaB[domain];
        cwght[WHITE] += deltaW[domain];
        pos++;
      }
     nxtdomain = vtype[domain];
     vtype[domain] = 1;
   }

  /* ----------------------------------------------
     partition improved => re-start the whole stuff
     ---------------------------------------------- */
#ifdef DEBUG
  printf(" INNER_LOOP_END (#pyhs. flips %d): S %d, B %d, W %d (%7.2f)\n",
         bestglobalpos, cwght[GRAY], cwght[BLACK], cwght[WHITE],
         bestglobalvalue);
  waitkey();
#endif

  /* JY: moved next instruction after the two
   *     freeBucket instructions because
   *     this was the cause of a memory leak.
   * if (bestglobalpos > 0) goto OUTER_LOOP_START;
   */

  freeBucket(b_bucket);
  freeBucket(w_bucket);

  if (bestglobalpos > 0) goto OUTER_LOOP_START;
  free(tmp_color); free(deltaS); free(deltaB); free(deltaW);
}
Beispiel #2
0
int
eliminateStep(minprior_t *minprior, int istage, int scoretype)
{ gelim_t     *Gelim;
  bucket_t    *bucket;
  stageinfo_t *stageinfo;
  int         *stage, *reachset, *auxtmp;
  int         *xadj, *adjncy, *vwght, *len, *degree, *score;
  int         *pflag, *pnreach, nelim, minscr, vwghtu, u, v, i, istart, istop;
  FLOAT       tri, rec;

  Gelim = minprior->Gelim;
  bucket = minprior->bucket;
  stage = minprior->ms->stage;
  stageinfo = minprior->stageinfo + istage;
  reachset = minprior->reachset;
  pnreach = &(minprior->nreach);
  auxtmp = minprior->auxtmp;
  pflag = &(minprior->flag);

  xadj = Gelim->G->xadj;
  adjncy = Gelim->G->adjncy;
  vwght = Gelim->G->vwght;
  len = Gelim->len;
  degree = Gelim->degree;
  score = Gelim->score;

#ifdef DEBUG
  printf("\nStarting new elimination step (nedges %d, maxedges %d)\n",
         Gelim->G->nedges, Gelim->maxedges);
  /* waitkey(); */
#endif

  /* ----------------------
     check for empty bucket
     ---------------------- */
  if ((u = minBucket(bucket)) == -1)
    return(0);
  minscr = score[u];

  /* ----------------------------------------
     loop while nodes of minimum score remain
     ---------------------------------------- */
  nelim = 0;
  *pnreach = 0;
  while (TRUE)
   { vwghtu = vwght[u];

     /* --------------------------------------------------
        increment welim and nelim and remove u from bucket
        -------------------------------------------------- */
     removeBucket(bucket, u);
     stageinfo->welim += vwghtu;
     nelim++;

     /* -----------------------------------------------------------------
        call buildElement to create element u and merge u's boundary with 
        the nodes in reachset; remove any vertex from bucket that belongs
        to u's boundary and to the actual stage
        ----------------------------------------------------------------- */
     buildElement(Gelim, u);
     istart = xadj[u];
     istop = istart + len[u];
     for (i = istart; i < istop; i++)
      { v = adjncy[i];                 /* v belongs to u's boundary */
        if (auxtmp[v] < *pflag)        /* v not yet in reachset */
         { auxtmp[v] = *pflag;
           if (stage[v] <= istage)     /* v belongs to actual stage */
             removeBucket(bucket, v);
           reachset[(*pnreach)++] = v;
         }
      }

#ifdef DEBUG
     printf("Node %d (weight %d, score %d) eliminated: (boundary weight %d)\n",
            u, vwghtu, minscr, degree[u]);
     for (i = istart; i < istop; i++)
       printf("%4d (degree %2d)", adjncy[i], degree[adjncy[i]]);
     printf("\n");
#endif

      /* ---------------------------------------------------------------
         increment the storage and operation counts for this elim. stage
         --------------------------------------------------------------- */
     tri = vwghtu;
     rec = degree[u];
     stageinfo->nzf += (int)((tri * (tri+1)) / 2);
     stageinfo->nzf += (int)(tri * rec);
     stageinfo->ops += (tri*tri*tri) / 3.0 + (tri*tri) / 2.0 - (5*tri) / 6.0;
     stageinfo->ops += (tri*tri*rec) + (rec*(rec+1)*tri);

     /* ---------------------------------------------------------------
        end this elim. step, if one of the following conditions is true
         (1) no multiple elimination
         (2) bucket empty
         (3) no further variable with minimum score
        ---------------------------------------------------------------- */
     if (scoretype / 10 == 0)
       break;
     if ((u = minBucket(bucket)) == -1)
       break;
     if (score[u] > minscr)
       break;
   }

  /* -----------------------
     clear auxtmp and return
     ----------------------- */
  (*pflag)++;
  return(nelim);
}
Beispiel #3
0
void
updateW2B(bucket_t *w_bucket, bucket_t *b_bucket, domdec_t *dd, PORD_INT domain,
          PORD_INT *tmp_color, PORD_INT *deltaW, PORD_INT *deltaB, PORD_INT *deltaS)
{ PORD_INT *xadj, *adjncy, *vwght, *vtype;
  PORD_INT weight, u, v, i, istart, istop, j, jstart, jstop;

  xadj = dd->G->xadj;
  adjncy = dd->G->adjncy;
  vwght = dd->G->vwght;
  vtype = dd->vtype;

  istart = xadj[domain];
  istop = xadj[domain+1];
  for (i = istart; i < istop; i++)
   { u = adjncy[i];
     weight = vwght[u];
     jstart = xadj[u];
     jstop = xadj[u+1];

     /* ---------------------------------------------------------------
        subcase (1): before flipping domain to BLACK there was only one
          other BLACK domain v. update deltaW[v] and deltaS[v]
        --------------------------------------------------------------- */
     if (deltaB[u] < 0)
      { v = -(deltaB[u]+1);
        deltaB[u] = 1;

#ifdef DEBUG
        printf(" W2B case (1): (via multisec %d) removing domain %d from "
               "b_bucket\n", u, v);
#endif

        removeBucket(b_bucket, v);
        deltaW[v] -= weight; deltaS[v] += weight;
        insertBucket(b_bucket, deltaS[v], v);
      }

     /* ---------------------------------------------------------------
        subcase (2): all other domains are WHITE. update deltaW, deltaS
          of these WHITE domains. NOTE: subcase (3) may directly follow
        --------------------------------------------------------------- */
     if (deltaB[u] == 0)
      { tmp_color[u] = GRAY;
        for (j = jstart; j < jstop; j++)
         { v = adjncy[j];
           if (vtype[v] == 1)
            {
#ifdef DEBUG
              printf(" W2B case (2): (via multisec %d) removing domain %d from "
                     "w_bucket\n", u, v);
#endif

              removeBucket(w_bucket, v);
              deltaW[v] += weight; deltaS[v] -= weight;
              insertBucket(w_bucket, deltaS[v], v);
            }
         }
      }

     if (deltaW[u] < 0) deltaW[u] = 1;   /* the unique WHITE dom. flipped */
     deltaB[u]++; deltaW[u]--;

     /* -------------------------------------------------------------
        subcase (3): after flipping domain to BLACK there is only one
          remaining WHITE domain. search it and update deltaB, deltaS
          furthermore, store the remaining WHITE domain in deltaW[u]
        ------------------------------------------------------------- */
     if (deltaW[u] == 1)
      { for (j = jstart; j < jstop; j++)
         { v = adjncy[j];
           if ((tmp_color[v] == WHITE) && (vtype[v] == 1))
            {
#ifdef DEBUG
              printf(" W2B case (3): (via multisec %d) removing domain %d from "
                     "w_bucket\n", u, v);
#endif

              removeBucket(w_bucket, v);
              deltaB[v] += weight; deltaS[v] -= weight;
              deltaW[u] = -(v+1);
              insertBucket(w_bucket, deltaS[v], v);
            }
         }
      }

     /* ---------------------------------------------------------------
        subcase (4): after flipping domain to BLACK there is no other
          WHITE domain. update deltaB, deltaS of the BLACK domains
        --------------------------------------------------------------- */
     if (deltaW[u] == 0)
      { tmp_color[u] = BLACK;
        for (j = jstart; j < jstop; j++)
         { v = adjncy[j];
           if (vtype[v] == 1)
            {
#ifdef DEBUG
              printf(" W2B case (4): (via multisec %d) removing domain %d from "
                     "b_bucket\n", u, v);
#endif

              removeBucket(b_bucket, v);
              deltaB[v] -= weight; deltaS[v] += weight;
              insertBucket(b_bucket, deltaS[v], v);
            }
         }
      }
   }
}