diff --git a/News.md b/News.md index ff85ec26..5dfa821e 100644 --- a/News.md +++ b/News.md @@ -4,10 +4,10 @@ - 4/12/2018: Initial release of combined EAGO packages v0.1.1. ## v0.1.2 -- 6/20/2018: [EAGO v0.1.2 has been tagged](https://github.com/PSORLab/EAGO.jl/releases/tag/v0.1.2). Significant speed and functionality updates. +- 6/20/2018: [**EAGO v0.1.2 has been tagged**](https://github.com/PSORLab/EAGO.jl/releases/tag/v0.1.2). Significant speed and functionality updates. ## v0.2.0 -- 6/14/2019: [EAGO v0.2.0 has been tagged](https://github.com/PSORLab/EAGO.jl/releases/tag/v0.2.0). This update creates a number of breaking changes to the EAGO API. Please review the use cases provided in the documentation to update examples. +- 6/14/2019: [**EAGO v0.2.0 has been tagged**](https://github.com/PSORLab/EAGO.jl/releases/tag/v0.2.0). This update creates a number of breaking changes to the EAGO API. Please review the use cases provided in the documentation to update examples. - Updated to support Julia 1.0+, MathOptInterface (MOI), and MOI construction of subproblems. - Additional domain reduction routines available. - Support for specialized handling of linear and quadratic terms. @@ -60,5 +60,12 @@ - Drops appveyor CI and Travis CI in favor of Github Actions. - 11/18/2020 [**EAGO v0.5.1 has been tagged**](https://github.com/PSORLab/EAGO.jl/releases/tag/v0.5.1) - Support for Julia ~1 (with limited functionality for Julia 1.0, 1.1). -- 11/18/2020 **EAGO v0.5.2 has been tagged** +- 11/18/2020 [**EAGO v0.5.2 has been tagged**](https://github.com/PSORLab/EAGO.jl/releases/tag/v0.5.2) - Fix user specified branching variables. + +## v0.8.0 +- 6/12/2023: [**EAGO v0.8.0 has been tagged**](https://github.com/PSORLab/EAGO.jl/releases/tag/v0.8.0). + - Updated EAGO for compatibility with the nonlinear expression API changes introduced in JuMP v1.2: https://discourse.julialang.org/t/ann-upcoming-refactoring-of-jumps-nonlinear-api/83052 + - EAGO now uses the `MOI.Nonlinear` submodule instead of `JuMP._Derivatives`. + - Models, nodes, expressions, constraints, and operators are now compatible with MOI. + - Added logic and comparison operators to `EAGO.OperatorRegistry`. \ No newline at end of file diff --git a/Project.toml b/Project.toml index e6dbf238..8ec063b6 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "EAGO" uuid = "bb8be931-2a91-5aca-9f87-79e1cb69959a" authors = ["Matthew Wilhelm "] -version = "0.8.0" +version = "0.8.1" [deps] Cassette = "7057c7e9-c182-5462-911a-8362d720325c" diff --git a/README.md b/README.md index 05944724..43779b5e 100644 --- a/README.md +++ b/README.md @@ -99,11 +99,11 @@ As a global optimization platform, EAGO's solvers can be used to find solutions The EAGO package has numerous features: a solver accessible from JuMP/MathOptInterface (MOI), domain reduction routines, McCormick relaxations, and specialized non-convex semi-infinite program solvers. A full description of all EAGO features is available on the [**documentation website**](https://psorlab.github.io/EAGO.jl/dev/). A series of example have been provided in the form of Jupyter notebooks in the separate [**EAGO-notebooks**](https://github.com/PSORLab/EAGO-notebooks) repository. ## Recent News -- 6/12/2023: [EAGO v0.8.0 has been tagged](https://github.com/PSORLab/EAGO.jl/releases/tag/v0.8.0). - - Updated EAGO for compatibility with the nonlinear expression API changes introduced in JuMP v1.2: https://discourse.julialang.org/t/ann-upcoming-refactoring-of-jumps-nonlinear-api/83052 - - EAGO now uses the `MOI.Nonlinear` submodule instead of `JuMP._Derivatives`. - - Models, nodes, expressions, constraints, and operators are now compatible with MOI. - - Added logic and comparison operators to `EAGO.OperatorRegistry`. +- 6/15/2023: [**EAGO v0.8.1 has been tagged**](https://github.com/PSORLab/EAGO.jl/releases/tag/v0.8.1). + - Resolved an issue where integer and binary variables would sometimes throw an `MathOptInterface.UpperBoundAlreadySet` error. + - Added the function `unbounded_check!` which warns users if they are missing variable bounds and sets them to +/- 1E10 by default. + - Added an EAGO parameter `unbounded_check` which defaults to `true` and enables `unbounded_check!`. + - Bumped requirement for PrettyTables.jl to v2+ to accomodate the latest version of DataFrames.jl. For a full list of EAGO release news, click [**here**](https://github.com/PSORLab/EAGO.jl/releases). diff --git a/src/eago_optimizer/moi_wrapper.jl b/src/eago_optimizer/moi_wrapper.jl index 29d8aa8f..9190f4fd 100644 --- a/src/eago_optimizer/moi_wrapper.jl +++ b/src/eago_optimizer/moi_wrapper.jl @@ -176,7 +176,7 @@ MOI.get(m::Optimizer, ::MOI.DualStatus) = MOI.NO_SOLUTION MOI.get(m::Optimizer, ::MOI.ObjectiveBound) = m._objective_bound MOI.get(m::Optimizer, ::MOI.NumberOfVariables) = m._input_problem._variable_count MOI.get(m::Optimizer, ::MOI.SolverName) = "EAGO: Easy Advanced Global Optimization" -MOI.get(m::Optimizer, ::MOI.SolverVersion) = "0.7.1" +MOI.get(m::Optimizer, ::MOI.SolverVersion) = "0.8.1" MOI.get(m::Optimizer, ::MOI.TerminationStatus) = m._termination_status_code MOI.get(m::Optimizer, ::MOI.SolveTimeSec) = m._run_time MOI.get(m::Optimizer, ::MOI.NodeCount) = m._node_count diff --git a/src/eago_optimizer/optimize/nonconvex/display.jl b/src/eago_optimizer/optimize/nonconvex/display.jl index 45d72ef0..ec4cdf37 100644 --- a/src/eago_optimizer/optimize/nonconvex/display.jl +++ b/src/eago_optimizer/optimize/nonconvex/display.jl @@ -44,7 +44,7 @@ function print_solution!(m::GlobalOptimizer) println("LBD = $(MOI.get(m, MOI.ObjectiveBound()))") println("UBD = $(MOI.get(m, MOI.ObjectiveValue()))") end - println("Solution is :") + println("Solution is:") if m._feasible_solution_found for i = 1:m._input_problem._variable_count println(" X[$i] = $(m._continuous_solution[i])") diff --git a/src/eago_optimizer/optimize/nonconvex/stack_management.jl b/src/eago_optimizer/optimize/nonconvex/stack_management.jl index 33179058..1c97daab 100644 --- a/src/eago_optimizer/optimize/nonconvex/stack_management.jl +++ b/src/eago_optimizer/optimize/nonconvex/stack_management.jl @@ -238,24 +238,27 @@ for cases where the interval bounds contain `-Inf` or `Inf`. If any branching va are missing bounds, add the missing bound at +/- 1e10 and warn the user. """ function unbounded_check!(m::GlobalOptimizer) - unbounded_flag = false - wp = m._working_problem - epigraph_flag = _variable_num(FullVar(), m) != m._input_problem._variable_count - for i = 1:_variable_num(BranchVar(), m) - epigraph_flag #Not including epigraph reformulation variable - if !wp._variable_info[i].has_lower_bound - unbounded_flag = true - wp._variable_info[i] = VariableInfo(wp._variable_info[i], GT(-1e10)) - end - if !wp._variable_info[i].has_upper_bound - unbounded_flag = true - wp._variable_info[i] = VariableInfo(wp._variable_info[i], LT(1e10)) + if m._parameters.unbounded_check + unbounded_flag = false + wp = m._working_problem + epigraph_flag = _variable_num(FullVar(), m) != m._input_problem._variable_count + for i = 1:_variable_num(BranchVar(), m) - epigraph_flag #Not including epigraph reformulation variable + if !wp._variable_info[i].has_lower_bound + unbounded_flag = true + wp._variable_info[i] = VariableInfo(wp._variable_info[i], GT(-1e10)) + end + if !wp._variable_info[i].has_upper_bound + unbounded_flag = true + wp._variable_info[i] = VariableInfo(wp._variable_info[i], LT(1e10)) + end end + unbounded_flag && @warn(""" + At least one branching variable is unbounded. This will interfere with EAGO's global + optimization routine and may cause unexpected results. Bounds have been automatically + generated at +/- 1e10 for all unbounded variables, but tighter user-defined bounds are + highly recommended. To disable this warning and the automatic generation of bounds, use + the option `unbounded_check = false`.""") end - unbounded_flag && @warn(""" - At least one branching variable is unbounded. This will interfere with EAGO's global - optimization routine and may cause unexpected results. Bounds have been automatically - generated at +/- 1e10 for all unbounded variables, but tighter user-defined bounds are - highly recommended.""") end """ diff --git a/src/eago_optimizer/types/global_optimizer.jl b/src/eago_optimizer/types/global_optimizer.jl index a7c0369a..41ec0eff 100644 --- a/src/eago_optimizer/types/global_optimizer.jl +++ b/src/eago_optimizer/types/global_optimizer.jl @@ -222,7 +222,7 @@ Base.@kwdef mutable struct EAGOParameters cut_safe_b::Float64 = 1E9 "Solve upper problem for every node with depth less than `upper_bounding_depth`, - and otherwise solve upper problems with a probability of (1/2)^(depth-upper_bounding_depth) + and otherwise solve upper problems with a probability of `(1/2)^(depth-upper_bounding_depth)` (default = 8)" upper_bounding_depth::Int = 8 @@ -241,8 +241,10 @@ Base.@kwdef mutable struct EAGOParameters integer_rel_tol::Float64 = 1E-9 # Other forcing options - "Ignore EAGO's ability to parse problem types and force it to run global optimization" + "Ignore EAGO's ability to parse problem types and force it to run global optimization (default = false)" force_global_solve::Bool = false + "Check that all branching variables have finite bounds and set them to +/- 1E10 if not (default = true)" + unbounded_check::Bool = true end const EAGO_PARAMETERS = fieldnames(EAGOParameters)