Skip to content

Commit cd96cd4

Browse files
authored
[docs] update knapsack tutorial (#3216)
1 parent ceff7b2 commit cd96cd4

File tree

1 file changed

+114
-17
lines changed

1 file changed

+114
-17
lines changed

docs/src/tutorials/linear/knapsack.jl

Lines changed: 114 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,41 +3,138 @@
33
# v.2.0. If a copy of the MPL was not distributed with this file, You can #src
44
# obtain one at https://mozilla.org/MPL/2.0/. #src
55

6-
# # The knapsack problem
6+
# # The knapsack problem example
77

8-
# Formulate and solve a simple knapsack problem:
9-
#
10-
# max sum(p_j x_j)
11-
# st sum(w_j x_j) <= C
12-
# x binary
8+
# The purpose of this example is demonstrate how to formulate and solve a
9+
# simple optimization problem.
10+
# We use the knapsack problem for this purpose.
11+
12+
# ## Required packages
13+
14+
# This tutorial requires the following packages:
1315

1416
using JuMP
1517
import HiGHS
1618
import Test
1719

18-
function example_knapsack()
19-
profit = [5, 3, 2, 7, 4]
20-
weight = [2, 8, 4, 2, 5]
21-
capacity = 10
20+
# ## Formulation
21+
22+
# The simple [knapsack problem](https://en.wikipedia.org/wiki/Knapsack_problem)
23+
# is a well-known type of optimization problem: given a set of items and
24+
# a container with a fixed capacity, choose a subset of items having the greatest combined
25+
# value that will fit within the container without exceeding the capacity.
26+
# The name of the problem suggests its analogy to packing for a trip,
27+
# where the baggage weight limit is the capacity and the goal is to pack the
28+
# most profitable combination of belongings.
29+
30+
# We can formulate the problem as an integer linear program
31+
32+
# ```math
33+
# \begin{aligned}
34+
# \max \; & \sum_{i=1}^n c_i x_i \\
35+
# s.t. \; & \sum_{i=1}^n w_i x_i \le C, \\
36+
# & x_i \in \{0,1\},\quad \forall i=1,\ldots,n
37+
# \end{aligned}
38+
# ```
39+
40+
# or more compactly as
41+
42+
# ```math
43+
# \begin{aligned}
44+
# \max \; & c^\top x \\
45+
# s.t. \; & w^\top x \le C \\
46+
# & x \text{ binary },
47+
# \end{aligned}
48+
# ```
49+
50+
# where there is a choice between ``n`` items, with item ``i`` having weight ``w_i``,
51+
# profit ``c_i`` and a decision variable ``x_i`` equal to 1 if the item is chosen
52+
# and 0 if not.
53+
54+
# ## Data
55+
56+
# The data for the problem is two vectors (one for the profits
57+
# and one for the weights) along with a capacity.
58+
# For our example, we use a capacity of 10 units
59+
capacity = 10;
60+
# and vector data
61+
profit = [5, 3, 2, 7, 4];
62+
weight = [2, 8, 4, 2, 5];
63+
64+
# ## JuMP formulation
65+
66+
# Let's begin constructing the JuMP model for our knapsack problem.
67+
# First, we'll create a `Model` object for holding model elements as
68+
# we construct each part. We'll also set the solver that will
69+
# ultimately be called to solve the model, once it's constructed.
70+
model = Model(HiGHS.Optimizer)
71+
72+
# Next we need the decision variables for which items are chosen.
73+
@variable(model, x[1:5], Bin)
74+
75+
# We now want to constrain those variables so that their combined
76+
# weight is less than or equal to the given capacity.
77+
@constraint(model, sum(weight[i] * x[i] for i in 1:5) <= capacity)
78+
79+
# Finally, we set an objective: maximise the combined profit of the
80+
# selected items.
81+
@objective(model, Max, sum(profit[i] * x[i] for i in 1:5))
82+
83+
# Let's print a human-readable description of the model and
84+
# check that the model looks as expected:
85+
print(model)
86+
87+
# We can now solve the optimization problem and inspect the results.
88+
optimize!(model)
89+
solution_summary(model)
90+
91+
# The items chosen are
92+
93+
items_chosen = [i for i in 1:5 if value(x[i]) > 0.5]
94+
95+
# After working interactively, it is good practice to implement
96+
# your model in a function.
97+
# A function can be used to ensure that the model is given
98+
# well-defined input data by validation checks, and that the
99+
# solution process went as expected.
100+
101+
function solve_knapsack_problem(;
102+
profit,
103+
weight::Vector{T},
104+
capacity::T,
105+
) where {T<:Real}
106+
N = length(weight)
107+
108+
## The profit and weight vectors must be of equal length.
109+
@assert length(profit) == N
110+
22111
model = Model(HiGHS.Optimizer)
23112
set_silent(model)
24-
@variable(model, x[1:5], Bin)
25-
## Objective: maximize profit
113+
114+
## Declare the decision variables as binary (0 or 1).
115+
@variable(model, x[1:N], Bin)
116+
117+
## Objective: maximize profit.
26118
@objective(model, Max, profit' * x)
27-
## Constraint: can carry all
119+
120+
## Constraint: can carry all items.
28121
@constraint(model, weight' * x <= capacity)
122+
29123
## Solve problem using MIP solver
30124
optimize!(model)
31125
println("Objective is: ", objective_value(model))
32126
println("Solution is:")
33-
for i in 1:5
34-
print("x[$i] = ", value(x[i]))
35-
println(", p[$i]/w[$i] = ", profit[i] / weight[i])
127+
for i in 1:N
128+
print("x[$i] = ", Int(value(x[i])))
129+
println(", c[$i]/w[$i] = ", profit[i] / weight[i])
36130
end
37131
Test.@test termination_status(model) == OPTIMAL
38132
Test.@test primal_status(model) == FEASIBLE_POINT
39133
Test.@test objective_value(model) == 16.0
40134
return
41135
end
42136

43-
example_knapsack()
137+
solve_knapsack_problem(; profit = profit, weight = weight, capacity = capacity)
138+
139+
# We observe that the chosen items (1, 4 and 5) have the best
140+
# profit to weight ratio for in this particular example.

0 commit comments

Comments
 (0)