Skip to content

Commit

Permalink
Utilize XPRSoptimize for versions 41.01 and above, and update depreca…
Browse files Browse the repository at this point in the history
…ted function calls for version 44.01.
  • Loading branch information
trulsf committed Jan 14, 2025
1 parent 60ae1dd commit f25d565
Showing 1 changed file with 89 additions and 21 deletions.
110 changes: 89 additions & 21 deletions src/MOI/MOI_wrapper.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2907,13 +2907,33 @@ function MOI.optimize!(model::Optimizer)
_set_MIP_start(model)
end
start_time = time()
if model.has_nlp_constraints
@checked Lib.XPRSnlpoptimize(model.inner, model.solve_method)
elseif is_mip(model)
@checked Lib.XPRSmipoptimize(model.inner, model.solve_method)

version = getversion()
# Verson 41.01 introduces XPRSoptimize as a more general optimization routine,
# automatically selecting the algorithm based on the presence of mip entities and
# nonlinear constraints
if version >= v"41.01"
solvestatus = Ref{Int32}()
solstatus = Ref{Int32}()
@checked Lib.XPRSoptimize(
model.inner,
model.solve_method,
solvestatus,
solstatus,
)
opt_used = getattribute(model.inner, "XPRS_OPTIMIZETYPEUSED")
# 0: LP solver, 1: MIP solver, 2: Local nonlinear solver, 3: Global nonlinear solver
model.has_nlp_constraints = (opt_used == 2 || opt_used == 3)
else
@checked Lib.XPRSlpoptimize(model.inner, model.solve_method)
if model.has_nlp_constraints
@checked Lib.XPRSnlpoptimize(model.inner, model.solve_method)
elseif is_mip(model)
@checked Lib.XPRSmipoptimize(model.inner, model.solve_method)
else
@checked Lib.XPRSlpoptimize(model.inner, model.solve_method)
end
end

model.cached_solution.solve_time = time() - start_time
check_cb_exception(model)
# Should be almost a no-op if not needed. Might have minor overhead due to
Expand All @@ -2924,33 +2944,81 @@ function MOI.optimize!(model::Optimizer)
model.termination_status = _cache_termination_status(model)
model.primal_status = _cache_primal_status(model)
model.dual_status = _cache_dual_status(model)
# TODO: add @checked here - must review statuses
if model.has_nlp_constraints
Lib.XPRSgetnlpsol(

# XPRSgetnlpsol and XPRSgetmippsol are deprecated as of version 44.01
# XPRSgetsolution is also recommended instead of XPRSgetlpsol also after solving LPs
if version >= v"44.01"
sol_status = Ref{Int32}()
ncols = getattribute(model.inner, "XPRS_INPUTCOLS")
@checked Lib.XPRSgetsolution(
model.inner,
sol_status,
model.cached_solution.variable_primal,
model.cached_solution.linear_primal,
model.cached_solution.linear_dual,
model.cached_solution.variable_dual,
0,
ncols - 1,
)
elseif is_mip(model)
# TODO @checked (only works if not in [MOI.NO_SOLUTION, MOI.INFEASIBILITY_CERTIFICATE, MOI.INFEASIBLE_POINT])
Lib.XPRSgetmipsol(
slack_status = Ref{Int32}()
nrows = getattribute(model.inner, "XPRS_INPUTROWS")
@checked Lib.XPRSgetslacks(
model.inner,
model.cached_solution.variable_primal,
slack_status,
model.cached_solution.linear_primal,
0,
nrows - 1,
)
fill!(model.cached_solution.linear_dual, NaN)
fill!(model.cached_solution.variable_dual, NaN)
else
Lib.XPRSgetlpsol(
dual_status = Ref{Int32}()
@checked Lib.XPRSgetduals(
model.inner,
model.cached_solution.variable_primal,
model.cached_solution.linear_primal,
dual_status,
model.cached_solution.linear_dual,
0,
nrows - 1,
)
# Check if dual values are not available (MIP or global solves)
if dual_status[] == Lib.XPRS_SOLSTATUS_NOTFOUND
fill!(model.cached_solution.linear_dual, NaN)
end
redcost_status = Ref{Int32}()
@checked Lib.XPRSgetredcosts(
model.inner,
redcost_status,
model.cached_solution.variable_dual,
0,
ncols - 1,
)
if redcost_status[] == Lib.XPRS_SOLSTATUS_NOTFOUND
fill!(model.cached_solution.variable_dual, NaN)
end
else
# TODO: add @checked here - must review statuses
if model.has_nlp_constraints
Lib.XPRSgetnlpsol(
model.inner,
model.cached_solution.variable_primal,
model.cached_solution.linear_primal,
model.cached_solution.linear_dual,
model.cached_solution.variable_dual,
)
elseif is_mip(model)
# TODO @checked (only works if not in [MOI.NO_SOLUTION, MOI.INFEASIBILITY_CERTIFICATE, MOI.INFEASIBLE_POINT])
Lib.XPRSgetmipsol(
model.inner,
model.cached_solution.variable_primal,
model.cached_solution.linear_primal,
)
fill!(model.cached_solution.linear_dual, NaN)
fill!(model.cached_solution.variable_dual, NaN)
else
Lib.XPRSgetlpsol(
model.inner,
model.cached_solution.variable_primal,
model.cached_solution.linear_primal,
model.cached_solution.linear_dual,
model.cached_solution.variable_dual,
)
end
end

model.cached_solution.linear_primal .=
rhs .- model.cached_solution.linear_primal
status = MOI.get(model, MOI.PrimalStatus())
Expand Down

0 comments on commit f25d565

Please sign in to comment.