Google OR-Tools v9.11
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
solution.h
Go to the documentation of this file.
1// Copyright 2010-2024 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// IWYU pragma: private, include "ortools/math_opt/cpp/math_opt.h"
15// IWYU pragma: friend "ortools/math_opt/cpp/.*"
16
17#ifndef OR_TOOLS_MATH_OPT_CPP_SOLUTION_H_
18#define OR_TOOLS_MATH_OPT_CPP_SOLUTION_H_
19
20#include <optional>
21
22#include "absl/container/flat_hash_map.h"
23#include "absl/status/status.h"
24#include "absl/status/statusor.h"
27#include "ortools/math_opt/cpp/enums.h" // IWYU pragma: export
31#include "ortools/math_opt/result.pb.h" // IWYU pragma: export
32#include "ortools/math_opt/solution.pb.h"
34
35namespace operations_research {
36namespace math_opt {
37
38// Feasibility of a primal or dual solution as claimed by the solver.
39enum class SolutionStatus {
40 // Solver does not claim a feasibility status.
41 kUndetermined = SOLUTION_STATUS_UNDETERMINED,
42
43 // Solver claims the solution is feasible.
44 kFeasible = SOLUTION_STATUS_FEASIBLE,
45
46 // Solver claims the solution is infeasible.
47 kInfeasible = SOLUTION_STATUS_INFEASIBLE,
48};
49
50MATH_OPT_DEFINE_ENUM(SolutionStatus, SOLUTION_STATUS_UNSPECIFIED);
51
52// A solution to an optimization problem.
53//
54// E.g. consider a simple linear program:
55// min c * x
56// s.t. A * x >= b
57// x >= 0.
58// A primal solution is assignment values to x. It is feasible if it satisfies
59// A * x >= b and x >= 0 from above. In the class PrimalSolution,
60// variable_values is x and objective_value is c * x.
61//
62// For the general case of a MathOpt optimization model.
64 // Returns the PrimalSolution equivalent of primal_solution_proto.
65 //
66 // Returns an error when:
67 // * VariableValuesFromProto(primal_solution_proto.variable_values) fails.
68 // * the feasibility_status is not specified.
69 static absl::StatusOr<PrimalSolution> FromProto(
70 const ModelStorage* model,
71 const PrimalSolutionProto& primal_solution_proto);
72
73 // Returns the proto equivalent of this.
74 PrimalSolutionProto Proto() const;
75
76 // Returns the value for the given `objective`.
77 //
78 // Will CHECK-fail if `objective` has been deleted, or if it is from the is
79 // from the wrong model (however, if the solution has no variables, this CHECK
80 // will not occur due to an implementation detail of the struct).
81 double get_objective_value(Objective objective) const;
82
84 double objective_value = 0.0;
85 absl::flat_hash_map<Objective, double> auxiliary_objective_values;
86
88};
89
90// A direction of unbounded improvement to an optimization problem;
91// equivalently, a certificate of infeasibility for the dual of the
92// optimization problem.
93//
94// E.g. consider a simple linear program:
95// min c * x
96// s.t. A * x >= b
97// x >= 0
98// A primal ray is an x that satisfies:
99// c * x < 0
100// A * x >= 0
101// x >= 0
102// Observe that given a feasible solution, any positive multiple of the primal
103// ray plus that solution is still feasible, and gives a better objective
104// value. A primal ray also proves the dual optimization problem infeasible.
105//
106// In the class PrimalRay, variable_values is this x.
107//
108// For the general case of a MathOpt optimization model.
109struct PrimalRay {
110 // Returns the PrimalRay equivalent of primal_ray_proto.
111 //
112 // Returns an error when
113 // VariableValuesFromProto(primal_ray_proto.variable_values) fails.
114 static absl::StatusOr<PrimalRay> FromProto(
115 const ModelStorage* model, const PrimalRayProto& primal_ray_proto);
116
117 // Returns the proto equivalent of this.
118 PrimalRayProto Proto() const;
119
121};
122
123// A solution to the dual of an optimization problem.
124//
125// E.g. consider the primal dual pair linear program pair:
126// (Primal) (Dual)
127// min c * x max b * y
128// s.t. A * x >= b s.t. y * A + r = c
129// x >= 0 y, r >= 0.
130// The dual solution is the pair (y, r). It is feasible if it satisfies the
131// constraints from (Dual) above.
132//
133// Below, y is dual_values, r is reduced_costs, and b * y is objective value.
135 // Returns the DualSolution equivalent of dual_solution_proto.
136 //
137 // Returns an error when any of:
138 // * VariableValuesFromProto(dual_solution_proto.reduced_costs) fails.
139 // * LinearConstraintValuesFromProto(dual_solution_proto.dual_values) fails.
140 // * dual_solution_proto.feasibility_status is not specified.
141 static absl::StatusOr<DualSolution> FromProto(
142 const ModelStorage* model, const DualSolutionProto& dual_solution_proto);
143
144 // Returns the proto equivalent of this.
145 DualSolutionProto Proto() const;
146
148
149 // Note: Some solvers only return quadratic constraint duals when a
150 // solver-specific parameter is set
151 // (see go/mathopt-qcqp-dual#solver-specific).
152 absl::flat_hash_map<QuadraticConstraint, double> quadratic_dual_values;
154 std::optional<double> objective_value;
155
157};
158
159// A direction of unbounded improvement to the dual of an optimization
160// problem; equivalently, a certificate of primal infeasibility.
161//
162// E.g. consider the primal dual linear program pair:
163// (Primal) (Dual)
164// min c * x max b * y
165// s.t. A * x >= b s.t. y * A + r = c
166// x >= 0 y, r >= 0.
167// The dual ray is the pair (y, r) satisfying:
168// b * y > 0
169// y * A + r = 0
170// y, r >= 0
171// Observe that adding a positive multiple of (y, r) to dual feasible solution
172// maintains dual feasibility and improves the objective (proving the dual is
173// unbounded). The dual ray also proves the primal problem is infeasible.
174//
175// In the class DualRay, y is dual_values and r is reduced_costs.
176struct DualRay {
177 // Returns the DualRay equivalent of dual_ray_proto.
178 //
179 // Returns an error when either of:
180 // * VariableValuesFromProto(dual_ray_proto.reduced_costs) fails.
181 // * LinearConstraintValuesFromProto(dual_ray_proto.dual_values) fails.
182 static absl::StatusOr<DualRay> FromProto(const ModelStorage* model,
183 const DualRayProto& dual_ray_proto);
184
185 // Returns the proto equivalent of this.
186 DualRayProto Proto() const;
187
190};
191
192// A combinatorial characterization for a solution to a linear program.
193//
194// The simplex method for solving linear programs always returns a "basic
195// feasible solution" which can be described combinatorially as a Basis. A
196// basis assigns a BasisStatus for every variable and linear constraint.
197//
198// E.g. consider a standard form LP:
199// min c * x
200// s.t. A * x = b
201// x >= 0
202// that has more variables than constraints and with full row rank A.
203//
204// Let n be the number of variables and m the number of linear constraints. A
205// valid basis for this problem can be constructed as follows:
206// * All constraints will have basis status FIXED.
207// * Pick m variables such that the columns of A are linearly independent and
208// assign the status BASIC.
209// * Assign the status AT_LOWER for the remaining n - m variables.
210//
211// The basic solution for this basis is the unique solution of A * x = b that
212// has all variables with status AT_LOWER fixed to their lower bounds (all
213// zero). The resulting solution is called a basic feasible solution if it
214// also satisfies x >= 0.
215struct Basis {
216 // Returns the equivalent Basis object for basis_proto.
217 //
218 // Returns an error if:
219 // * VariableBasisFromProto(basis_proto.variable_status) fails.
220 // * LinearConstraintBasisFromProto(basis_proto.constraint_status) fails.
221 static absl::StatusOr<Basis> FromProto(const ModelStorage* model,
222 const BasisProto& basis_proto);
223
224 // Returns a failure if the referenced variables don't belong to the input
225 // expected_storage (which must not be nullptr).
226 absl::Status CheckModelStorage(const ModelStorage* expected_storage) const;
227
228 // Returns the proto equivalent of this object.
229 //
230 // The caller should use CheckModelStorage() as this function does not check
231 // internal consistency of the referenced variables and constraints.
232 BasisProto Proto() const;
233
236
237 // This is an advanced feature used by MathOpt to characterize feasibility of
238 // suboptimal LP solutions (optimal solutions will always have status
239 // SolutionStatus::kFeasible).
240 //
241 // For single-sided LPs it should be equal to the feasibility status of the
242 // associated dual solution. For two-sided LPs it may be different in some
243 // edge cases (e.g. incomplete solves with primal simplex).
244 //
245 // If you are providing a starting basis via
246 // `ModelSolveParameters.initial_basis`, this value is ignored. It is only
247 // relevant for the basis returned by `Solution.basis`, and it is is always
248 // populated in a Basis returned by a call to Solve().
249 std::optional<SolutionStatus> basic_dual_feasibility;
250};
251
252// What is included in a solution depends on the kind of problem and solver.
253// The current common patterns are
254// 1. MIP solvers return only a primal solution.
255// 2. Simplex LP solvers often return a basis and the primal and dual
256// solutions associated to this basis.
257// 3. Other continuous solvers often return a primal and dual solution that
258// are connected in a solver-dependent form.
259struct Solution {
260 // Returns the Solution equivalent of solution_proto.
261 //
262 // Returns an error if FromProto() fails on any field that is not std::nullopt
263 // (see the static FromProto() functions for each field type for details).
264 static absl::StatusOr<Solution> FromProto(
265 const ModelStorage* model, const SolutionProto& solution_proto);
266
267 // Returns the proto equivalent of this.
268 SolutionProto Proto() const;
269
270 std::optional<PrimalSolution> primal_solution;
271 std::optional<DualSolution> dual_solution;
272 std::optional<Basis> basis;
273};
274
275} // namespace math_opt
276} // namespace operations_research
277
278#endif // OR_TOOLS_MATH_OPT_CPP_SOLUTION_H_
#define MATH_OPT_DEFINE_ENUM(CppEnum, proto_unspecified_value)
Definition enums.h:325
GRBmodel * model
absl::flat_hash_map< Variable, V > VariableMap
absl::flat_hash_map< LinearConstraint, V > LinearConstraintMap
SolutionStatus
Feasibility of a primal or dual solution as claimed by the solver.
Definition solution.h:39
@ kUndetermined
Solver does not claim a feasibility status.
@ kFeasible
Solver claims the solution is feasible.
@ kInfeasible
Solver claims the solution is infeasible.
In SWIG mode, we don't want anything besides these top-level includes.
absl::Status CheckModelStorage(const ModelStorage *expected_storage) const
Definition solution.cc:199
LinearConstraintMap< BasisStatus > constraint_status
Definition solution.h:234
static absl::StatusOr< Basis > FromProto(const ModelStorage *model, const BasisProto &basis_proto)
Definition solution.cc:183
VariableMap< BasisStatus > variable_status
Definition solution.h:235
std::optional< SolutionStatus > basic_dual_feasibility
Definition solution.h:249
DualRayProto Proto() const
Returns the proto equivalent of this.
Definition solution.cc:176
static absl::StatusOr< DualRay > FromProto(const ModelStorage *model, const DualRayProto &dual_ray_proto)
Definition solution.cc:162
LinearConstraintMap< double > dual_values
Definition solution.h:188
VariableMap< double > reduced_costs
Definition solution.h:189
static absl::StatusOr< DualSolution > FromProto(const ModelStorage *model, const DualSolutionProto &dual_solution_proto)
Definition solution.cc:122
LinearConstraintMap< double > dual_values
Definition solution.h:147
absl::flat_hash_map< QuadraticConstraint, double > quadratic_dual_values
Definition solution.h:152
std::optional< double > objective_value
Definition solution.h:154
DualSolutionProto Proto() const
Returns the proto equivalent of this.
Definition solution.cc:149
PrimalRayProto Proto() const
Returns the proto equivalent of this.
Definition solution.cc:116
VariableMap< double > variable_values
Definition solution.h:120
static absl::StatusOr< PrimalRay > FromProto(const ModelStorage *model, const PrimalRayProto &primal_ray_proto)
Definition solution.cc:106
absl::flat_hash_map< Objective, double > auxiliary_objective_values
Definition solution.h:85
static absl::StatusOr< PrimalSolution > FromProto(const ModelStorage *model, const PrimalSolutionProto &primal_solution_proto)
Definition solution.cc:59
PrimalSolutionProto Proto() const
Returns the proto equivalent of this.
Definition solution.cc:82
double get_objective_value(Objective objective) const
Definition solution.cc:92
std::optional< PrimalSolution > primal_solution
Definition solution.h:270
std::optional< DualSolution > dual_solution
Definition solution.h:271
SolutionProto Proto() const
Returns the proto equivalent of this.
Definition solution.cc:248
static absl::StatusOr< Solution > FromProto(const ModelStorage *model, const SolutionProto &solution_proto)
Definition solution.cc:225