Skip to content

Commit

Permalink
Remove GLPK
Browse files Browse the repository at this point in the history
  • Loading branch information
odow committed Dec 30, 2024
1 parent e5c8113 commit f16c4cc
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 23 deletions.
2 changes: 0 additions & 2 deletions docs/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ Downloads = "f43a241f-c20a-4ad4-852c-f6b1247861c6"
Dualization = "191a621a-6537-11e9-281d-650236a99e60"
Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9"
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
GLPK = "60bf3e95-4087-53dc-ae20-288a0d20c6a6"
Gurobi = "2e9cd046-0924-5485-92f1-d5272153d98b"
HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3"
HiGHS = "87dc4568-4c63-4d18-b0c0-bb2238e4078b"
Expand Down Expand Up @@ -61,7 +60,6 @@ DocumenterCitations = "1"
Dualization = "0.5"
Enzyme = "0.13.7"
ForwardDiff = "0.10"
GLPK = "=1.2.1"
Gurobi = "1"
HTTP = "1.5.4"
HiGHS = "=1.12.0"
Expand Down
68 changes: 47 additions & 21 deletions docs/src/tutorials/linear/callbacks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
# The tutorial uses the following packages:

using JuMP
import GLPK
import Gurobi
import Random
import Test

Expand All @@ -29,7 +29,8 @@ import Test
# An example using a lazy constraint callback.

function example_lazy_constraint()
model = Model(GLPK.Optimizer)
model = Model(Gurobi.Optimizer)
set_silent(model)
@variable(model, 0 <= x <= 2.5, Int)
@variable(model, 0 <= y <= 2.5, Int)
@objective(model, Max, y)
Expand Down Expand Up @@ -57,6 +58,7 @@ function example_lazy_constraint()
println("Adding $(con)")
MOI.submit(model, MOI.LazyConstraint(cb_data), con)
end
return
end
set_attribute(model, MOI.LazyConstraintCallback(), my_callback_function)
optimize!(model)
Expand All @@ -78,7 +80,11 @@ function example_user_cut_constraint()
Random.seed!(1)
N = 30
item_weights, item_values = rand(N), rand(N)
model = Model(GLPK.Optimizer)
model = Model(Gurobi.Optimizer)
set_silent(model)
## Turn off "Cuts" parameter so that our new one must be called. In real
## models, you should leave "Cuts" turned on.
set_attribute(model, "Cuts", 0)
@variable(model, x[1:N], Bin)
@constraint(model, sum(item_weights[i] * x[i] for i in 1:N) <= 10)
@objective(model, Max, sum(item_values[i] * x[i] for i in 1:N))
Expand Down Expand Up @@ -115,7 +121,11 @@ function example_heuristic_solution()
Random.seed!(1)
N = 30
item_weights, item_values = rand(N), rand(N)
model = Model(GLPK.Optimizer)
model = Model(Gurobi.Optimizer)
set_silent(model)
## Turn off "Heuristics" parameter so that our new one must be called. In
## real models, you should leave "Heuristics" turned on.
set_attribute(model, "Heuristics", 0)
@variable(model, x[1:N], Bin)
@constraint(model, sum(item_weights[i] * x[i] for i in 1:N) <= 10)
@objective(model, Max, sum(item_values[i] * x[i] for i in 1:N))
Expand All @@ -140,41 +150,57 @@ end

example_heuristic_solution()

# ## GLPK solver-dependent callback
# ## Gurobi solver-dependent callback

# An example using GLPK's solver-dependent callback.
# An example using Gurobi's solver-dependent callback.

function example_solver_dependent_callback()
model = Model(GLPK.Optimizer)
model = direct_model(Gurobi.Optimizer())
@variable(model, 0 <= x <= 2.5, Int)
@variable(model, 0 <= y <= 2.5, Int)
@objective(model, Max, y)
lazy_called = false
function my_callback_function(cb_data)
lazy_called = true
reason = GLPK.glp_ios_reason(cb_data.tree)
println("Called from reason = $(reason)")
if reason != GLPK.GLP_IROWGEN
cb_calls = Cint[]
function my_callback_function(cb_data, cb_where::Cint)
# You can reference variables outside the function as normal
push!(cb_calls, cb_where)
# You can select where the callback is run
if cb_where == Gurobi.GRB_CB_MIPNODE
# You can query a callback attribute using GRBcbget
resultP = Ref{Cint}()
Gurobi.GRBcbget(
cb_data,
cb_where,
Gurobi.GRB_CB_MIPNODE_STATUS,
resultP,
)
if resultP[] != Gurobi.GRB_OPTIMAL
return # Solution is something other than optimal.
end
elseif cb_where != Gurobi.GRB_CB_MIPSOL
return
end
# Before querying `callback_value`, you must call:
Gurobi.load_callback_variable_primal(cb_data, cb_where)
x_val = callback_value(cb_data, x)
y_val = callback_value(cb_data, y)
# You can submit solver-independent MathOptInterface attributes such as
# lazy constraints, user-cuts, and heuristic solutions.
if y_val - x_val > 1 + 1e-6
con = @build_constraint(y - x <= 1)
println("Adding $(con)")
MOI.submit(model, MOI.LazyConstraint(cb_data), con)
elseif y_val + x_val > 3 + 1e-6
con = @build_constraint(y - x <= 1)
println("Adding $(con)")
con = @build_constraint(y + x <= 3)
MOI.submit(model, MOI.LazyConstraint(cb_data), con)
end
# You can terminate the callback as follows:
Gurobi.GRBterminate(backend(model))
return
end
set_attribute(model, GLPK.CallbackFunction(), my_callback_function)
# You _must_ set this parameter if using lazy constraints.
set_attribute(model, "LazyConstraints", 1)
set_attribute(model, Gurobi.CallbackFunction(), my_callback_function)
optimize!(model)
Test.@test is_solved_and_feasible(model)
Test.@test lazy_called
Test.@test value(x) == 1
Test.@test value(y) == 2
Test.@test termination_status(model) == MOI.INTERRUPTED
return
end

Expand Down

0 comments on commit f16c4cc

Please sign in to comment.