From 684f664f5882a694112666842fabd8fae9f8a900 Mon Sep 17 00:00:00 2001 From: James Foster Date: Mon, 13 Feb 2023 12:54:43 +1100 Subject: [PATCH 1/4] Track markdown version --- docs/src/tutorials/linear/knapsack.md | 49 +++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 docs/src/tutorials/linear/knapsack.md diff --git a/docs/src/tutorials/linear/knapsack.md b/docs/src/tutorials/linear/knapsack.md new file mode 100644 index 00000000000..f8f3756eb12 --- /dev/null +++ b/docs/src/tutorials/linear/knapsack.md @@ -0,0 +1,49 @@ +```@meta +EditURL = "/docs/src/tutorials/linear/knapsack.jl" +``` + +# The knapsack problem + +Formulate and solve a simple knapsack problem: + + max sum(p_j x_j) + st sum(w_j x_j) <= C + x binary + +````@example knapsack +using JuMP +import HiGHS +import Test + +function example_knapsack() + profit = [5, 3, 2, 7, 4] + weight = [2, 8, 4, 2, 5] + capacity = 10 + model = Model(HiGHS.Optimizer) + set_silent(model) + @variable(model, x[1:5], Bin) + # Objective: maximize profit + @objective(model, Max, profit' * x) + # Constraint: can carry all + @constraint(model, weight' * x <= capacity) + # Solve problem using MIP solver + optimize!(model) + println("Objective is: ", objective_value(model)) + println("Solution is:") + for i in 1:5 + print("x[$i] = ", value(x[i])) + println(", p[$i]/w[$i] = ", profit[i] / weight[i]) + end + Test.@test termination_status(model) == OPTIMAL + Test.@test primal_status(model) == FEASIBLE_POINT + Test.@test objective_value(model) == 16.0 + return +end + +example_knapsack() +```` + +--- + +!!! tip + This tutorial was generated using [Literate.jl](https://github.com/fredrikekre/Literate.jl). [View the source `.jl` file on GitHub](https://github.com/jump-dev/JuMP.jl/tree/master/docs/src/tutorials/linear/knapsack.jl). From 66c7c02e88f30ffdd4ad61331239ae8378cc55c3 Mon Sep 17 00:00:00 2001 From: James Foster Date: Mon, 13 Feb 2023 21:18:43 +1100 Subject: [PATCH 2/4] Remove md version of knapsack, add jl version --- docs/src/tutorials/linear/knapsack.jl | 131 ++++++++++++++++++++++---- docs/src/tutorials/linear/knapsack.md | 49 ---------- 2 files changed, 114 insertions(+), 66 deletions(-) delete mode 100644 docs/src/tutorials/linear/knapsack.md diff --git a/docs/src/tutorials/linear/knapsack.jl b/docs/src/tutorials/linear/knapsack.jl index 50f5a74cdb7..c5533eecb7c 100644 --- a/docs/src/tutorials/linear/knapsack.jl +++ b/docs/src/tutorials/linear/knapsack.jl @@ -3,36 +3,126 @@ # v.2.0. If a copy of the MPL was not distributed with this file, You can #src # obtain one at https://mozilla.org/MPL/2.0/. #src -# # The knapsack problem +# # The knapsack problem example -# Formulate and solve a simple knapsack problem: -# -# max sum(p_j x_j) -# st sum(w_j x_j) <= C -# x binary +# The purpose of this example is demonstrate how to formulate and solve a +# simple optimization problem. +# We use the knapsack problem for this purpose. + +# ## Required packages + +# This tutorial requires the following packages: using JuMP import HiGHS import Test -function example_knapsack() - profit = [5, 3, 2, 7, 4] - weight = [2, 8, 4, 2, 5] - capacity = 10 +# ## Formulation + +# The simple [knapsack problem](https://en.wikipedia.org/wiki/Knapsack_problem) +# is a well-known type of optimization problem: given a set of items and +# a container with a fixed capacity, choose a subset of items having the greatest combined +# value that will fit within the container without exceeding the capacity. +# The name of the problem suggests its analogy to packing for a trip, +# where the baggage weight limit is the capacity and the goal is to pack the +# most profitable combination of belongings. + +# We can formulate the problem as an integer linear program + +# ```math +# \begin{aligned} +# \max \; & \sum_{i=1}^n c_i x_i \\ +# s.t. \; & \sum_{i=1}^n w_i x_i \le C, \\ +# & x_i \in \{0,1\},\quad \forall i=1,\ldots,n +# \end{aligned} +# ``` + +# or more compactly as + +# ```math +# \begin{aligned} +# \max \; & c^\top x \\ +# s.t. \; & w^\top x \le C \\ +# & x \text{ binary }, +# \end{aligned} +# ``` + +# where there is a choice between ``n`` items, with item ``i`` having weight ``w_i``, +# profit ``c_i`` and a decision variable ``x_i`` equal to 1 if the item is chosen +# and 0 if not. + +# ## Data + +# The data for the problem is two vectors (one for the profits +# and one for the weights) along with a capacity. +# For our example, we use a capacity of 10 units +capacity = 10; +# and vector data +profit = [5, 3, 2, 7, 4]; +weight = [2, 8, 4, 2, 5]; + +# ## JuMP formulation + +# Let's begin constructing the JuMP model for our knapsack problem. +# First, we'll create a `Model` object for holding model elements as +# we construct each part. We'll also set the solver that will +# ultimately be called to solve the model, once it's constructed. +model = Model(HiGHS.Optimizer) + +# Next we need the decision variables for which items are chosen. +@variable(model, x[1:5], Bin) + +# We now want to constrain those variables so that their combined +# weight is less than or equal to the given capacity. +@constraint(model, sum(weight[i] * x[i] for i in 1:5) <= capacity) + +# Finally, we set an objective: maximise the combined profit of the +# selected items. +@objective(model, Max, sum(profit[i] * x[i] for i in 1:5)) + +# Let's print a human-readable description of the model and +# check that the model looks as expected: +print(model) + +# We can now solve the optimization problem and inspect the results. +optimize!(model) +solution_summary(model) + +# After working interactively, it is good practice to implement +# your model in a function. +# A function can be used to ensure that the model is given +# well-defined input data by validation checks, and that the +# solution process went as expected. + +function solve_knapsack_problem(; + profit, + weight::Vector{T}, + capacity::T, +) where {T<:Real} + N = length(weight) + + ## The profit and weight vectors must be of equal length. + @assert length(profit) == N + model = Model(HiGHS.Optimizer) set_silent(model) - @variable(model, x[1:5], Bin) - ## Objective: maximize profit + + ## Declare the decision variables as binary (0 or 1). + @variable(model, x[1:N], Bin) + + ## Objective: maximize profit. @objective(model, Max, profit' * x) - ## Constraint: can carry all + + ## Constraint: can carry all items. @constraint(model, weight' * x <= capacity) + ## Solve problem using MIP solver optimize!(model) println("Objective is: ", objective_value(model)) println("Solution is:") - for i in 1:5 - print("x[$i] = ", value(x[i])) - println(", p[$i]/w[$i] = ", profit[i] / weight[i]) + for i in 1:N + print("x[$i] = ", Int(value(x[i]))) + println(", c[$i]/w[$i] = ", profit[i] / weight[i]) end Test.@test termination_status(model) == OPTIMAL Test.@test primal_status(model) == FEASIBLE_POINT @@ -40,4 +130,11 @@ function example_knapsack() return end -example_knapsack() +solve_knapsack_problem(; + profit = profit, + weight = weight, + capacity = capacity, +) + +# We observe that the chosen items (1, 4 and 5) have the best +# profit to weight ratio for in this particular example. diff --git a/docs/src/tutorials/linear/knapsack.md b/docs/src/tutorials/linear/knapsack.md deleted file mode 100644 index f8f3756eb12..00000000000 --- a/docs/src/tutorials/linear/knapsack.md +++ /dev/null @@ -1,49 +0,0 @@ -```@meta -EditURL = "/docs/src/tutorials/linear/knapsack.jl" -``` - -# The knapsack problem - -Formulate and solve a simple knapsack problem: - - max sum(p_j x_j) - st sum(w_j x_j) <= C - x binary - -````@example knapsack -using JuMP -import HiGHS -import Test - -function example_knapsack() - profit = [5, 3, 2, 7, 4] - weight = [2, 8, 4, 2, 5] - capacity = 10 - model = Model(HiGHS.Optimizer) - set_silent(model) - @variable(model, x[1:5], Bin) - # Objective: maximize profit - @objective(model, Max, profit' * x) - # Constraint: can carry all - @constraint(model, weight' * x <= capacity) - # Solve problem using MIP solver - optimize!(model) - println("Objective is: ", objective_value(model)) - println("Solution is:") - for i in 1:5 - print("x[$i] = ", value(x[i])) - println(", p[$i]/w[$i] = ", profit[i] / weight[i]) - end - Test.@test termination_status(model) == OPTIMAL - Test.@test primal_status(model) == FEASIBLE_POINT - Test.@test objective_value(model) == 16.0 - return -end - -example_knapsack() -```` - ---- - -!!! tip - This tutorial was generated using [Literate.jl](https://github.com/fredrikekre/Literate.jl). [View the source `.jl` file on GitHub](https://github.com/jump-dev/JuMP.jl/tree/master/docs/src/tutorials/linear/knapsack.jl). From eb574652052c5b8d654e50308c983bf3118aa33c Mon Sep 17 00:00:00 2001 From: James Foster Date: Mon, 13 Feb 2023 21:39:43 +1100 Subject: [PATCH 3/4] Catch formatter changes --- docs/src/tutorials/linear/knapsack.jl | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/docs/src/tutorials/linear/knapsack.jl b/docs/src/tutorials/linear/knapsack.jl index c5533eecb7c..14c8487ad60 100644 --- a/docs/src/tutorials/linear/knapsack.jl +++ b/docs/src/tutorials/linear/knapsack.jl @@ -130,11 +130,7 @@ function solve_knapsack_problem(; return end -solve_knapsack_problem(; - profit = profit, - weight = weight, - capacity = capacity, -) +solve_knapsack_problem(; profit = profit, weight = weight, capacity = capacity) # We observe that the chosen items (1, 4 and 5) have the best # profit to weight ratio for in this particular example. From c24fe26297ad133d15a7ba80d79dbeb7aed1be99 Mon Sep 17 00:00:00 2001 From: Oscar Dowson Date: Tue, 14 Feb 2023 09:13:38 +1300 Subject: [PATCH 4/4] Update docs/src/tutorials/linear/knapsack.jl --- docs/src/tutorials/linear/knapsack.jl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/src/tutorials/linear/knapsack.jl b/docs/src/tutorials/linear/knapsack.jl index 14c8487ad60..b071e833f13 100644 --- a/docs/src/tutorials/linear/knapsack.jl +++ b/docs/src/tutorials/linear/knapsack.jl @@ -88,6 +88,10 @@ print(model) optimize!(model) solution_summary(model) +# The items chosen are + +items_chosen = [i for i in 1:5 if value(x[i]) > 0.5] + # After working interactively, it is good practice to implement # your model in a function. # A function can be used to ensure that the model is given