示例#1
0
void 
movebilist (
    struct bilist *lptr,		/* ptr to element to move */
    struct bilist **oldlist,	/* head of list to remove it from */
    struct bilist **newlist	/* head of list to add it to */
)

/* Move an element from a old bidirectional list to new one. */
{
    removebilist(lptr, oldlist);

    add2bilist(lptr, newlist);
}
示例#2
0
int nway_klv(struct vtx_data **graph,      /* data structure for graph */
             int               nvtxs,      /* number of vtxs in graph */
             struct bilist **  lbuckets,   /* array of lists for bucket sort */
             struct bilist **  rbuckets,   /* array of lists for bucket sort */
             struct bilist *   llistspace, /* list data structure for each vertex */
             struct bilist *   rlistspace, /* list data structure for each vertex */
             int *             ldvals,     /* d-values for each transition */
             int *             rdvals,     /* d-values for each transition */
             int *             sets,       /* processor each vertex is assigned to */
             int               maxdval,    /* maximum d-value for a vertex */
             double *          goal,       /* desired set sizes */
             int               max_dev,    /* largest allowed deviation from balance */
             int **            bndy_list,  /* list of vertices on boundary (0 ends) */
             double *          weightsum   /* sum of vweights in each set (in and out) */
             )
{
  struct bilist **to_buckets;           /* buckets I'm moving to */
  struct bilist **from_buckets;         /* buckets I'm moving from */
  struct bilist * to_listspace;         /* list structure I'm moving to */
  struct bilist * from_listspace;       /* list structure I'm moving from */
  struct bilist * out_list;             /* list of vtxs moved out of separator */
  int *           to_dvals;             /* d-values I'm moving to */
  int *           from_dvals;           /* d-values I'm moving from */
  extern double   kl_bucket_time;       /* time spent in KL bucketsort */
  extern int      KL_BAD_MOVES;         /* # bad moves in a row to stop KL */
  extern int      DEBUG_KL;             /* debug flag for KL */
  extern int      KL_NTRIES_BAD;        /* number of unhelpful passes before quitting */
  extern int      KL_MAX_PASS;          /* maximum # outer KL loops */
  int *           bspace;               /* list of active vertices for bucketsort */
  int *           edges;                /* edge list for a vertex */
  int *           edges2;               /* edge list for a vertex */
  int *           bdy_ptr;              /* loops through bndy_list */
  double          total_weight;         /* weight of all vertices */
  double          partial_weight;       /* weight of vertices not in separator */
  double          ratio;                /* fraction of weight not in separator */
  double          time;                 /* timing parameter */
  double          delta0;               /* largest negative deviation from goal size */
  double          delta1;               /* largest negative deviation from goal size */
  double          left_imbalance = 0.0; /* imbalance if I move to the left */
  double          right_imbalance;      /* imbalance if I move to the right */
  double          balance_val;          /* how imbalanced is it */
  double          balance_best;         /* best balance yet if trying hard */
  int             flag;                 /* condition indicator */
  int             to = -1, from;        /* sets moving into / out of */
  int             rtop, ltop;           /* top of each set of buckets */
  int *           to_top;               /* ptr to top of set moving to */
  int             lvtx, rvtx;           /* next vertex to move left/right */
  int             lweight, rweight;     /* weights of moving vertices */
  int             weightfrom = 0;       /* weight moving out of a set */
  int             list_length;          /* how long is list of vertices to bucketsort? */
  int             balanced;             /* is partition balanced? */
  int             temp_balanced;        /* is intermediate partition balanced? */
  int             ever_balanced;        /* has any partition been balanced? */
  int             bestvtx = -1;         /* best vertex to move */
  int             bestval = -1;         /* best change in value for a vtx move */
  int             vweight;              /* weight of best vertex */
  int             gtotal;               /* sum of changes from moving */
  int             improved;             /* total improvement from KL */
  double          bestg;                /* maximum gtotal found in KL loop */
  double          bestg_min;            /* smaller than any possible bestg */
  int             beststep;             /* step where maximum value occurred */
  int             bestlength;           /* step where maximum value occurred */
  int             neighbor;             /* neighbor of a vertex */
  int             step_cutoff;          /* number of negative steps in a row allowed */
  int             cost_cutoff;          /* amount of negative d-values allowed */
  int             neg_steps;            /* number of negative steps in a row */
  int             neg_cost;             /* decrease in sum of d-values */
  int             vtx;                  /* vertex number */
  int             dval;                 /* dval of a vertex */
  int             group, group2;        /* set that a vertex is assigned to */
  int             left_too_big;         /* is left set too large? */
  int             right_too_big;        /* is right set too large? */
  int             vwgt;                 /* weight of a vertex */
  int             gain;                 /* reduction in separator due to a move */
  int             neighbor2;            /* neighbor of a vertex */
  int             step;                 /* loops through movements of vertices */
  int             parity;               /* sort forwards or backwards? */
  int             done;                 /* has termination criteria been achieved? */
  int             nbad;                 /* number of unhelpful passes in a row */
  int             npass;                /* total number of passes */
  int             nbadtries;            /* number of unhelpful passes before quitting */
  int             enforce_balance;      /* force a balanced partition? */
  int             enforce_balance_hard; /* really force a balanced partition? */
  int             i, j, k;              /* loop counters */

  double seconds(), drandom();
  int    make_sep_list();
  void   bucketsortsv(), clear_dvals(), p1bucket();
  void   removebilist(), movebilist(), add2bilist();

  nbadtries = KL_NTRIES_BAD;

  enforce_balance      = FALSE;
  enforce_balance_hard = FALSE;

  total_weight = goal[0] + goal[1];

  bspace = smalloc_ret((nvtxs + 1) * sizeof(int));

  if (bspace == NULL) {
    return (1);
  }

  bdy_ptr     = *bndy_list;
  list_length = 0;
  while (*bdy_ptr != 0) {
    bspace[list_length++] = *bdy_ptr++;
  }

  sfree(*bndy_list);

  clear_dvals(graph, nvtxs, ldvals, rdvals, bspace, list_length);

  step_cutoff = KL_BAD_MOVES;
  cost_cutoff = maxdval * step_cutoff / 7;
  if (cost_cutoff < step_cutoff)
    cost_cutoff = step_cutoff;

  partial_weight = weightsum[0] + weightsum[1];
  ratio          = partial_weight / total_weight;
  delta0         = fabs(weightsum[0] - goal[0] * ratio);
  delta1         = fabs(weightsum[1] - goal[1] * ratio);
  balanced =
      (delta0 + delta1 <= max_dev) && weightsum[0] != total_weight && weightsum[1] != total_weight;

  bestg_min = -2.0 * nvtxs * maxdval;
  parity    = FALSE;
  nbad      = 0;
  npass     = 0;
  improved  = 0;
  done      = FALSE;
  while (!done) {
    npass++;
    ever_balanced = FALSE;
    balance_best  = delta0 + delta1;

    /* Initialize various quantities. */
    ltop = rtop = 2 * maxdval;

    gtotal     = 0;
    bestg      = bestg_min;
    beststep   = -1;
    bestlength = list_length;
    out_list   = NULL;

    neg_steps = 0;

    /* Compute the initial d-values, and bucket-sort them. */
    time = seconds();
    bucketsortsv(graph, nvtxs, lbuckets, rbuckets, llistspace, rlistspace, ldvals, rdvals, sets,
                 maxdval, parity, bspace, list_length);
    parity = !parity;
    kl_bucket_time += seconds() - time;

    if (DEBUG_KL > 2) {
      printf("After sorting, left buckets:\n");
      p1bucket(lbuckets, llistspace, maxdval);
      printf("              right buckets:\n");
      p1bucket(rbuckets, rlistspace, maxdval);
    }

    /* Now determine the set of vertex moves. */

    for (step = 1;; step++) {

      /* Find the highest d-value in each set. */
      /* But only consider moves from large to small sets, or moves */
      /* in which balance is preserved. */
      /* Break ties in some nonarbitrary manner. */
      bestval = -maxdval - 1;

      partial_weight = weightsum[0] + weightsum[1];
      ratio          = partial_weight / total_weight;
      left_too_big   = (weightsum[0] > (goal[0] + .5 * max_dev) * ratio);
      right_too_big  = (weightsum[1] > (goal[1] + .5 * max_dev) * ratio);

      while (ltop >= 0 && lbuckets[ltop] == NULL) {
        --ltop;
      }
      if (ltop >= 0 && !left_too_big) {
        lvtx           = ((long)lbuckets[ltop] - (long)llistspace) / sizeof(struct bilist);
        lweight        = graph[lvtx]->vwgt;
        rweight        = lweight - (ltop - maxdval);
        weightfrom     = rweight;
        to             = 0;
        bestvtx        = lvtx;
        bestval        = ltop - maxdval;
        partial_weight = weightsum[0] + lweight + weightsum[1] - rweight;
        ratio          = partial_weight / total_weight;
        left_imbalance = max(fabs(weightsum[0] + lweight - goal[0] * ratio),
                             fabs(weightsum[1] - rweight - goal[1] * ratio));
      }

      while (rtop >= 0 && rbuckets[rtop] == NULL) {
        --rtop;
      }
      if (rtop >= 0 && !right_too_big) {
        rvtx            = ((long)rbuckets[rtop] - (long)rlistspace) / sizeof(struct bilist);
        rweight         = graph[rvtx]->vwgt;
        lweight         = rweight - (rtop - maxdval);
        partial_weight  = weightsum[0] - lweight + weightsum[1] + rweight;
        ratio           = partial_weight / total_weight;
        right_imbalance = max(fabs(weightsum[0] - lweight - goal[0] * ratio),
                              fabs(weightsum[1] + rweight - goal[1] * ratio));
        if (rtop - maxdval > bestval || (rtop - maxdval == bestval &&
                                         (right_imbalance < left_imbalance ||
                                          (right_imbalance == left_imbalance && drandom() < .5)))) {
          to         = 1;
          weightfrom = lweight;
          bestvtx    = rvtx;
          bestval    = rtop - maxdval;
        }
      }

      if (bestval == -maxdval - 1) { /* No allowed moves */
        if (DEBUG_KL > 0) {
          printf("No KLV moves at step %d.  bestg = %g at step %d.\n", step, bestg, beststep);
        }
        break;
      }

      if (to == 0) {
        from           = 1;
        to_listspace   = llistspace;
        from_listspace = rlistspace;
        to_dvals       = ldvals;
        from_dvals     = rdvals;
        to_buckets     = lbuckets;
        from_buckets   = rbuckets;
        to_top         = &ltop;
      }
      else {
        from           = 0;
        to_listspace   = rlistspace;
        from_listspace = llistspace;
        to_dvals       = rdvals;
        from_dvals     = ldvals;
        to_buckets     = rbuckets;
        from_buckets   = lbuckets;
        to_top         = &rtop;
      }

      vweight = graph[bestvtx]->vwgt;

      weightsum[to] += vweight;
      weightsum[from] -= weightfrom;

      /* Check if this partition is balanced. */
      partial_weight = weightsum[0] + weightsum[1];
      ratio          = partial_weight / total_weight;
      delta0         = fabs(weightsum[0] - goal[0] * ratio);
      delta1         = fabs(weightsum[1] - goal[1] * ratio);
      temp_balanced  = (delta0 + delta1 <= max_dev) && weightsum[0] != total_weight &&
                      weightsum[1] != total_weight;
      ever_balanced = (ever_balanced || temp_balanced);
      balance_val   = delta0 + delta1;

      gtotal += bestval;

      if ((gtotal > bestg && temp_balanced) ||
          (enforce_balance_hard && balance_val < balance_best)) {
        bestg    = gtotal;
        beststep = step;
        if (balance_val < balance_best) {
          balance_best = balance_val;
        }
        if (temp_balanced) {
          enforce_balance_hard = FALSE;
        }
      }

      if (DEBUG_KL > 1) {
        printf("At KLV step %d, bestvtx=%d, bestval=%d (2->%d), wt0 = %g, wt1 = %g\n", step,
               bestvtx, bestval, to, weightsum[0], weightsum[1]);
      }

      /* Monitor the stopping criteria. */
      if (bestval < 0) {
        if (!enforce_balance || ever_balanced)
          neg_steps++;
        if (bestg != bestg_min)
          neg_cost = bestg - gtotal;
        else
          neg_cost = -maxdval - 1;
        if ((neg_steps > step_cutoff || neg_cost > cost_cutoff) &&
            !(enforce_balance && bestg == bestg_min)) {
          if (DEBUG_KL > 0) {
            if (neg_steps > step_cutoff) {
              printf("KLV step cutoff at step %d.  bestg = %g at step %d.\n", step, bestg,
                     beststep);
            }
            else if (neg_cost > cost_cutoff) {
              printf("KLV cost cutoff at step %d.  bestg = %g at step %d.\n", step, bestg,
                     beststep);
            }
          }
          gtotal -= bestval;
          weightsum[to] -= vweight;
          weightsum[from] += weightfrom;
          break;
        }
      }
      else if (bestval > 0) {
        neg_steps = 0;
      }

      /* Remove vertex from its buckets, and flag it as finished. */
      sets[bestvtx] = to;
      removebilist(&to_listspace[bestvtx], &to_buckets[bestval + maxdval]);
      /*
                  printf("After to removebilist\n");
                  p1bucket(to_buckets, to_listspace, maxdval);
      */

      if (from_dvals[bestvtx] != -maxdval - 1) {
        removebilist(&from_listspace[bestvtx], &from_buckets[from_dvals[bestvtx] + maxdval]);
        /*
                        printf("After from removebilist\n");
                        p1bucket(from_buckets, from_listspace, maxdval);
        */
      }
      from_dvals[bestvtx] = -maxdval - 1;

      /* Now keep track of vertices moved out of separator so */
      /* I can restore them as needed. */
      llistspace[bestvtx].next = out_list;
      out_list                 = &(llistspace[bestvtx]);

      /* Now update the d-values of all the neighbors */
      /* And neighbors of neighbors ... */

      /* If left move:
         1. Separator neighbors right gain => infinity
         2. Left neighbors unaffected.
         3. Right neighbors move into separator.
            A. Right gain = infinity.
            B. Left gain = computed.
            C. For any of their neighbors in separator increase left gain.
      */

      edges = graph[bestvtx]->edges;
      for (j = graph[bestvtx]->nedges - 1; j; j--) {
        neighbor = *(++edges);

        group = sets[neighbor];

        if (group == 2) { /* In separator. */
          gain = from_dvals[neighbor] + maxdval;
          /* Gain in the from direction => -infinity */
          if (gain >= 0) {
            removebilist(&from_listspace[neighbor], &from_buckets[gain]);
            /*
                                    printf("\n  After removing %d\n", neighbor);
                                    p1bucket(from_buckets, from_listspace, maxdval);
            */
            from_dvals[neighbor] = -maxdval - 1;
          }
        }
        else if (group == from) {
          /* Gain in the from direction => -infinity */
          sets[neighbor]       = 2;
          from_dvals[neighbor] = -maxdval - 1;

          if (to == 0) {
            bspace[list_length++] = -neighbor;
          }
          else {
            bspace[list_length++] = neighbor;
          }

          edges2 = graph[neighbor]->edges;
          vwgt   = graph[neighbor]->vwgt;
          gain   = graph[neighbor]->vwgt;
          flag   = FALSE;
          for (k = graph[neighbor]->nedges - 1; k; k--) {
            neighbor2 = *(++edges2);
            group2    = sets[neighbor2];
            if (group2 == 2) {
              dval = to_dvals[neighbor2] + maxdval;
              if (dval >= 0) {
                movebilist(&to_listspace[neighbor2], &to_buckets[dval], &to_buckets[dval + vwgt]);
                /*
                                                printf("\n  After moving %d from bucket %d to bucket
                   %d\n", neighbor2, dval, dval + vwgt);
                                                p1bucket(to_buckets, to_listspace, maxdval);
                */
                to_dvals[neighbor2] += vwgt;
                dval += vwgt;
                if (dval > *to_top) {
                  *to_top = dval;
                }
              }
            }
            else if (group2 == from) {
              gain -= graph[neighbor2]->vwgt;
              if (to_dvals[neighbor2] + maxdval < 0) {
                flag = TRUE;
              }
            }
          }

          if (flag) { /* Not allowed to move further. */
            to_dvals[neighbor] = -maxdval - 1;
          }
          else {
            to_dvals[neighbor] = gain;
            /* place in appropriate bucket */

            gain += maxdval;
            add2bilist(&to_listspace[neighbor], &to_buckets[gain]);
            /*
                                    printf("\nAfter adding %d to bucket %d\n", neighbor, gain -
               maxdval);
                                    p1bucket(to_buckets, to_listspace, maxdval);
            */

            if (gain > *to_top)
              *to_top = gain;
          }
        }
      }
      if (beststep == step) {
        bestlength = list_length;
      }
      if (DEBUG_KL > 2) {
        printf("\n-- After step, left buckets:\n");
        p1bucket(lbuckets, llistspace, maxdval);
        printf("             right buckets:\n");
        p1bucket(rbuckets, rlistspace, maxdval);
      }
    }

    /* Done with a pass; should we actually perform any swaps? */
    if (bestg > 0 || (bestg != bestg_min && !balanced && enforce_balance)) {
      improved += bestg;
    }
    else {
      if (enforce_balance_hard) {
        /* I've done the best I can, give up. */
        done = TRUE;
      }
      if (enforce_balance) {
        enforce_balance_hard = TRUE;
      }
      enforce_balance = TRUE;
      nbad++;
    }

    /* Work backwards, undoing all the undesirable moves. */

    /* First reset vertices moved out of the separator. */
    if (out_list) {
      if (beststep < 0)
        beststep = 0;
      for (i = step - 1; i > beststep; i--) {
        vtx = ((long)out_list - (long)llistspace) / sizeof(struct bilist);
        if (sets[vtx] != 2) {
          weightsum[sets[vtx]] -= graph[vtx]->vwgt;
        }
        sets[vtx] = 2;
        out_list  = out_list->next;
      }
    }

    for (i = list_length - 1; i >= bestlength; i--) {
      vtx = bspace[i];
      if (vtx < 0) {
        if (sets[-vtx] == 2) {
          weightsum[1] += graph[-vtx]->vwgt;
        }
        sets[-vtx] = 1;
      }
      else {
        if (sets[vtx] == 2) {
          weightsum[0] += graph[vtx]->vwgt;
        }
        sets[vtx] = 0;
      }
    }

    partial_weight = weightsum[0] + weightsum[1];
    ratio          = partial_weight / total_weight;
    delta0         = fabs(weightsum[0] - goal[0] * ratio);
    delta1         = fabs(weightsum[1] - goal[1] * ratio);
    balanced       = (delta0 + delta1 <= max_dev) && weightsum[0] != total_weight &&
               weightsum[1] != total_weight;

    done = done || (nbad >= nbadtries && balanced);
    if (KL_MAX_PASS > 0) {
      done = done || (npass == KL_MAX_PASS && balanced);
    }

    if (!done) { /* Rezero dval values. */
      clear_dvals(graph, nvtxs, ldvals, rdvals, bspace, list_length);
    }

    /* Construct list of separator vertices to pass to buckets or return */
    list_length = make_sep_list(bspace, list_length, sets);

    if (done) {
      bspace[list_length] = 0;
      bspace              = srealloc(bspace, (list_length + 1) * sizeof(int));
      *bndy_list          = bspace;
    }

    gain = 0;
    j = k = 0;
    for (i = 1; i <= nvtxs; i++) {
      if (sets[i] == 0)
        j += graph[i]->vwgt;
      else if (sets[i] == 1)
        k += graph[i]->vwgt;
      else if (sets[i] == 2)
        gain += graph[i]->vwgt;
    }
    /*
            printf("\nAfter pass of KLV: sets = %d/%d, sep = %d  (bestg = %g)\n\n\n",
                   j, k, gain, bestg);
    */
  }

  if (DEBUG_KL > 0) {
    printf("   KLV required %d passes to improve by %d.\n", npass, improved);
  }

  return (0);
}
示例#3
0
void 
bucketsorts (
    struct vtx_data **graph,	/* graph data structure */
    int nvtxs,		/* number of vertices */
    struct bilist ****buckets,	/* array of lists for bucket sort */
    struct bilist **listspace,	/* list data structure for each vertex */
    int **dvals,		/* d-values for each vertex for removing */
    int *sets,			/* processor each vertex is assigned to */
    float *term_wgts[],		/* weights for terminal propogation */
    int maxdval,		/* maximum possible dvalue for a vertex */
    int nsets,		/* number of sets being divided into */
    int parity,		/* work in forward or backward direction? */
    int (*hops)[MAXSETS],	/* hop cost between sets */
    int *bspace,		/* indices for randomly ordering vtxs */
    int list_length,		/* number of values in bspace to work with */
    int npass,		/* which pass through KL is this? */
    int using_ewgts		/* are edge weights being used? */
)
{
    extern int KL_RANDOM;	/* use randomness in KL? */
    extern int KL_UNDO_LIST;	/* only sort vertices who have moved. */
    extern double CUT_TO_HOP_COST;	/* if term_prop, cut/hop importance */
    struct bilist **bptr=NULL;	/* loops through set of buckets */
    struct bilist *lptr=NULL;	/* pointer to an element in listspace */
    float    *ewptr=NULL;	/* loops through edge weights */
    int      *bsptr=NULL;	/* loops through bspace */
    int      *edges=NULL;	/* edge list for a vertex */
    int       myset;		/* set that current vertex belongs to */
    int       newset;		/* set current vertex could move to */
    int       set;		/* set that neighboring vertex belongs to */
    int       weight;		/* edge weight for a particular edge */
    int       vtx;		/* vertex in graph */
    float     tval;		/* terminal propagation value */
    int       val;		/* terminal propogation rounded value */
    double    cut_cost;		/* relative cut/hop importance */
    double    hop_cost;		/* relative hop/cut importance */
    int       myhop;		/* hops associated with current vertex */
    int       i, j, l;		/* loop counters */
    void      randomize(), add2bilist();

    /* For each vertex, compute d-values for each possible transition. */
    /* Then store them in each appropriate bucket. */

    if (npass == 1 || !KL_UNDO_LIST || list_length == nvtxs) {
	/* Empty all the buckets. */
	/* Last clause catches case where lists weren't undone. */
	bptr = buckets[0][1];
	for (i = nsets * (nsets - 1) * (2 * maxdval + 1); i; i--)
	    *bptr++ = NULL;
    }

    /* Randomize the order of the vertices */

    if ((KL_UNDO_LIST && list_length == nvtxs) || !KL_UNDO_LIST) {
	bsptr = bspace;
	list_length = nvtxs;
	if (parity)
	    for (i = 1; i <= nvtxs; i++)
		*bsptr++ = i;
	else
	    for (i = nvtxs; i; i--)
		*bsptr++ = i;
    }
    if (KL_RANDOM)
	randomize(bspace - 1, list_length);

    /* Now compute d-vals by seeing which sets neighbors belong to. */
    cut_cost = hop_cost = 1;
    if (term_wgts[1] != NULL) {
	if (CUT_TO_HOP_COST > 1) {
	    cut_cost = CUT_TO_HOP_COST;
	}
	else {
	    hop_cost = 1.0 / CUT_TO_HOP_COST;
	}
    }
    weight = cut_cost + .5;
    bsptr = bspace;
    for (i = 0; i < list_length; i++) {	/* Loop through vertices. */
	vtx = *bsptr++;
	myset = sets[vtx];

	/* Initialize all the preference values. */
	if (term_wgts[1] != NULL) {
	    /* Using terminal propogation. */
	    if (myset == 0) {	/* No terminal value. */
		for (newset = 1; newset < nsets; newset++) {
		    tval = (term_wgts[newset])[vtx];
		    if (tval < 0) {
			val = - tval * hop_cost + .5;
			val = -val;
		    }
		    else {
			val = tval * hop_cost + .5;
		    }
		    dvals[vtx][newset - 1] = val;
		}
	    }
	    else {
		tval = -(term_wgts[myset])[vtx];
		if (tval < 0) {
		    val = - tval * hop_cost + .5;
		    val = -val;
		}
		else {
		    val = tval * hop_cost + .5;
		}
		dvals[vtx][0] = val;
		l = 1;
		for (newset = 1; newset < nsets; newset++) {
		    if (newset != myset) {
			tval = (term_wgts[newset])[vtx] - (term_wgts[myset])[vtx];
		        if (tval < 0) {
			    val = - tval * hop_cost + .5;
			    val = -val;
		        }
		        else {
			    val = tval * hop_cost + .5;
		        }
			dvals[vtx][l] = val;
			l++;
		    }
		}
	    }
	}
	else {
	    for (j = 0; j < nsets - 1; j++)
		dvals[vtx][j] = 0;
	}

	/* First count the neighbors in each set. */
	edges = graph[vtx]->edges;
	if (using_ewgts)
	    ewptr = graph[vtx]->ewgts;
	for (j = graph[vtx]->nedges - 1; j; j--) {
	    set = sets[*(++edges)];
	    if (set < 0)
		set = -set - 1;
	    if (using_ewgts)
		weight = *(++ewptr) * cut_cost + .5;
	    myhop = hops[myset][set];

	    l = 0;
	    for (newset = 0; newset < nsets; newset++) {
		if (newset != myset) {
		    dvals[vtx][l] += weight * (myhop - hops[newset][set]);
		    l++;
		}
	    }
	}

	/* Now add to appropriate buckets. */
	l = 0;
	for (newset = 0; newset < nsets; newset++) {
	    if (newset != myset) {
		lptr = listspace[l];
		add2bilist(&lptr[vtx], &buckets[myset][newset][dvals[vtx][l] + maxdval]);
		++l;
	    }
	}
    }
}
示例#4
0
void 
bucketsort1 (
    struct vtx_data **graph,	/* graph data structure */
    int vtx,			/* vertex being added to lists */
    struct bilist ****buckets,	/* array of lists for bucket sort */
    struct bilist **listspace,	/* list data structure for each vertex */
    int **dvals,		/* d-values for each vertex for removing */
    int *sets,			/* processor each vertex is assigned to */
    float *term_wgts[],		/* weights for terminal propogation */
    int maxdval,		/* maximum possible dvalue for a vertex */
    int nsets,		/* number of sets being divided into */
    int (*hops)[MAXSETS],	/* hop cost between sets */
    int using_ewgts		/* are edge weights being used? */
)
{
    extern double CUT_TO_HOP_COST;	/* if term_prop, cut/hop importance */
    struct bilist *lptr=NULL;	/* pointer to an element in listspace */
    float    *ewptr=NULL;	/* loops through edge weights */
    int      *edges=NULL;	/* edge list for a vertex */
    int       myset;		/* set that current vertex belongs to */
    int       newset;		/* set current vertex could move to */
    int       set;		/* set that neighboring vertex belongs to */
    int       weight;		/* edge weight for a particular edge */
    float     tval;		/* terminal propagation value */
    int       val;		/* terminal propogation rounded value */
    double    cut_cost;		/* relative cut/hop importance */
    double    hop_cost;		/* relative hop/cut importance */
    int       myhop;		/* hops associated with current vertex */
    int       j, l;		/* loop counters */
    void      add2bilist();


    /* Compute d-vals by seeing which sets neighbors belong to. */
    cut_cost = hop_cost = 1;
    if (term_wgts[1] != NULL) {
	if (CUT_TO_HOP_COST > 1) {
	    cut_cost = CUT_TO_HOP_COST;
	}
	else {
	    hop_cost = 1.0 / CUT_TO_HOP_COST;
	}
    }

    weight = cut_cost + .5;
    myset = sets[vtx];

    /* Initialize all the preference values. */
    if (term_wgts[1] != NULL) {
	/* Using terminal propogation. */
	if (myset == 0) {	/* No terminal value. */
	    for (newset = 1; newset < nsets; newset++) {
		tval = (term_wgts[newset])[vtx];
		if (tval < 0) {
		    val = - tval * hop_cost + .5;
		    val = - val;
		}
		else {
		    val = tval * hop_cost + .5;
		}
		dvals[vtx][newset - 1] = val;
	    }
	}
	else {
	    tval = -(term_wgts[myset])[vtx];
	    if (tval < 0) {
		val = - tval * hop_cost + .5;
		val = - val;
	    }
	    else {
		val = tval * hop_cost + .5;
	    }
	    dvals[vtx][0] = val;
	    l = 1;
	    for (newset = 1; newset < nsets; newset++) {
		if (newset != myset) {
		    tval = (term_wgts[newset])[vtx] - (term_wgts[myset])[vtx];
		    if (tval < 0) {
		        val = - tval * hop_cost + .5;
		        val = - val;
		    }
		    else {
		        val = tval * hop_cost + .5;
		    }
		    dvals[vtx][l] = val;
		    l++;
		}
	    }
	}
    }
    else {
	for (j = 0; j < nsets - 1; j++)
	    dvals[vtx][j] = 0;
    }

    /* First count the neighbors in each set. */
    edges = graph[vtx]->edges;
    if (using_ewgts)
	ewptr = graph[vtx]->ewgts;
    for (j = graph[vtx]->nedges - 1; j; j--) {
	set = sets[*(++edges)];
	if (set < 0)
	    set = -set - 1;
	if (using_ewgts)
	    weight = *(++ewptr) * cut_cost + .5;
	myhop = hops[myset][set];

	l = 0;
	for (newset = 0; newset < nsets; newset++) {
	    if (newset != myset) {
		dvals[vtx][l] += weight * (myhop - hops[newset][set]);
		l++;
	    }
	}
    }

    /* Now add to appropriate buckets. */
    l = 0;
    for (newset = 0; newset < nsets; newset++) {
	if (newset != myset) {
	    lptr = listspace[l];
	    add2bilist(&lptr[vtx], &buckets[myset][newset][dvals[vtx][l] + maxdval]);
	    ++l;
	}
    }
}