Google OR-Tools v9.11
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
matchers.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// Matchers for MathOpt types, specifically SolveResult and nested fields.
15//
16// The matchers defined here are useful for writing unit tests checking that the
17// result of Solve(), absl::StatusOr<SolveResult>, meets expectations. We give
18// some examples below. All code is assumed with the following setup:
19//
20// namespace operations_research::math_opt {
21// using ::testing::status::IsOkAndHolds;
22//
23// Model model;
24// const Variable x = model.AddContinuousVariable(0.0, 1.0);
25// const Variable y = model.AddContinuousVariable(0.0, 1.0);
26// const LinearConstraint c = model.AddLinearConstraint(x + y <= 1);
27// model.Maximize(2*x + y);
28//
29// Example 1.a: result is OK, optimal, and objective value approximately 42.
30// EXPECT_THAT(Solve(model, SolverType::kGlop), IsOkAndHolds(IsOptimal(42)));
31//
32// Example 1.b: equivalent to 1.a.
33// ASSERT_OK_AND_ASSIGN(const SolveResult result,
34// Solve(model, SolverType::kGlop));
35// EXPECT_THAT(result, IsOptimal(42));
36//
37// Example 2: result is OK, optimal, and best solution is x=1, y=0.
38// ASSERT_OK_AND_ASSIGN(const SolveResult result,
39// Solve(model, SolverType::kGlop));
40// ASSERT_THAT(result, IsOptimal());
41// EXPECT_THAT(result.variable_value(), IsNear({{x, 1}, {y, 0}});
42// Note: the second ASSERT ensures that if the solution is not optimal, then
43// result.variable_value() will not run (the function will crash if the solver
44// didn't find a solution). Further, MathOpt guarantees there is a solution
45// when the termination reason is optimal.
46//
47// Example 3: result is OK, check the solution without specifying termination.
48// ASSERT_OK_AND_ASSIGN(const SolveResult result,
49// Solve(model, SolverType::kGlop));
50// EXPECT_THAT(result, HasBestSolution({{x, 1}, {y, 0}}));
51//
52// Example 4: multiple possible termination reason, primal ray optional:
53// ASSERT_OK_AND_ASSIGN(const SolveResult result,
54// Solve(model, SolverType::kGlop));
55// ASSERT_THAT(result, TerminatesWithOneOf(
56// TerminationReason::kUnbounded,
57// TerminationReason::kInfeasibleOrUnbounded));
58// if(!result.primal_rays.empty()) {
59// EXPECT_THAT(result.primal_rays[0], PrimalRayIsNear({{x, 1,}, {y, 0}}));
60// }
61//
62//
63// Tips on writing good tests:
64// * Use ASSERT_OK_AND_ASSIGN(const SolveResult result, Solve(...)) to ensure
65// the test terminates immediately if Solve() does not return OK.
66// * If you ASSERT_THAT(result, IsOptimal()), you can assume that you have a
67// feasible primal solution afterwards. Otherwise, make no assumptions on
68// the contents of result (e.g. do not assume result contains a primal ray
69// just because the termination reason was UNBOUNDED).
70// * For problems that are infeasible, the termination reasons INFEASIBLE and
71// DUAL_INFEASIBLE are both possible. Likewise, for unbounded problems, you
72// can get both UNBOUNDED and DUAL_INFEASIBLE. See TerminatesWithOneOf()
73// below to make assertions in this case. Note also that some solvers have
74// solver specific parameters to ensure that DUAL_INFEASIBLE will not be
75// returned (e.g. for Gurobi, use DualReductions or InfUnbdInfo).
76// * The objective value and variable values should always be compared up to
77// a tolerance, even if your decision variables are integer. The matchers
78// defined have a configurable tolerance with default value 1e-5.
79// * Primal and dual rays are unique only up to a constant scaling. The
80// matchers provided rescale both expected and actual before comparing.
81// * Take care on problems with multiple optimal solutions. Do not rely on a
82// particular solution being returned in your test, as the test will break
83// when we upgrade the solver.
84//
85// This file also defines functions to let gunit print various MathOpt types.
86//
87// To see the error messages these matchers generate, run
88// blaze test experimental/users/rander/math_opt:matchers_error_messages
89// which is a fork of matchers_test.cc where the assertions are all negated
90// (note that every test should fail).
91#ifndef OR_TOOLS_MATH_OPT_CPP_MATCHERS_H_
92#define OR_TOOLS_MATH_OPT_CPP_MATCHERS_H_
93
94#include <optional>
95#include <ostream>
96#include <string>
97#include <type_traits>
98#include <vector>
99
100#include "absl/container/flat_hash_map.h"
101#include "absl/status/statusor.h"
102#include "gtest/gtest.h"
103#include "ortools/base/gmock.h"
109
110namespace operations_research {
111namespace math_opt {
112
113constexpr double kMatcherDefaultTolerance = 1e-5;
114
116// Matchers for absl::flat_hash_map
118
119// Checks that the maps have identical keys and values within tolerance. This
120// factory will CHECK-fail if expected contains any NaN values.
121testing::Matcher<VariableMap<double>> IsNear(
122 VariableMap<double> expected, double tolerance = kMatcherDefaultTolerance);
123
124// Checks that the keys of actual are a subset of the keys of expected, and that
125// for all shared keys, the values are within tolerance. This factory will
126// CHECK-fail if expected contains any NaN values, and any NaN values in the
127// expression compared against will result in the matcher failing.
128testing::Matcher<VariableMap<double>> IsNearlySubsetOf(
129 VariableMap<double> expected, double tolerance = kMatcherDefaultTolerance);
130
131// Checks that the maps have identical keys and values within tolerance. This
132// factory will CHECK-fail if expected contains any NaN values, and any NaN
133// values in the expression compared against will result in the matcher failing.
134testing::Matcher<LinearConstraintMap<double>> IsNear(
136 double tolerance = kMatcherDefaultTolerance);
137
138// Checks that the keys of actual are a subset of the keys of expected, and that
139// for all shared keys, the values are within tolerance. This factory will
140// CHECK-fail if expected contains any NaN values, and any NaN values in the
141// expression compared against will result in the matcher failing.
142testing::Matcher<LinearConstraintMap<double>> IsNearlySubsetOf(
144 double tolerance = kMatcherDefaultTolerance);
145
146// Checks that the maps have identical keys and values within tolerance. This
147// factory will CHECK-fail if expected contains any NaN values.
148testing::Matcher<absl::flat_hash_map<QuadraticConstraint, double>> IsNear(
149 absl::flat_hash_map<QuadraticConstraint, double> expected,
150 double tolerance = kMatcherDefaultTolerance);
151
152// Checks that the keys of actual are a subset of the keys of expected, and that
153// for all shared keys, the values are within tolerance. This factory will
154// CHECK-fail if expected contains any NaN values, and any NaN values in the
155// expression compared against will result in the matcher failing.
156testing::Matcher<absl::flat_hash_map<QuadraticConstraint, double>>
157IsNearlySubsetOf(absl::flat_hash_map<QuadraticConstraint, double> expected,
158 double tolerance = kMatcherDefaultTolerance);
159
161// Matchers for various Variable expressions (e.g. LinearExpression)
163
164// Checks that the expressions are structurally identical (i.e., internal maps
165// have the same keys and storage, coefficients are exactly equal). This factory
166// will CHECK-fail if expected contains any NaN values, and any NaN values in
167// the expression compared against will result in the matcher failing.
168testing::Matcher<LinearExpression> IsIdentical(LinearExpression expected);
169
170testing::Matcher<LinearExpression> LinearExpressionIsNear(
171 LinearExpression expected, double tolerance = kMatcherDefaultTolerance);
172
173// Checks that the bounded linear expression is equivalent to expected, where
174// equivalence is maintained by:
175// * adding alpha to the lower bound, the linear expression and upper bound
176// * multiplying the lower bound, linear expression, by -1 (and flipping the
177// inequalities).
178// Note that, as implemented, we do not allow for arbitrary multiplicative
179// rescalings (this makes additive tolerance complicated).
180testing::Matcher<BoundedLinearExpression> IsNearlyEquivalent(
181 const BoundedLinearExpression& expected,
182 double tolerance = kMatcherDefaultTolerance);
183
184// Checks that the expressions are structurally identical (i.e., internal maps
185// have the same keys and storage, coefficients are exactly equal). This factory
186// will CHECK-fail if expected contains any NaN values, and any NaN values in
187// the expression compared against will result in the matcher failing.
188testing::Matcher<QuadraticExpression> IsIdentical(QuadraticExpression expected);
189
191// Matchers for solutions
193
194// Options for IsNear(Solution).
197 bool check_primal = true;
198 bool check_dual = true;
199 bool check_basis = true;
200 // If false, only match on primal/dual solutions that are feasible. If true,
201 // match on solutions that are either feasible or undetermined.
202 bool allow_undetermined = false;
205testing::Matcher<Solution> IsNear(Solution expected,
206 SolutionMatcherOptions options = {});
207
208// Checks variables match and variable/objective values are within tolerance and
209// feasibility statuses are identical.
210testing::Matcher<PrimalSolution> IsNear(
211 PrimalSolution expected, double tolerance = kMatcherDefaultTolerance,
212 bool allow_undetermined = false);
213
214// Checks dual variables, reduced costs and objective are within tolerance and
215// feasibility statuses are identical.
216testing::Matcher<DualSolution> IsNear(
217 DualSolution expected, double tolerance = kMatcherDefaultTolerance,
218 bool allow_undetermined = false);
219
220testing::Matcher<Basis> BasisIs(const Basis& expected);
221
223// Matchers for a Rays
225
226// Checks variables match and that after rescaling, variable values are within
227// tolerance.
228testing::Matcher<PrimalRay> IsNear(PrimalRay expected,
229 double tolerance = kMatcherDefaultTolerance);
230
231// Checks variables match and that after rescaling, variable values are within
232// tolerance.
233testing::Matcher<PrimalRay> PrimalRayIsNear(
234 VariableMap<double> expected_var_values,
235 double tolerance = kMatcherDefaultTolerance);
236
237// Checks that dual variables and reduced costs are defined for the same
238// set of Variables/LinearConstraints, and that their rescaled values are within
239// tolerance.
240testing::Matcher<DualRay> IsNear(DualRay expected,
241 double tolerance = kMatcherDefaultTolerance);
242
244// Matchers for a Termination
246
247testing::Matcher<Termination> ReasonIs(TerminationReason reason);
248
249// Checks that the termination reason is optimal, but does not check the other
250// fields of Termination are consistent with optimality.
251testing::Matcher<Termination> ReasonIsOptimal();
252
253// Checks that the termination reason is optimal and that problem status is
254// consistent with optimality (i.e. status is primal and dual feasible).
255testing::Matcher<Termination> TerminationIsOptimal();
256
257// Checks that the termination reason is optimal, that the objective bounds
258// match the provided ones and that problem status is consistent with
259// optimality (i.e. status is primal and dual feasible).
260//
261// If dual_objective_value is not set, use the primal_objective_value.
262testing::Matcher<Termination> TerminationIsOptimal(
263 double primal_objective_value,
264 std::optional<double> dual_objective_value = std::nullopt,
265 double tolerance = kMatcherDefaultTolerance);
266
267// Checks the following:
268// * The reason is kFeasible or kNoSolutionFound.
269// * The limit is the expected one.
270// * If the optional `detail_matcher` is provided, it matches the `detail`.
271//
272// See TerminatesWithLimit() for a similar matcher for SolveResult.
273//
274// TODO: b/343234961 - Maybe change the name and sync the signatures/features.
275testing::Matcher<Termination> LimitIs(
276 Limit limit, testing::Matcher<std::string> detail_matcher = testing::_);
277
278testing::Matcher<Termination> TerminationIsIgnoreDetail(
279 const Termination& expected);
280
281testing::Matcher<ObjectiveBounds> ObjectiveBoundsNear(
282 const ObjectiveBounds& expected,
283 double tolerance = kMatcherDefaultTolerance);
284
285testing::Matcher<ProblemStatus> ProblemStatusIs(const ProblemStatus& expected);
286
288// Matchers for a SolveResult
290
291// Checks the following:
292// * The termination reason is optimal.
293// * If expected_primal_objective contains a value, there is at least one
294// primal feasible solution and that solution has an objective value within
295// tolerance of expected_objective. However, primal and dual bounds are not
296// checked.
297// TODO(b/309658404): Note the bounds should be at least finite once we validate
298// this.
299testing::Matcher<SolveResult> IsOptimal(
300 std::optional<double> expected_primal_objective = std::nullopt,
301 double tolerance = kMatcherDefaultTolerance);
302
303testing::Matcher<SolveResult> IsOptimalWithSolution(
304 double expected_objective, VariableMap<double> expected_variable_values,
305 double tolerance = kMatcherDefaultTolerance);
306
307testing::Matcher<SolveResult> IsOptimalWithDualSolution(
308 double expected_objective, LinearConstraintMap<double> expected_dual_values,
309 VariableMap<double> expected_reduced_costs,
310 double tolerance = kMatcherDefaultTolerance);
311
312testing::Matcher<SolveResult> IsOptimalWithDualSolution(
313 double expected_objective, LinearConstraintMap<double> expected_dual_values,
314 absl::flat_hash_map<QuadraticConstraint, double>
315 expected_quadratic_dual_values,
316 VariableMap<double> expected_reduced_costs,
317 double tolerance = kMatcherDefaultTolerance);
318
319// Checks the following:
320// * The result has the expected termination reason.
321testing::Matcher<SolveResult> TerminatesWith(TerminationReason expected);
322
323// Checks that the result has one of the allowed termination reasons.
324testing::Matcher<SolveResult> TerminatesWithOneOf(
325 const std::vector<TerminationReason>& allowed);
326
327// Checks the following:
328// * The result has termination reason kFeasible or kNoSolutionFound.
329// * The limit is expected, or is kUndetermined if allow_limit_undetermined.
330//
331// See LimitIs() for a matcher for Termination only.
332testing::Matcher<SolveResult> TerminatesWithLimit(
333 Limit expected, bool allow_limit_undetermined = false);
334
335// Checks the following:
336// * The result has termination reason kFeasible.
337// * The limit is expected, or is kUndetermined if allow_limit_undetermined.
338testing::Matcher<SolveResult> TerminatesWithReasonFeasible(
339 Limit expected, bool allow_limit_undetermined = false);
340
341// Checks the following:
342// * The result has termination reason kNoSolutionFound.
343// * The limit is expected, or is kUndetermined if allow_limit_undetermined.
344testing::Matcher<SolveResult> TerminatesWithReasonNoSolutionFound(
345 Limit expected, bool allow_limit_undetermined = false);
346
347// SolveResult has a primal solution matching expected within tolerance.
348testing::Matcher<SolveResult> HasSolution(
349 PrimalSolution expected, double tolerance = kMatcherDefaultTolerance);
350
351// SolveResult has a dual solution matching expected within
352// tolerance.
353testing::Matcher<SolveResult> HasDualSolution(
354 DualSolution expected, double tolerance = kMatcherDefaultTolerance);
355
356// Actual SolveResult contains a primal ray that matches expected within
357// tolerance.
358testing::Matcher<SolveResult> HasPrimalRay(
359 PrimalRay expected, double tolerance = kMatcherDefaultTolerance);
360
361// Actual SolveResult contains a primal ray with variable values equivalent to
362// (under L_inf scaling) expected_vars up to tolerance.
363testing::Matcher<SolveResult> HasPrimalRay(
364 VariableMap<double> expected_vars,
365 double tolerance = kMatcherDefaultTolerance);
366
367// Actual SolveResult contains a dual ray that matches expected within
368// tolerance.
369testing::Matcher<SolveResult> HasDualRay(
370 DualRay expected, double tolerance = kMatcherDefaultTolerance);
371
372// Configures SolveResult matcher IsConsistentWith() below.
374 double tolerance = 1e-5;
375 bool first_solution_only = true;
376 bool check_dual = true;
377 bool check_rays = true;
378
379 // If the expected result has termination reason kInfeasible, kUnbounded, or
380 // kDualInfeasasible, the primal solution, dual solution, and basis are
381 // ignored unless check_solutions_if_inf_or_unbounded is true.
382 //
383 // TODO(b/201099290): this is perhaps not a good default. Gurobi as
384 // implemented is returning primal solutions for both unbounded and
385 // infeasible problems. We need to add unit tests that inspect this value
386 // and turn them on one solver at a time with a new parameter on
387 // SimpleLpTestParameters.
389 bool check_basis = false;
390
391 // In linear programming, the following outcomes are all possible
392 //
393 // Primal LP | Dual LP | Possible MathOpt Termination Reasons
394 // -----------------------------------------------------------------
395 // 1. Infeasible | Unbounded | kInfeasible
396 // 2. Optimal | Optimal | kOptimal
397 // 3. Unbounded | Infeasible | kUnbounded, kInfeasibleOrUnbounded
398 // 4. Infeasible | Infeasible | kInfeasible, kInfeasibleOrUnbounded
399 //
400 // (Above "Optimal" means that an optimal solution exists. This is a statement
401 // about the existence of optimal solutions and certificates of
402 // infeasibility/unboundedness, not about the outcome of applying any
403 // particular algorithm.)
404 //
405 // When writing your unit test, you can typically tell which case of 1-4 you
406 // are in, but in cases 3-4 you do not know which termination reason will be
407 // returned. In some situations, it may not be clear if you are in case 1 or
408 // case 4 as well.
409 //
410 // When inf_or_unb_soft_match=false, the matcher must exactly specify the
411 // status returned by the solver. For cases 3-4, this is implementation
412 // dependent and we do not recommend this. When
413 // inf_or_unb_soft_match=true:
414 // * kInfeasible can also match kInfeasibleOrUnbounded
415 // * kUnbounded can also match kInfeasibleOrUnbounded
416 // * kInfeasibleOrUnbounded can also match kInfeasible and kUnbounded.
417 // For case 2, inf_or_unb_soft_match has no effect.
418 //
419 // To build the strongest possible matcher (accepting the minimal set of
420 // termination reasons):
421 // * If you know you are in case 1, se inf_or_unb_soft_match=false
422 // (soft_match=true over-matches)
423 // * For case 3, use inf_or_unb_soft_match=false and
424 // termination_reason=kUnbounded (kInfeasibleOrUnbounded over-matches).
425 // * For case 4 (or if you are unsure of case 1 vs case 4), use
426 // inf_or_unb_soft_match=true and
427 // termination_reason=kInfeasible (kInfeasibleOrUnbounded over-matches).
428 // * If you cannot tell if you are in case 3 or case 4, use
429 // inf_or_unb_soft_match=true and termination reason
430 // kInfeasibleOrUnbounded.
431 //
432 // If the above is too complicated, always setting
433 // inf_or_unb_soft_match=true and using any of the expected MathOpt
434 // termination reasons from the above table will give a matcher that is
435 // slightly too lenient.
436 bool inf_or_unb_soft_match = true;
437};
438
439// Tests that two SolveResults are equivalent. Basic use:
440//
441// SolveResult expected;
442// // Fill in expected...
443// ASSERT_OK_AND_ASSIGN(SolveResult actual, Solve(model, solver_type));
444// EXPECT_THAT(actual, IsConsistentWith(expected));
445//
446// Equivalence is defined as follows:
447// * The termination reasons are the same.
448// - For infeasible and unbounded problems, see
449// options.inf_or_unb_soft_match.
450// * The solve stats are ignored.
451// * For both primal and dual solutions, either expected and actual are
452// both empty, or their first entries satisfy IsNear() at options.tolerance.
453// - Not checked if options.check_solutions_if_inf_or_unbounded and the
454// problem is infeasible or unbounded (default).
455// - If options.first_solution_only is false, check the entire list of
456// solutions matches in the same order.
457// - Dual solution is not checked if options.check_dual=false
458// * For both the primal and dual rays, either expected and actual are both
459// empty, or any ray in expected IsNear() any ray in actual (which is up
460// to a rescaling) at options.tolerance.
461// - Not checked if options.check_rays=false
462// - If options.first_solution_only is false, check the entire list of
463// solutions matches in the same order.
464// * The basis is not checked by default. If enabled, checked with BasisIs().
465// - Enable with options.check_basis
466//
467// This function is symmetric in that:
468// EXPECT_THAT(actual, IsConsistentWith(expected));
469// EXPECT_THAT(expected, IsConsistentWith(actual));
470// agree on matching, they only differ in strings produced. Per gmock
471// conventions, prefer the former.
472//
473// For problems with either primal or dual infeasibility, see
474// SolveResultMatcherOptions::inf_or_unb_soft_match for guidance on how to
475// best set the termination reason and inf_or_unb_soft_match.
476testing::Matcher<SolveResult> IsConsistentWith(
477 const SolveResult& expected, const SolveResultMatcherOptions& options = {});
478
480// Mocking
482
483using MockSolveFunction = testing::MockFunction<
484 absl::StatusOr<operations_research::math_opt::SolveResult>(
489
491// Matchers for a ComputeInfeasibleSubsystemResult
493
494// Checks that ComputeInfeasibleSubsystemResult.feasibility is kFeasible,
495// that the .infeasible_subsystem is empty and that is_minimal is false.
496testing::Matcher<ComputeInfeasibleSubsystemResult> IsFeasible();
497
498// Checks that ComputeInfeasibleSubsystemResult.feasibility is kUndetermined,
499// that the .infeasible_subsystem is empty and that is_minimal is false..
500testing::Matcher<ComputeInfeasibleSubsystemResult> IsUndetermined();
501
502// Checks that ComputeInfeasibleSubsystemResult.feasibility is kInfeasible and
503// that .infeasible_subsystem is not empty. If expected_is_minimal is set, test
504// that .is_minimal has the same value. If expected_infeasible_subsystem is set,
505// test that the resulting ModelSubset::Proto() are EqualsProto().
506testing::Matcher<ComputeInfeasibleSubsystemResult> IsInfeasible(
507 std::optional<bool> expected_is_minimal = std::nullopt,
508 std::optional<ModelSubset> expected_infeasible_subsystem = std::nullopt);
509
511// Rarely used
513
514// Actual UpdateResult.did_update is true.
515testing::Matcher<UpdateResult> DidUpdate();
516
518// Implementation details
520
521void PrintTo(const PrimalSolution& primal_solution, std::ostream* os);
522void PrintTo(const DualSolution& dual_solution, std::ostream* os);
523void PrintTo(const PrimalRay& primal_ray, std::ostream* os);
524void PrintTo(const DualRay& dual_ray, std::ostream* os);
525void PrintTo(const Basis& basis, std::ostream* os);
526void PrintTo(const Solution& solution, std::ostream* os);
527void PrintTo(const SolveResult& result, std::ostream* os);
528
529// We do not want to rely on ::testing::internal::ContainerPrinter because we
530// want to sort the keys.
531template <typename K, typename V, typename = std::enable_if_t<is_key_type_v<K>>>
532void PrintTo(const absl::flat_hash_map<K, V>& id_map, std::ostream* const os) {
533 constexpr int kMaxPrint = 10;
534 int num_added = 0;
535 *os << "{";
536 for (const K k : SortedKeys(id_map)) {
537 if (num_added > 0) {
538 *os << ", ";
539 }
540 if (num_added >= kMaxPrint) {
541 *os << "...(size=" << id_map.size() << ")";
542 break;
543 }
544 *os << "{" << k << ", " << ::testing::PrintToString(id_map.at(k)) << "}";
545 ++num_added;
546 }
547 *os << "}";
548}
549
550} // namespace math_opt
551} // namespace operations_research
552
553#endif // OR_TOOLS_MATH_OPT_CPP_MATCHERS_H_
double solution
Matcher< SolveResult > IsOptimalWithSolution(const double expected_objective, const VariableMap< double > expected_variable_values, const double tolerance)
Definition matchers.cc:777
Matcher< SolveResult > HasPrimalRay(PrimalRay expected, const double tolerance)
Definition matchers.cc:839
Matcher< Termination > TerminationIsOptimal()
Definition matchers.cc:736
absl::flat_hash_map< Variable, V > VariableMap
Matcher< Termination > ReasonIsOptimal()
Definition matchers.cc:722
Matcher< ObjectiveBounds > ObjectiveBoundsNear(const ObjectiveBounds &expected, const double tolerance)
Definition matchers.cc:607
SolverType
The solvers supported by MathOpt.
Definition parameters.h:42
TerminationReason
The reason a call to Solve() terminates.
constexpr double kMatcherDefaultTolerance
Definition matchers.h:113
absl::flat_hash_map< LinearConstraint, V > LinearConstraintMap
Matcher< Termination > ReasonIs(TerminationReason reason)
Definition matchers.cc:718
Matcher< SolveResult > TerminatesWithOneOf(const std::vector< TerminationReason > &allowed)
Checks that the result has one of the allowed termination reasons.
Definition matchers.cc:615
Matcher< ProblemStatus > ProblemStatusIs(const ProblemStatus &expected)
Definition matchers.cc:726
testing::MockFunction< absl::StatusOr< operations_research::math_opt::SolveResult >( const operations_research::math_opt::Model &, operations_research::math_opt::SolverType, const operations_research::math_opt::SolveArguments &, const operations_research::math_opt::SolverInitArguments &)> MockSolveFunction
Definition matchers.h:498
testing::Matcher< ComputeInfeasibleSubsystemResult > IsInfeasible(const std::optional< bool > expected_is_minimal, const std::optional< ModelSubset > expected_infeasible_subsystem)
Definition matchers.cc:994
Matcher< Termination > LimitIs(math_opt::Limit limit, const Matcher< std::string > detail_matcher)
Definition matchers.cc:709
testing::Matcher< BoundedLinearExpression > IsNearlyEquivalent(const BoundedLinearExpression &expected, const double tolerance)
Definition matchers.cc:310
Matcher< SolveResult > IsConsistentWith(const SolveResult &expected, const SolveResultMatcherOptions &options)
Definition matchers.cc:942
Matcher< Termination > TerminationIsIgnoreDetail(const Termination &expected)
Definition matchers.cc:757
Matcher< SolveResult > HasSolution(PrimalSolution expected, const double tolerance)
SolveResult has a primal solution matching expected within tolerance.
Definition matchers.cc:823
Matcher< SolveResult > HasDualRay(DualRay expected, const double tolerance)
Definition matchers.cc:851
testing::Matcher< SolveResult > TerminatesWithReasonFeasible(const Limit expected, const bool allow_limit_undetermined)
Definition matchers.cc:657
Matcher< SolveResult > TerminatesWith(const TerminationReason expected)
Definition matchers.cc:621
testing::Matcher< SolveResult > TerminatesWithLimit(const Limit expected, const bool allow_limit_undetermined)
Definition matchers.cc:648
Matcher< PrimalRay > PrimalRayIsNear(VariableMap< double > expected_var_values, const double tolerance)
Definition matchers.cc:538
testing::Matcher< LinearExpression > IsIdentical(LinearExpression expected)
Definition matchers.cc:278
Matcher< VariableMap< double > > IsNear(VariableMap< double > expected, const double tolerance)
Definition matchers.cc:221
Matcher< VariableMap< double > > IsNearlySubsetOf(VariableMap< double > expected, double tolerance)
Definition matchers.cc:215
Matcher< UpdateResult > DidUpdate()
Actual UpdateResult.did_update is true.
Definition matchers.cc:1027
void PrintTo(const PrimalSolution &primal_solution, std::ostream *const os)
Definition matchers.cc:88
testing::Matcher< LinearExpression > LinearExpressionIsNear(const LinearExpression expected, const double tolerance)
Definition matchers.cc:282
Matcher< SolveResult > IsOptimalWithDualSolution(const double expected_objective, const LinearConstraintMap< double > expected_dual_values, const VariableMap< double > expected_reduced_costs, const double tolerance)
Definition matchers.cc:790
Matcher< SolveResult > HasDualSolution(DualSolution expected, const double tolerance)
Definition matchers.cc:831
Matcher< Basis > BasisIs(const Basis &expected)
Definition matchers.cc:449
testing::Matcher< ComputeInfeasibleSubsystemResult > IsFeasible()
Definition matchers.cc:972
std::vector< typename Map::key_type > SortedKeys(const Map &map)
Definition key_types.h:87
testing::Matcher< ComputeInfeasibleSubsystemResult > IsUndetermined()
Definition matchers.cc:983
Matcher< SolveResult > IsOptimal(const std::optional< double > expected_primal_objective, const double tolerance)
Definition matchers.cc:762
testing::Matcher< SolveResult > TerminatesWithReasonNoSolutionFound(const Limit expected, const bool allow_limit_undetermined)
Definition matchers.cc:665
In SWIG mode, we don't want anything besides these top-level includes.
A LinearExpression with upper and lower bounds.
Bounds on the optimal objective value.
Configures SolveResult matcher IsConsistentWith() below.
Definition matchers.h:385
All information regarding why a call to Solve() terminated.