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); } } }
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); }
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; }