Constraint Knapsack
The constraint Knapsack ensures that some items are packed in a knapsack with certain weight and profit restrictions. So, the context is to manage a collection of items, each one being described by 2 attributes: its weight and its profit. We have to decide how many copies of each item must be selected (or simply, which items must be selected, in a single occurrence, if variables are 0/1) while respecting a numerical condition
The operator of the first condition is expected to be in
Ensuring a minimum benefit when filling a knapsack:
In PyCSP
To see how this constraint works, we need first to import the library PyCSP
from pycsp3 import *
For our illustration, we assume that we have 10 items with the following weights and profits:
weights = [10, 2, 6, 11, 21, 4, 8, 3, 8, 10]
profits = [20, 4, 3, 9, 13, 2, 3, 4, 7, 8]
nItems = len(weights)
We also assume that we need to collect some of these items (in a knapsack) while considering that the capacity of the knapsack is 20 (w_limit) and the minimum satisfactory level is 30 (p_limit).
w_limit, p_limit = 20, 30
Next, we introduce an array
x = VarArray(size=nItems, dom={0, 1})
We can display (the structure of) the array as well as the domain of the first variable.
print("Array of variable x: ", x)
print("Domain of any variable: ", x[0].dom)
Array of variable x: [x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9]]
Domain of any variable: 0 1
We simply post a single constraint Knapsack with the limits mentioned above.
satisfy(
Knapsack(x, weights=weights, wlimit=w_limit, profits=profits) >= p_limit
);
By calling the function solve(), we can check that the problem (actually, the single constraint) is satisfiable (SAT). We can also print the values assigned to the variables in the found solution; we can call the function values() that collects the values assigned (in the last found solution) to a specified list of variables.
if solve() is SAT:
print("Values of x: ", values(x))
Values of x: [1, 1, 0, 0, 0, 1, 0, 1, 0, 0]
On this simple constraint, one can verify that the number of solutions (supports) is 2.
if solve(sols=ALL) is SAT:
for i in range(n_solutions()):
print(f"Solution {i+1}: {values(x, sol=i)} of profit {sum(value(x[j], sol=i)*profits[j] for j in range(nItems))}")
Solution 1: [1, 1, 0, 0, 0, 1, 0, 1, 0, 0] of profit 30
Solution 2: [1, 1, 0, 0, 0, 0, 0, 0, 1, 0] of profit 31
Let us display the internal representation of the posted constraint:
print(posted())
knapsack(list:x[], weights:[10, 2, 6, 11, 21, 4, 8, 3, 8, 10], limit:(le,20), profits:[20, 4, 3, 9, 13, 2, 3, 4, 7, 8], condition:(ge,30))
Now, let us discard it:
unpost()
Let us check that there are no more constraints:
print(posted())
[]
Let us post the same constraint, this time by using the other parameter wcondition:
satisfy(
Knapsack(x, weights=weights, wcondition=le(w_limit), profits=profits) >= p_limit
);
Let us check that this is the same constraint:
print(posted())
knapsack(list:[x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9]], weights:[10, 2, 6, 11, 21, 4, 8, 3, 8, 10], limit:(le,20), profits:[20, 4, 3, 9, 13, 2, 3, 4, 7, 8], condition:(ge,30))
Since XCSP