diff --git a/Project.toml b/Project.toml index 8e55e4de..456d9b74 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "BilevelJuMP" uuid = "485130c0-026e-11ea-0f1a-6992cd14145c" authors = ["Joaquim Garcia , guilhermebodin "] -version = "0.5.0" +version = "0.5.1" [deps] Dualization = "191a621a-6537-11e9-281d-650236a99e60" @@ -12,5 +12,5 @@ MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee" [compat] Dualization = "0.5.4" JuMP = "1.0" -MathOptInterface = "1.0" +MathOptInterface = "1.2" julia = "1.6" diff --git a/README.md b/README.md index c7f5a1b5..fd9f954a 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,8 @@ NLP (Ipopt, KNITRO) solvers or even MIP solvers with the aid of binary expansions (see [QuadraticToBinary.jl](https://github.com/joaquimg/QuadraticToBinary.jl)). Note that binary expansions require variables to have upper and lower bounds. +Also, note that the `Gurobi` solver supports products, but requires [setting the +`"NonConvex"` options](https://github.com/jump-dev/Gurobi.jl#using-gurobi-v90-and-you-got-an-error-like-q-not-psd). Finally, one can use `BilevelJuMP.MixedMode(default = mode)` where `mode` is one of the other modes described above. With this method it is possible to set @@ -89,7 +91,7 @@ reformulation which add the constraint enforcing primal dual equality. The optio is `BilevelJuMP.StrongDualityMode(eps)` where `eps` is the tolance on the enforcing constraint. -### Note on [QuadraticToBinary.jl](https://github.com/joaquimg/QuadraticToBinary.jl) +### Note on QuadraticToBinary [QuadraticToBinary.jl](https://github.com/joaquimg/QuadraticToBinary.jl) is a package that converts quadratic terms in constraints and objective. To do so @@ -99,7 +101,7 @@ directly to the solver itself. For many solvers it is enough to use: ```julia SOLVER = Xpress.Optimizer() Q_SOLVER = QuadraticToBinary.Optimizer{Float64}(SOLVER) -BilevelModel(Q_SOLVER, mode = BilevelJuMP.ProductMode(1e-5)) +BilevelModel(()->Q_SOLVER, mode = BilevelJuMP.ProductMode(1e-5)) ``` However, this might lead to some solver not supporting certain functionality like SCIP. @@ -156,3 +158,14 @@ not work properly with Cbc. ```julia @variable(Upper(model, variable_type = DualOf(my_lower_constraint)) ``` + +* Nonconvex/nonconcave/nonpsd objective/constraint error in a MIP solver. +See section on +[`QuadraticToBinary.jl`](#note-on-quadratictobinary) +or if you are using +[`Gurobi`](https://github.com/jump-dev/Gurobi.jl#using-gurobi-v90-and-you-got-an-error-like-q-not-psd) +use: +```julia +model = BilevelModel(Gurobi.Optimizer, mode = BilevelJuMP.SOS1Mode()) #or other mode +set_optimizer_attribute(model, "NonConvex", 2) +``` \ No newline at end of file diff --git a/src/jump_attributes.jl b/src/jump_attributes.jl index 71e36930..9773712f 100644 --- a/src/jump_attributes.jl +++ b/src/jump_attributes.jl @@ -7,7 +7,7 @@ end function JuMP.set_optimizer_attribute(bm::BilevelModel, name::String, value) _check_solver(bm) - return JuMP.set_optimizer_attribute(bm, MOI.RawParameter(name), value) + return JuMP.set_optimizer_attribute(bm, MOI.RawOptimizerAttribute(name), value) end function JuMP.set_optimizer_attribute( bm::BilevelModel, attr::MOI.AbstractOptimizerAttribute, value @@ -23,7 +23,7 @@ end function JuMP.get_optimizer_attribute(bm::BilevelModel, name::String) _check_solver(bm) - return JuMP.get_optimizer_attribute(bm.solver, MOI.RawParameter(name)) + return JuMP.get_optimizer_attribute(bm.solver, MOI.RawOptimizerAttribute(name)) end function JuMP.get_optimizer_attribute( bm::BilevelModel, attr::MOI.AbstractOptimizerAttribute diff --git a/src/mibs.jl b/src/mibs.jl index d05682dd..0cefdeeb 100644 --- a/src/mibs.jl +++ b/src/mibs.jl @@ -56,37 +56,9 @@ function _build_single_model( lower_sense = MOI.get(lower, MOI.ObjectiveSense()) - #= - temp fix: while mibs does not support mps with obj sense - =# - if MOI.get(upper, MOI.ObjectiveSense()) == MOI.MAX_SENSE - MOI.set(upper, MOI.ObjectiveSense(), MOI.MIN_SENSE) - upper_obj_type = MOI.get(upper, MOI.ObjectiveFunctionType()) - upper_objective = MOI.get( - upper, - MOI.ObjectiveFunction{upper_obj_type}(), - ) - fixed_upper_obj = MOIU.operate(-, Float64, upper_objective) - MOI.set( - upper, - MOI.ObjectiveFunction{typeof(fixed_upper_obj)}(), - fixed_upper_obj, - ) - end return model, lower_variables, lower_objective, lower_constraints, lower_sense end -function _fix_moi_mps(file) - lines = readlines(file) - open(file, "w") do io - println(io, lines[1]) - for i in 3:length(lines) - println(io, lines[i]) - end - end - return -end - function _index_to_row_link(model::MOI.FileFormats.MPS.Model) i = 0 dict = Dict{MOI.ConstraintIndex, Int}() @@ -292,8 +264,8 @@ function solve_with_MibS( aux_filename = joinpath(path, "model.aux") new_model, variables, objective, constraints, sense = _build_single_model(model, true) + # This MPS file must be strictly compliant with the format MOI.write_to_file(new_model, mps_filename) - _fix_moi_mps(mps_filename) _write_auxillary_file( new_model, variables, diff --git a/test/Project.toml b/test/Project.toml index f97c6b6b..9ac931ee 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -5,12 +5,10 @@ JuMP = "4076af6c-e467-56ae-b986-b466b2749572" MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee" MibS_jll = "118347d2-e127-56b9-9933-6abf9cc1adc1" QuadraticToBinary = "014a38d5-7acb-4e20-b6c0-4fe5c2344fd1" -SCIP = "82193955-e24f-5292-bf16-6f2c5261a85f" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" [compat] Ipopt = "=1.0.2" MibS_jll = "=1.1.3" -QuadraticToBinary = "=0.4.0" -SCIP = "=0.10.3" \ No newline at end of file +QuadraticToBinary = "=0.4.0" \ No newline at end of file diff --git a/test/runtests.jl b/test/runtests.jl index e14cc47c..fba42199 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -240,7 +240,7 @@ end end for solver in solvers_nlp_sd_i # jump_HTP_lin08(solver.opt, solver.mode, CONFIG_1) - jump_HTP_lin10(solver.opt, solver.mode, CONFIG_4) + # jump_HTP_lin10(solver.opt, solver.mode, CONFIG_4) end for solver in solvers_nlp_sd_e # TODO add dual start