Exemplo n.º 1
0
static void heuristic(allinfo *a)
{
  register item *i, *j, *m;
  register stype c, z, ub;
  register state *v, *r1, *rm;
  item *red, d;

  if (a->d.size == 0) return;

  /* define limits */
  dynheur++;
  r1 = a->d.fset; rm = a->d.lset;
  c = a->c; z = a->z; ub = a->ub;

  /* forward solution with dyn prog */
  if (a->intv2 != a->intv2b) {
    red = (a->intv2+1)->f;
    for (i = red, m = a->litem+1, j = NULL; i != m; i++) {
      v = findvect(c - i->w, r1, rm); if (v == NULL) continue;
      if (v->psum+i->p > z) { j = i; z = v->psum+i->p; if (z == ub) break; }
    }
    if (j != NULL) {
      swapout(a, j, RIGHT); d = *red;
      for (i = red, m = a->t; i != m; i--) *i = *(i-1);
      *(a->t) = d; a->lsort++;
      multiply(a, a->t, RIGHT); a->t++;
      reduceset(a);
    }
  }

  /* backward solution with dyn prog */
  if (a->intv1 != a->intv1b) {
    red = (a->intv1-1)->l;
    for (i = a->fitem, m = red+1, j = NULL; i != m; i++) {
      v = findvect(c + i->w, r1, rm); if (v == NULL) continue;
      if (v->psum-i->p > z) { j = i; z = v->psum-i->p; if (z == ub) break; }
    }
    if (j != NULL) {
      swapout(a, j, LEFT); d = *red;
      for (i = red, m = a->s; i != m; i++) *i = *(i+1);
      *(a->s) = d; a->fsort--;
      multiply(a, a->s, LEFT); a->s--;
      reduceset(a);
    }
  }
}
Exemplo n.º 2
0
static void reduceset(allinfo *a)
{
  register state *i, *m, *k;
  register stype c, z;
  register prod p, w;
  state *v, *r1, *rm;
  boolean atstart, atend;

  if (a->d.size == 0) return;

  /* find break point and improve solution */
  r1 = a->d.fset; rm = a->d.lset;
  v = findvect(a->c, r1, rm);
  if (v == NULL) v = r1 - 1; else if (v->psum > a->z) improvesol(a, v);

  /* expand core, and choose ps, ws, pt, wt */
  expandcore(a, &atstart, &atend);

  /* now do the reduction */
  /* NB! This is the most efficient implementation, no product q is needed */
  c = a->c; z = a->z + 1; k = a->d.setm;
  if (!atstart) {
    p = a->ps; w = a->ws; 
    for (i = rm, m = v; i != m; i--) {
      if (DET(i->psum-z, i->wsum-c, p, w) >= 0) { k--; *k = *i; } 
    }
  }
  if (!atend) {
    p = a->pt; w = a->wt; 
    for (i = v, m = r1 - 1; i != m; i--) {
      if (DET(i->psum-z, i->wsum-c, p, w) >= 0) { k--; *k = *i; } 
    }
  }

  /* save limit */
  a->d.fset = k;
  a->d.lset = a->d.setm - 1; /* reserve one record for multiplication */
  a->d.size = DIFF(a->d.fset, a->d.lset);
}
Exemplo n.º 3
0
void reduceset(allinfo *a)
{
  register state *i, *m, *k;
  register ptype ps, ws, pt, wt, r;
  stype z, c;
  state *r1, *rm, *v;
  item *f, *l;

  if (a->d.size == 0) return;

  /* initialize limits */
  r1 = a->d.fset; rm = a->d.lset;
  v  = findvect(a->c, r1, rm);
  if (v == NULL) v = r1 - 1; /* all states infeasible */ 
  else { if (v->psum > a->z) improvesolution(a, v); }

  c = a->c; z = a->z + 1; k = a->d.setm;

  /* expand core, and choose ps, ws */
  if (a->s < a->fsort) {
    if (a->intv1 == a->intv1b) {
      ps = PMAX; ws = WMAX;
    } else {
      pop(a, LEFT, &f, &l);
      if (f < a->ftouch) a->ftouch = f;
      ps = f->p; ws = f->w; /* default: pick first item */
      simpreduce(LEFT, &f, &l, a);
      if (f <= l) {
	partsort(a, f, l, 0, SORTALL); a->fsort = f;
	ps = a->s->p; ws = a->s->w;
      }
    }
  } else {
    ps = a->s->p; ws = a->s->w;
  }

  /* expand core, and choose pt, wt */
  if (a->t > a->lsort) {
    if (a->intv2 == a->intv2b) {
      pt = PMIN; wt = WMIN;
    } else {
      pop(a, RIGHT, &f, &l);
      if (l > a->ltouch) a->ltouch = l;
      pt = l->p; wt = l->w; /* default: pick first item */
      simpreduce(RIGHT, &f, &l, a);
      if (f <= l) {
	partsort(a, f, l, 0, SORTALL); a->lsort = l;
	pt = a->t->p; wt = a->t->w;
      }
    }
  } else {
    pt = a->t->p; wt = a->t->w;
  }

  /* now do the reduction */
  r = DET(z, c, ps, ws);
  for (i = rm, m = v; i != m; i--) {
    if (DET(i->psum, i->wsum, ps, ws) >= r) {
      k--; *k = *i;
    }
  }

  r = DET(z, c, pt, wt);
  for (i = v, m = r1 - 1; i != m; i--) {
    if (DET(i->psum, i->wsum, pt, wt) >= r) {
      k--; *k = *i;
    }
  }

  a->ps = ps; a->ws = ws;
  a->pt = pt; a->wt = wt;
  a->d.fset = k;
  a->d.lset = a->d.setm - 1; /* reserve one record for multiplication */
  a->d.size = a->d.lset - a->d.fset + 1;
}