Skip to content

Commit

Permalink
v0.2.5 updates
Browse files Browse the repository at this point in the history
  • Loading branch information
harshangrjn committed May 30, 2021
1 parent b59bc27 commit d22a7c6
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 55 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Critical Updates for Alpine.jl

## v0.2.5
* Cleaning up of solver logs
* Time correction for local solve
* Removed unused `Alpine.Optimizer` options in solver.jl

## v0.2.4
* Added unit tests for utility functions
* Removed un-used functions from utility functions which aren't part of Alpine's algorithm
Expand Down
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name = "Alpine"
uuid = "07493b3f-dabb-5b16-a503-4139292d7dd4"
authors = ["Harsha Nagarajan, Site Wang, Kaarthik Sundar and contributors"]
repo = "https://github.com/lanl-ansi/Alpine.jl.git"
version = "0.2.4"
version = "0.2.5"

[deps]
Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b"
Expand Down
25 changes: 19 additions & 6 deletions src/algorithm.jl
Original file line number Diff line number Diff line change
Expand Up @@ -91,30 +91,43 @@ function presolve(m::Optimizer)
# Solver status - returns error when see different

if m.status[:local_solve] in STATUS_OPT || m.status[:local_solve] in STATUS_LIMIT
get_option(m, :log_level) > 0 && println(" Local solver returns a feasible point")

get_option(m, :log_level) > 0 && println(" Local solver returns a feasible point with value $(round(m.best_obj, digits=4))")

bound_tightening(m, use_bound = true) # performs bound-tightening with the local solve objective value

get_option(m, :presolve_bt) && init_disc(m) # Re-initialize discretization dictionary on tight bounds

get_option(m, :disc_ratio_branch) && (set_option(m, :disc_ratio, update_disc_ratio(m, true)))

add_partition(m, use_solution=m.best_sol) # Setting up the initial discretization
# get_option(m, :log_level) > 0 && println("Ending the presolve")

elseif m.status[:local_solve] in STATUS_INF

(get_option(m, :log_level) > 0) && println(" Bound tightening without objective bounds (OBBT)")

bound_tightening(m, use_bound = false) # do bound tightening without objective value

(get_option(m, :disc_ratio_branch)) && (set_option(m, :disc_ratio, update_disc_ratio(m, true)))

get_option(m, :presolve_bt) && init_disc(m)
# get_option(m, :log_level) > 0 && println("Ending the presolve")

elseif m.status[:local_solve] == MOI.INVALID_MODEL

@warn " Warning: Presolve ends with local solver yielding $(m.status[:local_solve]). \n This may come from Ipopt's `:Not_Enough_Degrees_Of_Freedom`. \n Consider more replace equality constraints with >= and <= to resolve this."

else

@warn " Warning: Presolve ends with local solver yielding $(m.status[:local_solve])."

end

cputime_presolve = time() - start_presolve
m.logs[:presolve_time] += cputime_presolve
m.logs[:total_time] = m.logs[:presolve_time]
m.logs[:time_left] -= m.logs[:presolve_time]
# (get_option(m, :log_level) > 0) && println("Presolve time = $(round.(m.logs[:total_time]; digits=2))s")
(get_option(m, :log_level) > 0) && println(" Completed presolve in $(round.(m.logs[:total_time]; digits=2))s ($(m.logs[:bt_iter]) iterations)")
(get_option(m, :log_level) > 0) && println(" Completed presolve in $(round.(m.logs[:total_time]; digits=2))s")
return
end

Expand Down Expand Up @@ -161,7 +174,7 @@ function check_exit(m::Optimizer)
m.logs[:n_iter] >= get_option(m, :max_iter) && return true
m.best_abs_gap <= get_option(m, :abs_gap) && return true

# Userlimits check
# User-limits check
m.logs[:time_left] < get_option(m, :tol) && return true

return false
Expand Down Expand Up @@ -234,7 +247,6 @@ function local_solve(m::Optimizer; presolve = false)
l_var, u_var = m.l_var_tight[1:m.num_var_orig], m.u_var_tight[1:m.num_var_orig]
end

start_local_solve = time()
x = load_nonlinear_model(m, local_solve_model, l_var, u_var)
(!m.d_orig.want_hess) && MOI.initialize(m.d_orig, [:Grad, :Jac, :Hess, :HessVec, :ExprGraph]) # Safety scheme for sub-solvers re-initializing the NLPEvaluator

Expand All @@ -257,6 +269,7 @@ function local_solve(m::Optimizer; presolve = false)
end
end

start_local_solve = time()
MOI.optimize!(local_solve_model)
local_nlp_status = MOI.get(local_solve_model, MOI.TerminationStatus())

Expand Down
31 changes: 19 additions & 12 deletions src/log.jl
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,15 @@ function logging_summary(m::Optimizer)
printstyled("\nPROBLEM STATISTICS\n", color=:cyan)
is_min_sense(m) && (println(" Objective sense = Min", ))
is_max_sense(m) && (println(" Objective sense = Max", ))
println(" #Variables = ", length([i for i in 1:m.num_var_orig if m.var_type[i] == :Cont]) + length([i for i in 1:m.num_var_orig if m.var_type[i] == :Bin]) + length([i for i in 1:m.num_var_orig if m.var_type[i] == :Int]))
println(" #Bin-Int Variables = ", length([i for i in 1:m.num_var_orig if m.var_type[i] == :Bin]) + length([i for i in 1:m.num_var_orig if m.var_type[i] == :Int]))
println(" #Constraints = ", m.num_constr_orig)
println(" #NL Constraints = ", m.num_nlconstr_orig)
println(" #Linear Constraints = ", m.num_lconstr_orig)
get_option(m, :recognize_convex) && println(" #Detected convex constraints = $(length([i for i in m.constr_structure if i == :convex]))")
println(" #Detected nonlinear terms = ", length(m.nonconvex_terms))
println(" #Variables involved in nonlinear terms = ", length(m.candidate_disc_vars))
println(" #Potential variables for partitioning = ", length(m.disc_vars))
println(" # Variables = ", length([i for i in 1:m.num_var_orig if m.var_type[i] == :Cont]) + length([i for i in 1:m.num_var_orig if m.var_type[i] == :Bin]) + length([i for i in 1:m.num_var_orig if m.var_type[i] == :Int]))
println(" # Bin-Int Variables = ", length([i for i in 1:m.num_var_orig if m.var_type[i] == :Bin]) + length([i for i in 1:m.num_var_orig if m.var_type[i] == :Int]))
println(" # Constraints = ", m.num_constr_orig)
println(" # NL Constraints = ", m.num_nlconstr_orig)
println(" # Linear Constraints = ", m.num_lconstr_orig)
get_option(m, :recognize_convex) && println(" # Detected convex constraints = $(length([i for i in m.constr_structure if i == :convex]))")
println(" # Detected nonlinear terms = ", length(m.nonconvex_terms))
println(" # Variables involved in nonlinear terms = ", length(m.candidate_disc_vars))
println(" # Potential variables for partitioning = ", length(m.disc_vars))

printstyled("SUB-SOLVERS USED BY ALPINE\n", color=:cyan)
if get_option(m, :minlp_solver) === nothing
Expand All @@ -53,8 +53,15 @@ function logging_summary(m::Optimizer)
println(" MIP solver = ", m.mip_solver_id)

printstyled("ALPINE CONFIGURATION\n", color=:cyan)
println(" Maximum iterations = ", get_option(m, :max_iter))
println(" Relative optimality gap criteria = ", get_option(m, :rel_gap)*100, "%")
if is_min_sense(m)
println(" Maximum iterations (lower-bounding MIPs) = ", get_option(m, :max_iter))
elseif is_max_sense(m)
println(" Maximum iterations (upper-bounding MIPs) = ", get_option(m, :max_iter))
else
println(" Maximum iterations (bounding MIPs) = ", get_option(m, :max_iter))
end

println(" Relative global optimality gap = ", get_option(m, :rel_gap)*100, "%")

if get_option(m, :disc_var_pick) == 0
println(" Potential variables chosen for partitioning = All")
Expand All @@ -72,7 +79,7 @@ function logging_summary(m::Optimizer)
(get_option(m, :convhull_ebd)) && println(" Encoding method = $(get_option(m, :convhull_ebd_encode))")
(get_option(m, :convhull_ebd)) && println(" Independent branching scheme = $(get_option(m, :convhull_ebd_ibs))")
println(" Bound-tightening (OBBT) presolve = ", get_option(m, :presolve_bt))
get_option(m, :presolve_bt) && println(" OBBT maximum iterations = ", get_option(m, :presolve_bt_max_iter))
get_option(m, :presolve_bt) && println(" Maximum iterations (OBBT) = ", get_option(m, :presolve_bt_max_iter))
end

end
Expand Down
2 changes: 1 addition & 1 deletion src/presolve.jl
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ function minmax_bound_tightening(m::Optimizer; use_bound = true, timelimit = Inf
timelimit = get_option(m, :presolve_time_limit)
end

# Regulating Special Input Conditions: default use best feasible solution objective value
# Regulating special input conditions: default use best feasible solution objective value
(use_bound == true) ? bound = m.best_obj : bound = Inf
l_var_orig = copy(m.l_var_tight)
u_var_orig = copy(m.u_var_tight)
Expand Down
Loading

0 comments on commit d22a7c6

Please sign in to comment.