static void expandcore(allinfo *a, boolean *atstart, boolean *atend) { item *f, *l; /* expand core */ *atstart = FALSE; if (a->s < a->fsort) { if (a->intv1 == a->intv1b) { *atstart = TRUE; } else { pop(a, LEFT, &f, &l); a->ps = f->p; a->ws = f->w; simpreduce(LEFT, &f, &l, a); if (f != l+1) { partsort(a, f, l, 0, 0, SORTALL); a->fsort = f; a->ps = a->s->p; a->ws = a->s->w; } } } else { a->ps = a->s->p; a->ws = a->s->w; } /* expand core */ *atend = FALSE; if (a->t > a->lsort) { if (a->intv2 == a->intv2b) { *atend = TRUE; } else { pop(a, RIGHT, &f, &l); a->pt = l->p; a->wt = l->w; simpreduce(RIGHT, &f, &l, a); if (f != l+1) { partsort(a, f, l, 0, 0, SORTALL); a->lsort = l; a->pt = a->t->p; a->wt = a->t->w; } } } else { a->pt = a->t->p; a->wt = a->t->w; } }
void partsort(allinfo *a, item *f, item *l, stype ws, int what) { register ptype mp, mw; register item *i, *j, *m; register stype wi; register int d; d = l - f + 1; if (d < 1) errorx("negative interval in partsort"); if (d > MINMED) { m = median(f, l, (int) sqrt((double)d)); } else { if (d > 1) { m = f + d / 2; if (DET(f->p, f->w, m->p, m->w) < 0) SWAP(f, m); if (d > 2) { if (DET(m->p, m->w, l->p, l->w) < 0) { SWAP(m, l); if (DET(f->p, f->w, m->p, m->w) < 0) SWAP(f, m); } } } } if (d > 3) { mp = m->p; mw = m->w; i = f; j = l; wi = ws; for (;;) { do { wi += i->w; i++; } while (DET(i->p, i->w, mp, mw) > 0); do { j--; } while (DET(j->p, j->w, mp, mw) < 0); if (i > j) break; SWAP(i, j); } if (wi <= a->cstar) { if (what == SORTALL) partsort(a, f, i-1, ws, what); if (what == PARTIATE) push(a, LEFT, f, i-1); partsort(a, i, l, wi, what); } else { if (what == SORTALL) partsort(a, i, l, wi, what); if (what == PARTIATE) push(a, RIGHT, i, l); partsort(a, f, i-1, ws, what); } } if ((d <= 3) || (what == SORTALL)) { a->fpart = f; a->lpart = l; a->wfpart = ws; } }
static void partsort(allinfo *a, item *f, item *l, stype ws, stype c, int what) { register itype mp, mw; register item *i, *j, *m; register stype wi; int d; d = l - f + 1; if (d > 1) { m = f + d / 2; if (DET(f->p, f->w, m->p, m->w) < 0) SWAP(f, m); if (d > 2) { if (DET(m->p, m->w, l->p, l->w) < 0) { SWAP(m, l); if (DET(f->p, f->w, m->p, m->w) < 0) SWAP(f, m); } } } if (d > 3) { mp = m->p; mw = m->w; i = f; j = l; wi = ws; for (;;) { do { wi += i->w; i++; } while (DET(i->p, i->w, mp, mw) > 0); do { j--; } while (DET(j->p, j->w, mp, mw) < 0); if (i > j) break; SWAP(i, j); } if (wi <= c) { if (what == SORTALL) partsort(a, f, i-1, ws, c, what); if (what == PARTITION) push(a, LEFT, f, i-1); partsort(a, i, l, wi, c, what); } else { if (what == SORTALL) partsort(a, i, l, wi, c, what); if (what == PARTITION) push(a, RIGHT, i, l); partsort(a, f, i-1, ws, c, what); } } if ((d <= 3) || (what == SORTALL)) { a->fpart = f; a->lpart = l; a->wfpart = ws; } }
int main(int argc, char **argv) { struct stat hdst; struct part_geom whole, entry; struct part_entry table[4], *pe; int drive, par = 0, device, incr; int partf; char *table_file; int hd_major, hd_minor; int needsort; int shrink; /* True if partitions are shrinked to fit. */ unsigned long base, size, limit; if ((arg0= strrchr(argv[0], '/')) == nil) arg0= argv[0]; else arg0++; if (argc < 2 || argc > 3) { fprintf(stderr, "Usage: %s device [partition-file]\n", arg0); exit(1); } dev_file= argv[1]; table_file= argv[argc - 1]; shrink= (argc == 2); if (stat(dev_file, &hdst) < 0) fatal(dev_file); /* Geometry (to print nice numbers.) */ if (diocntl(hdst.st_rdev, DGETP, &geometry) < 0) fatal(dev_file); if (!S_ISBLK(hdst.st_mode)) { fprintf(stderr, "%s: %s is not a device\n", arg0, dev_file); exit(1); } hd_major= major(hdst.st_rdev); hd_minor= minor(hdst.st_rdev); if (hd_minor >= MINOR_d0p0s0) { errno= EINVAL; fatal(dev_file); } if (hd_major == major(DEV_FD0)) { /* HD is actually a floppy. */ if (hd_minor >= 4) { errno= EINVAL; fatal(dev_file); } device= hd_minor + (28 << 2); incr= 4; needsort= 0; } else if (hd_minor % (1 + NR_PARTITIONS) == 0) { /* Partitioning hd0, hd5, ... */ device= hd_minor + 1; incr= 1; needsort= 1; } else { /* Subpartitioning hd[1-4], hd[6-9], ... */ drive= hd_minor / (1 + NR_PARTITIONS); par= hd_minor % (1 + NR_PARTITIONS) - 1; device= MINOR_d0p0s0 + (drive * NR_PARTITIONS + par) * NR_PARTITIONS; if (device + NR_PARTITIONS - 1 > BYTE) { errno= EINVAL; fatal(dev_file); } incr= 1; needsort= 0; } /* Device is now the first of the minor devices to be repartitioned. */ /* Read the partition table from the boot block. */ if ((partf= open(table_file, O_RDONLY)) < 0 || lseek(partf, (off_t) PART_TABLE_OFF, SEEK_SET) == -1 || (par= read(partf, (char *) table, (int) sizeof(table))) < 0 ) fatal(table_file); if (par < sizeof(table)) { fprintf(stderr, "%s: %s does not contain a partition table\n", arg0, table_file); exit(1); } if (needsort) partsort(table); /* Show the geometry of the affected drive or partition. */ if (diocntl(hdst.st_rdev, DGETP, &whole) < 0) fatal(dev_file); /* Use sector numbers. */ base = whole.base / SECTOR_SIZE; size = whole.size / SECTOR_SIZE; limit = base + size; show_part(dev_file, base, size); /* Send the partition table entries to the device driver. */ for (par= 0; par < NR_PARTITIONS; par++, device+= incr) { pe = &table[par]; if (shrink && pe->size != 0) { /* Shrink the partition entry to fit within the * enclosing device just like the driver does. */ unsigned long part_limit= pe->lowsec + pe->size; if (part_limit < pe->lowsec) part_limit= limit; if (part_limit > limit) part_limit= limit; if (pe->lowsec < base) pe->lowsec= base; if (part_limit < pe->lowsec) part_limit= pe->lowsec; pe->size= part_limit - pe->lowsec; } entry.base= pe->lowsec * SECTOR_SIZE; entry.size= pe->size * SECTOR_SIZE; if (diocntl(makedev(hd_major, device), DSETP, &entry) < 0) fatal(dev_file); show_part(finddev(makedev(hd_major, device)), pe->lowsec, pe->size); } exit(0); }
extern stype combo(item *f, item *l, stype c, stype lb, stype ub, boolean def, boolean relx) /* f,l : first, last item */ /* c : capacity of knapsack */ /* lb : lower bound. Solution vector is only updated if better z found */ /* ub : upper bound. When upper bound is reached terminate immediately */ /* def : should solution vector be defined or just find objective value */ /* relx: relaxed problem is solved (no more relaxations will be made) */ /* returns the objective value of the problem */ { allinfo a; interval *inttab; boolean heur, rudi; if ((ub != 0) && (lb == ub)) return lb; heur = FALSE; rudi = FALSE; inttab = palloc(sizeof(interval), SORTSTACK); a.intv1b = &inttab[0]; a.intv2b = &inttab[SORTSTACK - 1]; a.intv1 = a.intv1b; a.intv2 = a.intv2b; a.fitem = f; a.litem = l; a.c = c; a.z = lb; a.lb = lb; a.relx = relx; a.master = (def && !relx); a.coresize = 0; partsort(&a, a.fitem, a.litem, 0, a.c, PARTITION); findbreak(&a); a.ub = (ub == 0 ? a.dantzig : ub); /* find and enumerate core */ findcore(&a); reduceset(&a); while ((a.d.size > 0) && (a.z < a.ub)) { if (a.t <= a.lsort) { if (haschance(&a, a.t, RIGHT)) multiply(&a, a.t, RIGHT); a.t++; } reduceset(&a); if (a.s >= a.fsort) { if (haschance(&a, a.s, LEFT)) multiply(&a, a.s, LEFT); a.s--; } reduceset(&a); /* find better lower bound when needed */ if ((!heur) && (a.d.size > MINHEUR)) { heuristic(&a); heur = TRUE; } /* find tight bound when needed */ if ((!relx) && (a.d.size > MINSET)) { surrelax(&a); relx = TRUE; } /* use rudimentary divisibility to decrease c */ if ((!rudi) && (a.d.size > MINRUDI)) { rudidiv(&a); rudi = TRUE; } } pfree(a.d.set1); pfree(inttab); if ((def) && (a.z > a.lb)) definesolution(&a); pfree(a.ffull); return a.z; }
stype minknap(int n, int *p, int *w, int *x, int c) { allinfo a; item* tab;//[KNAPSIZE]; static item tabmem[KNAPSIZE]; interval* inttab;//[KNAPSIZE]; static interval inttabmem[SORTSTACK]; /* allocate space for internal representation */ //tab = (item *) palloc(sizeof(item) * n); tab = tabmem;//(item *) palloc(sizeof(item) * n); a.fitem = &tab[0]; a.litem = &tab[n-1]; copyproblem(a.fitem, a.litem, p, w, x); a.n = n; a.cstar = c; a.iterates = 0; a.simpreduced = 0; a.pireduced = 0; a.pitested = 0; a.maxstates = 0; a.coresize = 0; //inttab = (interval*) palloc(sizeof(interval) * SORTSTACK); inttab = inttabmem; a.intv1 = a.intv1b = &inttab[0]; a.intv2 = a.intv2b = &inttab[SORTSTACK - 1]; a.fsort = a.litem; a.lsort = a.fitem; partsort(&a, a.fitem, a.litem, 0, PARTIATE); findbreak(&a); a.ub = a.dantzig; a.firsttime = TRUE; for (;;) { a.iterates++; a.s = a.b-1; a.t = a.b; initfirst(&a, a.psumb, a.wsumb); initvect(&a); reduceset(&a); while ((a.d.size > 0) && (a.z < a.ub)) { if (a.t <= a.lsort) { if (haschance(&a, a.t, RIGHT)) multiply(&a, a.t, RIGHT); (a.t)++; } reduceset(&a); if (a.s >= a.fsort) { if (haschance(&a, a.s, LEFT)) multiply(&a, a.s, LEFT); (a.s)--; } reduceset(&a); } //pfree(a.d.set1); definesolution(&a); if (a.welldef) break; } //pfree(tab); //pfree(inttab); return a.zstar; }
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; }