From 9903e983f3b7bcd1c39fc1f5b33e8113a0c868e5 Mon Sep 17 00:00:00 2001 From: odow Date: Mon, 21 Feb 2022 15:47:29 +1300 Subject: [PATCH] More updates --- docs/src/assets/n_queens.png | Bin 6978 -> 0 bytes .../algebraic_modeling_languages.md | 75 ++++++++---------- docs/src/installation.md | 2 +- docs/src/manual/models.md | 10 +-- .../src/tutorials/linear/facility_location.jl | 6 ++ docs/src/tutorials/linear/n-queens.jl | 2 - 6 files changed, 43 insertions(+), 52 deletions(-) delete mode 100644 docs/src/assets/n_queens.png diff --git a/docs/src/assets/n_queens.png b/docs/src/assets/n_queens.png deleted file mode 100644 index a564c5ee955f12a419f67693281687d3ceb7001d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6978 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 diff --git a/docs/src/background/algebraic_modeling_languages.md b/docs/src/background/algebraic_modeling_languages.md index 8a4dbd25b22..81fbbccd115 100644 --- a/docs/src/background/algebraic_modeling_languages.md +++ b/docs/src/background/algebraic_modeling_languages.md @@ -1,7 +1,7 @@ ```@meta CurrentModule = JuMP DocTestSetup = quote - using JuMP, GLPK + using JuMP, HiGHS end DocTestFilters = [r"≤|<=", r"≥|>=", r" == | = ", r" ∈ | in ", r"MathOptInterface|MOI"] ``` @@ -35,7 +35,7 @@ much easier. A solver is a software package that computes solutions to one or more classes of problems. - For example, [GLPK](https://www.gnu.org/software/glpk/) is a solver for + For example, [HiGHS](https://github.com/ERGO-Code/HiGHS) is a solver for linear programming (LP) and mixed integer programming (MIP) problems. It incorporates algorithms such as the simplex method and the interior-point method. @@ -128,11 +128,11 @@ JuMP provides the first part of an algebraic modeling language using the For example, here's how we write the knapsack problem in JuMP: ```jldoctest -julia> using JuMP, GLPK +julia> using JuMP, HiGHS julia> function algebraic_knapsack(c, w, b) n = length(c) - model = Model(GLPK.Optimizer) + model = Model(HiGHS.Optimizer) @variable(model, x[1:n] >= 0, Int) @objective(model, Max, sum(c[i] * x[i] for i = 1:n)) @constraint(model, sum(w[i] * x[i] for i = 1:n) <= b) @@ -154,11 +154,11 @@ the model we wrote out above. For the next step, JuMP's macros re-write the variables and constraints into a functional form. Here's what the JuMP code looks like after this step: ```jldoctest -julia> using JuMP, GLPK +julia> using JuMP, HiGHS julia> function nonalgebraic_knapsack(c, w, b) n = length(c) - model = Model(GLPK.Optimizer) + model = Model(HiGHS.Optimizer) x = [VariableRef(model) for i = 1:n] for i = 1:n set_lower_bound(x[i], 0) @@ -194,7 +194,7 @@ Hopefully you agree that the macro version is much easier to read! In the third step, JuMP converts the functional form of the problem, i.e., `nonalgebraic_knapsack`, into the MathOptInterface API: ```jldoctest -julia> using MathOptInterface, GLPK +julia> using MathOptInterface, HiGHS julia> const MOI = MathOptInterface; @@ -220,7 +220,7 @@ julia> function mathoptinterface_knapsack(optimizer, c, w, b) end mathoptinterface_knapsack (generic function with 1 method) -julia> mathoptinterface_knapsack(GLPK.Optimizer, [1.0, 2.0], [0.5, 0.5], 1.25) +julia> mathoptinterface_knapsack(HiGHS.Optimizer, [1.0, 2.0], [0.5, 0.5], 1.25) 2-element Vector{Float64}: 0.0 2.0 @@ -228,61 +228,48 @@ julia> mathoptinterface_knapsack(GLPK.Optimizer, [1.0, 2.0], [0.5, 0.5], 1.25) The code is becoming more verbose and looking less like the mathematical formulation that we started with. -### Step IV: MathOptInterface to GLPK +### Step IV: MathOptInterface to HiGHS -As a final step, the [GLPK.jl](https://github.com/jump-dev/GLPK.jl) package +As a final step, the [HiGHS.jl](https://github.com/jump-dev/HiGHS.jl) package converts the MathOptInterface form, i.e., `mathoptinterface_knapsack`, into a -GLPK-specific API: +HiGHS-specific API: ```jldoctest -julia> using GLPK +julia> using HiGHS -julia> function glpk_knapsack(c, w, b) +julia> function highs_knapsack(c, w, b) n = length(c) - model = glp_create_prob() - glp_add_cols(model, n) + model = Highs_create() for i in 1:n - glp_set_col_bnds(model, i, GLP_LO, 0.0, GLP_DBL_MAX) - glp_set_col_kind(model, i, GLP_IV) - glp_set_col_name(model, i, "x[$i]") + Highs_addCol(model, c[i], 0.0, Inf, 0, C_NULL, C_NULL) + Highs_changeColIntegrality(model, i-1, 1) end - glp_set_obj_dir(model, GLP_MAX) - for i in 1:n - glp_set_obj_coef(model, i, c[i]) - end - glp_set_obj_coef(model, 0, 0.0) - glp_add_rows(model, 1) - glp_set_mat_row( + Highs_changeObjectiveSense(model, -1) + Highs_addRow( model, - 1, - length(w), - Ref(Cint.(1:n), 0), - Ref(w, 0), + -Inf, + b, + Cint(length(w)), + collect(Cint(0):Cint(n-1)), + w, ) - glp_set_row_bnds(model, 1, GLP_UP, -GLP_DBL_MAX, b) - simplex_options = glp_smcp() - glp_init_smcp(simplex_options) - simplex_options.msg_lev = GLP_MSG_ERR - glp_simplex(model, simplex_options) - options = glp_iocp() - glp_init_iocp(options) - options.msg_lev = GLP_MSG_ERR - glp_intopt(model, options) - x = glp_mip_col_val.(model, 1:n) - glp_delete_prob(model) + Highs_run(model) + x = fill(NaN, 2) + Highs_getSolution(model, x, C_NULL, C_NULL, C_NULL) + Highs_destroy(model) return x end -glpk_knapsack (generic function with 1 method) +highs_knapsack (generic function with 1 method) -julia> glpk_knapsack([1.0, 2.0], [0.5, 0.5], 1.25) +julia> highs_knapsack([1.0, 2.0], [0.5, 0.5], 1.25) 2-element Vector{Float64}: 0.0 2.0 ``` We've now gone from a algebraic model that looked identical to the mathematical -model we started with, to a verbose function that uses GLPK-specific +model we started with, to a verbose function that uses HiGHS-specific functionality. -The difference between `algebraic_knapsack` and `glpk_knapsack` highlights the +The difference between `algebraic_knapsack` and `highs_knapsack` highlights the benefit that algebraic modeling languages provide to users. Moreover, if we used a different solver, the solver-specific function would be entirely different. A key benefit of an algebraic modeling language is that you can change the solver diff --git a/docs/src/installation.md b/docs/src/installation.md index 7aee060dece..f329a9bbea9 100644 --- a/docs/src/installation.md +++ b/docs/src/installation.md @@ -115,7 +115,7 @@ The link in the `Solver` column is the corresponding Julia package. | [FICO Xpress](https://www.fico.com/en/products/fico-xpress-optimization-suite) | [Xpress.jl](https://github.com/jump-dev/Xpress.jl) | Manual | Comm. | (MI)LP, (MI)SOCP | | [GLPK](http://www.gnu.org/software/glpk/) | [GLPK.jl](https://github.com/jump-dev/GLPK.jl) | | GPL | (MI)LP | | [Gurobi](https://gurobi.com) | [Gurobi.jl](https://github.com/jump-dev/Gurobi.jl) | Manual | Comm. | (MI)LP, (MI)SOCP | -| [HiGHS](https://github.com/ERGO-Code/HiGHS) | [HiGHS.jl](https://github.com/jump-dev/HiGHS.jl) | |MIT | LP | +| [HiGHS](https://github.com/ERGO-Code/HiGHS) | [HiGHS.jl](https://github.com/jump-dev/HiGHS.jl) | |MIT | (MI)LP | | [Hypatia.jl](https://github.com/chriscoey/Hypatia.jl) | | | MIT | LP, SOCP, SDP | | [Ipopt](https://github.com/coin-or/Ipopt) | [Ipopt.jl](https://github.com/jump-dev/Ipopt.jl) | | EPL | LP, QP, NLP | | [Juniper.jl](https://github.com/lanl-ansi/Juniper.jl) | | | MIT | (MI)SOCP, (MI)NLP | diff --git a/docs/src/manual/models.md b/docs/src/manual/models.md index 0d9804dce78..1a3646b7f35 100644 --- a/docs/src/manual/models.md +++ b/docs/src/manual/models.md @@ -1,7 +1,7 @@ ```@meta CurrentModule = JuMP DocTestSetup = quote - using JuMP, HiGHS, SCS, GLPK + using JuMP, HiGHS, SCS end DocTestFilters = [r"≤|<=", r"≥|>=", r" == | = ", r" ∈ | in ", r"MathOptInterface|MOI"] ``` @@ -538,14 +538,14 @@ A HiGHS model with 0 columns and 0 rows. A downside of direct mode is that there is no bridging layer. Therefore, only constraints which are natively supported by the solver are supported. For -example, `GLPK.jl` does not implement constraints of the form `l <= a' x <= u`. +example, `HiGHS.jl` does not implement quadratic constraints: ```julia direct_mode -julia> model = direct_model(GLPK.Optimizer()); +julia> model = direct_model(HiGHS.Optimizer()); julia> @variable(model, x[1:2]); -julia> @constraint(model, 1 <= x[1] + x[2] <= 2) -ERROR: Constraints of type MathOptInterface.ScalarAffineFunction{Float64}-in-MathOptInterface.Interval{Float64} are not supported by the solver. +julia> @constraint(model, x[1]^2 + x[2]^2 <= 2) +ERROR: Constraints of type MathOptInterface.MathOptInterface.ScalarQuadraticFunction{Float64}-in-MathOptInterface.LessThan{Float64} are not supported by the solver. If you expected the solver to support your problem, you may have an error in your formulation. Otherwise, consider using a different solver. diff --git a/docs/src/tutorials/linear/facility_location.jl b/docs/src/tutorials/linear/facility_location.jl index 5f73e567730..3b3a624a7ab 100644 --- a/docs/src/tutorials/linear/facility_location.jl +++ b/docs/src/tutorials/linear/facility_location.jl @@ -129,6 +129,9 @@ ufl = Model(HiGHS.Optimizer) #- # Solve the uncapacitated facility location problem with HiGHS optimize!(ufl) + +#- + println("Optimal value: ", objective_value(ufl)) # ### Visualizing the solution @@ -258,6 +261,9 @@ cfl = Model(HiGHS.Optimizer) #- # Solve the problem optimize!(cfl) + +#- + println("Optimal value: ", objective_value(cfl)) # ### Visualizing the solution diff --git a/docs/src/tutorials/linear/n-queens.jl b/docs/src/tutorials/linear/n-queens.jl index 4c8da95620f..2a4ac4d9468 100644 --- a/docs/src/tutorials/linear/n-queens.jl +++ b/docs/src/tutorials/linear/n-queens.jl @@ -69,5 +69,3 @@ optimize!(model) # We can now review the solution that our model found: solution = round.(Int, value.(x)) - -# ![Four Queens](../../assets/n_queens.png)