From 8069ed2da14574d300e182f9538ce9a985cdb8c2 Mon Sep 17 00:00:00 2001 From: odow Date: Tue, 13 Aug 2024 12:25:11 +1200 Subject: [PATCH] Remove unnecessary calls to Base.eval --- src/bounding_model.jl | 11 +++++------ src/log.jl | 11 +++++++---- src/main_algorithm.jl | 9 ++++++--- src/multilinear.jl | 11 +++++++++-- src/nlexpr.jl | 2 +- src/operators.jl | 2 +- src/presolve.jl | 1 - src/utility.jl | 4 +--- 8 files changed, 30 insertions(+), 21 deletions(-) diff --git a/src/bounding_model.jl b/src/bounding_model.jl index fd041ea1..b94bbed7 100644 --- a/src/bounding_model.jl +++ b/src/bounding_model.jl @@ -195,7 +195,10 @@ end function amp_post_lifted_objective(m::Optimizer) #if isa(m.obj_expr_orig, Number) - if expr_isconst(m.obj_expr_orig) + if m.obj_expr_orig == :(+()) + JuMP.@objective(m.model_mip, m.sense_orig, 0.0) + elseif expr_isconst(m.obj_expr_orig) + # This eval is okay because expr_isconst is true JuMP.@objective(m.model_mip, m.sense_orig, eval(m.obj_expr_orig)) elseif m.obj_structure == :affine JuMP.@objective( @@ -235,7 +238,6 @@ function add_partition(m::Optimizer; kwargs...) point_vec = m.best_bound_sol if isa(get_option(m, :disc_add_partition_method), Function) - # m.discretization = eval(get_option(m, :disc_add_partition_method))(m, use_disc=discretization, use_solution=point_vec) m.discretization = get_option(m, :disc_add_partition_method)( m, use_disc = discretization, @@ -441,9 +443,6 @@ function update_partition_scaling_factor(m::Optimizer, presolve = false) m.logs[:n_iter] > 2 && return get_option(m, :partition_scaling_factor) # Stop branching after the second iterations ratio_pool = [8:2:20;] # Built-in try range - convertor = Dict(MOI.MAX_SENSE => :<, MOI.MIN_SENSE => :>) - # revconvertor = Dict(MOI.MAX_SENSE => :>, MOI.MIN_SENSE => :<) - incumb_ratio = ratio_pool[1] is_min_sense(m) ? incumb_res = -Inf : incumb_res = Inf res_collector = Float64[] @@ -469,7 +468,7 @@ function update_partition_scaling_factor(m::Optimizer, presolve = false) create_bounding_mip(m, use_disc = branch_disc) res = disc_branch_solve(m) push!(res_collector, res) - if eval(convertor[m.sense_orig])(res, incumb_res) # && abs(abs(collector[end]-res)/collector[end]) > 1e-1 # %1 of difference + if m.sense_orig == MOI.MAX_SENSE ? res < incumb_res : res > incumb_res incumb_res = res incumb_ratio = r end diff --git a/src/log.jl b/src/log.jl index 6bf1c4ee..23193b13 100644 --- a/src/log.jl +++ b/src/log.jl @@ -114,12 +114,12 @@ function logging_summary(m::Optimizer) end function logging_head(m::Optimizer) - if is_min_sense(m) + if !is_max_sense(m) printstyled("LOWER-BOUNDING ITERATIONS", color = :cyan, bold = true) UB_iter = "Incumbent" UB = "Best Incumbent" LB = "Lower Bound" - elseif is_max_sense(m) + else printstyled("UPPER-BOUNDING ITERATIONS", color = :cyan, bold = true) UB_iter = "Incumbent" UB = "Best Incumbent" @@ -148,8 +148,11 @@ function logging_row_entry(m::Optimizer; kwargs...) spc = max(0, b_len - length(objstr)) end UB_block = string(" ", objstr, " "^spc) - - if expr_isconst(m.obj_expr_orig) + if m.obj_expr_orig == :(+()) + bdstr = 0.0 + spc = b_len - 1 + elseif expr_isconst(m.obj_expr_orig) + # This eval is okay because expr_isconst is true bdstr = eval(m.obj_expr_orig) spc = b_len - length(bdstr) elseif isa(m.logs[:bound][end], Float64) diff --git a/src/main_algorithm.jl b/src/main_algorithm.jl index b6b58a60..4a3cdda8 100644 --- a/src/main_algorithm.jl +++ b/src/main_algorithm.jl @@ -304,7 +304,6 @@ function check_exit(m::Optimizer) # constant objective with feasible local solve check if expr_isconst(m.obj_expr_orig) && (m.status[:local_solve] == MOI.OPTIMAL || m.status == MOI.LOCALLY_SOLVED) - # m.best_bound = eval(m.obj_expr_orig) m.best_bound = m.obj_expr_orig m.best_rel_gap = 0.0 m.best_abs_gap = 0.0 @@ -544,7 +543,12 @@ function bounding_solve(m::Optimizer) )+1] = copy(candidate_bound_sol) # Requires proper offseting end push!(m.logs[:bound], candidate_bound) - if eval(convertor[m.sense_orig])(candidate_bound, m.best_bound) + is_tighter = ifelse( + m.sense_orig == MOI.MAX_SENSE, + candidate_bound < m.best_bound, + candidate_bound > m.best_bound, + ) + if is_tighter m.best_bound = candidate_bound m.best_bound_sol = copy(candidate_bound_sol) m.status[:bounding_solve] = status @@ -590,7 +594,6 @@ function pick_disc_vars(m::Optimizer) disc_var_pick = get_option(m, :disc_var_pick) if isa(disc_var_pick, Function) - # eval(get_option(m, :disc_var_pick))(m) disc_var_pick(m) length(m.disc_vars) == 0 && length(m.nonconvex_terms) > 0 && diff --git a/src/multilinear.jl b/src/multilinear.jl index 38c439a0..68bf2087 100644 --- a/src/multilinear.jl +++ b/src/multilinear.jl @@ -325,8 +325,15 @@ function amp_warmstart_α(m::Optimizer, α::Dict) for i in 1:m.bound_sol_pool[:cnt] m.bound_sol_pool[:stat][i] == :Warmstarter && (m.bound_sol_pool[:stat][i] = :Alive) # reset the status if not dead - if m.bound_sol_pool[:stat][i] != :Dead && - eval(comp_opr[m.sense_orig])(m.bound_sol_pool[:obj][i], ws_obj) + if m.bound_sol_pool[:stat][i] == :Dead + continue + end + is_better = ifelse( + m.sense_orig == MOI.MAX_SENSE, + m.bound_sol_pool[:obj][i] > ws_obj, + m.bound_sol_pool[:obj][i] < ws_obj, + ) + if is_better ws_idx = i ws_obj = m.bound_sol_pool[:obj][i] end diff --git a/src/nlexpr.jl b/src/nlexpr.jl index 9bff622f..c271fe45 100644 --- a/src/nlexpr.jl +++ b/src/nlexpr.jl @@ -211,7 +211,7 @@ function expr_constr_parsing(expr::Expr, m::Optimizer, idx::Int = 0) # First process user-defined structures in-cases of over-ride # for i in 1:length(get_option(m, :constr_patterns)) - # is_structural = eval(get_option(m, :constr_patterns)[i])(expr, m, idx) + # is_structural = get_option(m, :constr_patterns)[i](expr, m, idx) # return # end diff --git a/src/operators.jl b/src/operators.jl index b3c93560..7eba1b6c 100644 --- a/src/operators.jl +++ b/src/operators.jl @@ -36,7 +36,7 @@ function detect_nonconvex_terms(expr::Any, constr_id::Int, m::Optimizer; kwargs. # First process user-defined structures in-cases of over-ride # for i in 1:length(get_option(m, :term_patterns)) - # skip, expr = eval(get_option(m, :term_patterns)[i])(expr, constr_id, m) + # skip, expr = get_option(m, :term_patterns)[i](expr, constr_id, m) # skip && return expr # end diff --git a/src/presolve.jl b/src/presolve.jl index f9ca770f..8c599bed 100644 --- a/src/presolve.jl +++ b/src/presolve.jl @@ -18,7 +18,6 @@ function bound_tightening_wrapper(m::Optimizer; use_bound = true, kwargs...) elseif get_option(m, :presolve_bt_algo) == 2 optimization_based_bound_tightening(m, use_bound = use_bound, use_tmc = true) elseif isa(get_option(m, :presolve_bt_algo), Function) - # eval(get_option(m, :presolve_bt_algo))(m) get_option(m, :presolve_bt_algo)(m) else error("Unrecognized bound tightening algorithm") diff --git a/src/utility.jl b/src/utility.jl index ac01d22a..0f8952d5 100644 --- a/src/utility.jl +++ b/src/utility.jl @@ -114,14 +114,12 @@ discretization_to_bounds(d::Dict, l::Int) = update_var_bounds(d, len = l) Update the data structure with feasible solution and its associated objective (if better) """ function update_incumbent(m::Optimizer, objval::Float64, sol::Vector) - convertor = Dict(MOI.MAX_SENSE => :>, MOI.MIN_SENSE => :<) push!(m.logs[:obj], objval) - if eval(convertor[m.sense_orig])(objval, m.best_obj) #&& !eval(convertor[m.sense_orig])(objval, m.best_bound) + if m.sense_orig == MOI.MAX_SENSE ? objval > m.best_obj : objval < m.best_obj m.best_obj = objval m.best_sol = sol m.detected_incumbent = true end - return end