Skip to content

Commit f25d565

Browse files
committed
Utilize XPRSoptimize for versions 41.01 and above, and update deprecated function calls for version 44.01.
1 parent 60ae1dd commit f25d565

File tree

1 file changed

+89
-21
lines changed

1 file changed

+89
-21
lines changed

src/MOI/MOI_wrapper.jl

+89-21
Original file line numberDiff line numberDiff line change
@@ -2907,13 +2907,33 @@ function MOI.optimize!(model::Optimizer)
29072907
_set_MIP_start(model)
29082908
end
29092909
start_time = time()
2910-
if model.has_nlp_constraints
2911-
@checked Lib.XPRSnlpoptimize(model.inner, model.solve_method)
2912-
elseif is_mip(model)
2913-
@checked Lib.XPRSmipoptimize(model.inner, model.solve_method)
2910+
2911+
version = getversion()
2912+
# Verson 41.01 introduces XPRSoptimize as a more general optimization routine,
2913+
# automatically selecting the algorithm based on the presence of mip entities and
2914+
# nonlinear constraints
2915+
if version >= v"41.01"
2916+
solvestatus = Ref{Int32}()
2917+
solstatus = Ref{Int32}()
2918+
@checked Lib.XPRSoptimize(
2919+
model.inner,
2920+
model.solve_method,
2921+
solvestatus,
2922+
solstatus,
2923+
)
2924+
opt_used = getattribute(model.inner, "XPRS_OPTIMIZETYPEUSED")
2925+
# 0: LP solver, 1: MIP solver, 2: Local nonlinear solver, 3: Global nonlinear solver
2926+
model.has_nlp_constraints = (opt_used == 2 || opt_used == 3)
29142927
else
2915-
@checked Lib.XPRSlpoptimize(model.inner, model.solve_method)
2928+
if model.has_nlp_constraints
2929+
@checked Lib.XPRSnlpoptimize(model.inner, model.solve_method)
2930+
elseif is_mip(model)
2931+
@checked Lib.XPRSmipoptimize(model.inner, model.solve_method)
2932+
else
2933+
@checked Lib.XPRSlpoptimize(model.inner, model.solve_method)
2934+
end
29162935
end
2936+
29172937
model.cached_solution.solve_time = time() - start_time
29182938
check_cb_exception(model)
29192939
# Should be almost a no-op if not needed. Might have minor overhead due to
@@ -2924,33 +2944,81 @@ function MOI.optimize!(model::Optimizer)
29242944
model.termination_status = _cache_termination_status(model)
29252945
model.primal_status = _cache_primal_status(model)
29262946
model.dual_status = _cache_dual_status(model)
2927-
# TODO: add @checked here - must review statuses
2928-
if model.has_nlp_constraints
2929-
Lib.XPRSgetnlpsol(
2947+
2948+
# XPRSgetnlpsol and XPRSgetmippsol are deprecated as of version 44.01
2949+
# XPRSgetsolution is also recommended instead of XPRSgetlpsol also after solving LPs
2950+
if version >= v"44.01"
2951+
sol_status = Ref{Int32}()
2952+
ncols = getattribute(model.inner, "XPRS_INPUTCOLS")
2953+
@checked Lib.XPRSgetsolution(
29302954
model.inner,
2955+
sol_status,
29312956
model.cached_solution.variable_primal,
2932-
model.cached_solution.linear_primal,
2933-
model.cached_solution.linear_dual,
2934-
model.cached_solution.variable_dual,
2957+
0,
2958+
ncols - 1,
29352959
)
2936-
elseif is_mip(model)
2937-
# TODO @checked (only works if not in [MOI.NO_SOLUTION, MOI.INFEASIBILITY_CERTIFICATE, MOI.INFEASIBLE_POINT])
2938-
Lib.XPRSgetmipsol(
2960+
slack_status = Ref{Int32}()
2961+
nrows = getattribute(model.inner, "XPRS_INPUTROWS")
2962+
@checked Lib.XPRSgetslacks(
29392963
model.inner,
2940-
model.cached_solution.variable_primal,
2964+
slack_status,
29412965
model.cached_solution.linear_primal,
2966+
0,
2967+
nrows - 1,
29422968
)
2943-
fill!(model.cached_solution.linear_dual, NaN)
2944-
fill!(model.cached_solution.variable_dual, NaN)
2945-
else
2946-
Lib.XPRSgetlpsol(
2969+
dual_status = Ref{Int32}()
2970+
@checked Lib.XPRSgetduals(
29472971
model.inner,
2948-
model.cached_solution.variable_primal,
2949-
model.cached_solution.linear_primal,
2972+
dual_status,
29502973
model.cached_solution.linear_dual,
2974+
0,
2975+
nrows - 1,
2976+
)
2977+
# Check if dual values are not available (MIP or global solves)
2978+
if dual_status[] == Lib.XPRS_SOLSTATUS_NOTFOUND
2979+
fill!(model.cached_solution.linear_dual, NaN)
2980+
end
2981+
redcost_status = Ref{Int32}()
2982+
@checked Lib.XPRSgetredcosts(
2983+
model.inner,
2984+
redcost_status,
29512985
model.cached_solution.variable_dual,
2986+
0,
2987+
ncols - 1,
29522988
)
2989+
if redcost_status[] == Lib.XPRS_SOLSTATUS_NOTFOUND
2990+
fill!(model.cached_solution.variable_dual, NaN)
2991+
end
2992+
else
2993+
# TODO: add @checked here - must review statuses
2994+
if model.has_nlp_constraints
2995+
Lib.XPRSgetnlpsol(
2996+
model.inner,
2997+
model.cached_solution.variable_primal,
2998+
model.cached_solution.linear_primal,
2999+
model.cached_solution.linear_dual,
3000+
model.cached_solution.variable_dual,
3001+
)
3002+
elseif is_mip(model)
3003+
# TODO @checked (only works if not in [MOI.NO_SOLUTION, MOI.INFEASIBILITY_CERTIFICATE, MOI.INFEASIBLE_POINT])
3004+
Lib.XPRSgetmipsol(
3005+
model.inner,
3006+
model.cached_solution.variable_primal,
3007+
model.cached_solution.linear_primal,
3008+
)
3009+
fill!(model.cached_solution.linear_dual, NaN)
3010+
fill!(model.cached_solution.variable_dual, NaN)
3011+
else
3012+
Lib.XPRSgetlpsol(
3013+
model.inner,
3014+
model.cached_solution.variable_primal,
3015+
model.cached_solution.linear_primal,
3016+
model.cached_solution.linear_dual,
3017+
model.cached_solution.variable_dual,
3018+
)
3019+
end
29533020
end
3021+
29543022
model.cached_solution.linear_primal .=
29553023
rhs .- model.cached_solution.linear_primal
29563024
status = MOI.get(model, MOI.PrimalStatus())

0 commit comments

Comments
 (0)