1/*-------------------------------------------------------------------------
4 * Knapsack problem solver
6 * Given input vectors of integral item weights (must be >= 0) and values
7 * (double >= 0), compute the set of items which produces the greatest total
8 * value without exceeding a specified total weight; each item is included at
9 * most once (this is the 0/1 knapsack problem). Weight 0 items will always be
12 * The performance of this algorithm is pseudo-polynomial, O(nW) where W is the
13 * weight limit. To use with non-integral weights or approximate solutions,
14 * the caller should pre-scale the input weights to a suitable range. This
15 * allows approximate solutions in polynomial time (the general case of the
16 * exact problem is NP-hard).
18 * Copyright (c) 2017-2025, PostgreSQL Global Development Group
21 * src/backend/lib/knapsack.c
23 *-------------------------------------------------------------------------
37 * The item_values input is optional; if omitted, all the items are assumed to
40 * Returns a Bitmapset of the 0..(n-1) indexes of the items chosen for
41 * inclusion in the solution.
43 * This uses the usual dynamic-programming algorithm, adapted to reuse the
44 * memory on each pass (by working from larger weights to smaller). At the
45 * start of pass number i, the values[w] array contains the largest value
46 * computed with total weight <= w, using only items with indices < i; and
47 * sets[w] contains the bitmap of items actually used for that value. (The
48 * bitmapsets are all pre-initialized with an unused high bit so that memory
49 * allocation is done only once.)
53 int *item_weights,
double *item_values)
66 Assert(num_items > 0 && item_weights);
71 for (
i = 0;
i <= max_weight; ++
i)
77 for (
i = 0;
i < num_items; ++
i)
79 int iw = item_weights[
i];
80 double iv = item_values ? item_values[
i] : 1;
82 for (
j = max_weight;
j >= iw; --
j)
88 /* copy sets[ow] to sets[j] without realloc */
Bitmapset * bms_replace_members(Bitmapset *a, const Bitmapset *b)
Bitmapset * bms_make_singleton(int x)
Bitmapset * bms_del_member(Bitmapset *a, int x)
Bitmapset * bms_add_member(Bitmapset *a, int x)
Bitmapset * bms_copy(const Bitmapset *a)
static Datum values[MAXATTR]
Assert(PointerIsAligned(start, uint64))
Bitmapset * DiscreteKnapsack(int max_weight, int num_items, int *item_weights, double *item_values)
MemoryContext CurrentMemoryContext
void MemoryContextDelete(MemoryContext context)
#define AllocSetContextCreate
#define ALLOCSET_SMALL_SIZES
static MemoryContext MemoryContextSwitchTo(MemoryContext context)