Google OR-Tools v9.12
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
xpress_solver.h
Go to the documentation of this file.
1// Copyright 2010-2025 Google LLC
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14#ifndef OR_TOOLS_MATH_OPT_SOLVERS_XPRESS_SOLVER_H_
15#define OR_TOOLS_MATH_OPT_SOLVERS_XPRESS_SOLVER_H_
16
17#include <cstdint>
18#include <limits>
19#include <memory>
20#include <optional>
21#include <vector>
22
23#include "absl/status/status.h"
24#include "absl/status/statusor.h"
25#include "absl/time/time.h"
26#include "absl/types/span.h"
28#include "ortools/math_opt/callback.pb.h"
31#include "ortools/math_opt/infeasible_subsystem.pb.h"
32#include "ortools/math_opt/model.pb.h"
33#include "ortools/math_opt/model_parameters.pb.h"
34#include "ortools/math_opt/model_update.pb.h"
35#include "ortools/math_opt/parameters.pb.h"
36#include "ortools/math_opt/result.pb.h"
37#include "ortools/math_opt/solution.pb.h"
39#include "ortools/math_opt/sparse_containers.pb.h"
41
43
44// Interface to FICO XPRESS solver
45// Largely inspired by the Gurobi interface
46class XpressSolver : public SolverInterface {
47 public:
48 // Creates the XPRESS solver and loads the model into it
49 static absl::StatusOr<std::unique_ptr<XpressSolver>> New(
50 const ModelProto& input_model,
51 const SolverInterface::InitArgs& init_args);
52
53 // Solves the optimization problem
54 absl::StatusOr<SolveResultProto> Solve(
55 const SolveParametersProto& parameters,
56 const ModelSolveParametersProto& model_parameters,
57 MessageCallback message_cb,
58 const CallbackRegistrationProto& callback_registration, Callback cb,
59 const SolveInterrupter* interrupter) override;
60
61 // Updates the problem (not implemented yet)
62 absl::StatusOr<bool> Update(const ModelUpdateProto& model_update) override;
63
64 // Computes the infeasible subsystem (not implemented yet)
65 absl::StatusOr<ComputeInfeasibleSubsystemResultProto>
66 ComputeInfeasibleSubsystem(const SolveParametersProto& parameters,
67 MessageCallback message_cb,
68 const SolveInterrupter* interrupter) override;
69
70 private:
71 explicit XpressSolver(std::unique_ptr<Xpress> g_xpress);
72
73 // For easing reading the code, we declare these types:
74 using VarId = int64_t;
75 using AuxiliaryObjectiveId = int64_t;
76 using LinearConstraintId = int64_t;
77 using QuadraticConstraintId = int64_t;
78 using SecondOrderConeConstraintId = int64_t;
79 using Sos1ConstraintId = int64_t;
80 using Sos2ConstraintId = int64_t;
81 using IndicatorConstraintId = int64_t;
82 using AnyConstraintId = int64_t;
83 using XpressVariableIndex = int;
84 using XpressMultiObjectiveIndex = int;
85 using XpressLinearConstraintIndex = int;
86 using XpressQuadraticConstraintIndex = int;
87 using XpressSosConstraintIndex = int;
88 using XpressGeneralConstraintIndex = int;
89 using XpressAnyConstraintIndex = int;
90
91 static constexpr XpressVariableIndex kUnspecifiedIndex = -1;
92 static constexpr XpressAnyConstraintIndex kUnspecifiedConstraint = -2;
93 static constexpr double kPlusInf = XPRS_PLUSINFINITY;
94 static constexpr double kMinusInf = XPRS_MINUSINFINITY;
95
96 static bool isFinite(double value) {
97 return value < kPlusInf && value > kMinusInf;
98 }
99
100 // Data associated with each linear constraint
101 struct LinearConstraintData {
102 XpressLinearConstraintIndex constraint_index = kUnspecifiedConstraint;
103 double lower_bound = kMinusInf;
104 double upper_bound = kPlusInf;
105 };
106
107 absl::StatusOr<SolveResultProto> ExtractSolveResultProto(
108 absl::Time start, const ModelSolveParametersProto& model_parameters,
109 const SolveParametersProto& solve_parameters);
110 absl::StatusOr<SolutionProto> GetSolution(
111 const ModelSolveParametersProto& model_parameters,
112 const SolveParametersProto& solve_parameters);
113 absl::StatusOr<SolveStatsProto> GetSolveStats(absl::Time start) const;
114
115 absl::StatusOr<double> GetBestPrimalBound() const;
116 absl::StatusOr<double> GetBestDualBound() const;
117
118 absl::StatusOr<TerminationProto> ConvertTerminationReason(
119 double best_primal_bound, double best_dual_bound) const;
120
121 absl::StatusOr<SolutionProto> GetLpSolution(
122 const ModelSolveParametersProto& model_parameters,
123 const SolveParametersProto& solve_parameters);
124 bool isPrimalFeasible() const;
125 bool isDualFeasible() const;
126
127 absl::StatusOr<std::optional<BasisProto>> GetBasisIfAvailable(
128 const SolveParametersProto& parameters);
129
130 absl::Status AddNewLinearConstraints(const LinearConstraintsProto& cts);
131 absl::Status AddNewVariables(const VariablesProto& new_variables);
132 absl::Status AddSingleObjective(const ObjectiveProto& objective);
133 absl::Status ChangeCoefficients(const SparseDoubleMatrixProto& matrix);
134
135 absl::Status LoadModel(const ModelProto& input_model);
136
137 std::string GetLpOptimizationFlags(const SolveParametersProto& parameters);
138 absl::Status CallXpressSolve(const SolveParametersProto& parameters);
139
140 // Fills in result with the values in xpress_values aided by the index
141 // conversion from map which should be either variables_map_ or
142 // linear_constraints_map_ as appropriate. Only key/value pairs that passes
143 // the filter predicate are added.
144 template <typename T>
145 void XpressVectorToSparseDoubleVector(
146 absl::Span<const double> xpress_values, const T& map,
147 SparseDoubleVectorProto& result,
148 const SparseVectorFilterProto& filter) const;
149
150 const std::unique_ptr<Xpress> xpress_;
151
152 // Internal correspondence from variable proto IDs to Xpress-numbered
153 // variables.
155 // Internal correspondence from linear constraint proto IDs to
156 // Xpress-numbered linear constraint and extra information.
158 linear_constraints_map_;
159
160 int get_model_index(XpressVariableIndex index) const { return index; }
161 int get_model_index(const LinearConstraintData& index) const {
162 return index.constraint_index;
163 }
164 SolutionStatusProto getLpSolutionStatus() const;
165 SolutionStatusProto getDualSolutionStatus() const;
166 absl::StatusOr<InvertedBounds> ListInvertedBounds() const;
167 absl::Status SetXpressStartingBasis(const BasisProto& basis);
168 absl::Status SetLpIterLimits(const SolveParametersProto& parameters);
169
170 bool is_mip_ = false;
171 bool is_maximize_ = false;
172
173 struct LpStatus {
174 int primal_status = 0;
175 int dual_status = 0;
176 };
177 LpStatus xpress_lp_status_;
178 LPAlgorithmProto lp_algorithm_ = LP_ALGORITHM_UNSPECIFIED;
179
180 int xpress_mip_status_ = 0;
181};
182
183} // namespace operations_research::math_opt
184
185#endif // OR_TOOLS_MATH_OPT_SOLVERS_XPRESS_SOLVER_H_
std::function< void(const std::vector< std::string > &)> MessageCallback
std::function< absl::StatusOr< CallbackResultProto >( const CallbackDataProto &)> Callback
absl::StatusOr< SolveResultProto > Solve(const SolveParametersProto &parameters, const ModelSolveParametersProto &model_parameters, MessageCallback message_cb, const CallbackRegistrationProto &callback_registration, Callback cb, const SolveInterrupter *interrupter) override
Solves the optimization problem.
absl::StatusOr< bool > Update(const ModelUpdateProto &model_update) override
Updates the problem (not implemented yet)
absl::StatusOr< ComputeInfeasibleSubsystemResultProto > ComputeInfeasibleSubsystem(const SolveParametersProto &parameters, MessageCallback message_cb, const SolveInterrupter *interrupter) override
Computes the infeasible subsystem (not implemented yet)
static absl::StatusOr< std::unique_ptr< XpressSolver > > New(const ModelProto &input_model, const SolverInterface::InitArgs &init_args)
Creates the XPRESS solver and loads the model into it.
An object oriented wrapper for quadratic constraints in ModelStorage.
Definition gurobi_isv.cc:28
#define XPRS_PLUSINFINITY
Definition environment.h:92
#define XPRS_MINUSINFINITY
Definition environment.h:93