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