Google OR-Tools v9.15
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
gscip_testing.cc
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
15
16#include <algorithm>
17#include <cstdlib>
18#include <ostream>
19#include <string>
20#include <vector>
21
22#include "absl/strings/str_cat.h"
23#include "absl/strings/str_join.h"
25
26namespace operations_research {
27
28using ::testing::MakeMatcher;
29using ::testing::Matcher;
30using ::testing::MatcherInterface;
31using ::testing::MatchResultListener;
32
34 GScipParameters result;
35 GScipSetOutputEnabled(&result, false);
36 return result;
37}
38
40 std::vector<std::string> terms;
41 for (const auto& var_value_pair : solution) {
42 terms.push_back(absl::StrCat(SCIPvarGetName(var_value_pair.first), "=",
43 var_value_pair.second));
44 }
45 std::sort(terms.begin(), terms.end());
46 return absl::StrCat("{", absl::StrJoin(terms, ","), "}");
47}
48
49bool SolutionsAlmostEqual(const GScipSolution& left, const GScipSolution& right,
50 const double tolerance) {
51 if (left.size() != right.size()) return false;
52 for (const auto& kv_pair : left) {
53 if (!right.contains(kv_pair.first)) return false;
54 if (std::abs(kv_pair.second - right.at(kv_pair.first)) > tolerance) {
55 return false;
56 }
57 }
58 return true;
59}
60
61namespace {
62
63class GScipSolutionNearMatcher : public MatcherInterface<GScipSolution> {
64 public:
65 GScipSolutionNearMatcher(const GScipSolution& rhs, double tolerance)
66 : rhs_(rhs), tolerance_(tolerance) {}
67
68 bool MatchAndExplain(GScipSolution lhs,
69 MatchResultListener* listener) const override {
70 if (!SolutionsAlmostEqual(lhs, rhs_, tolerance_)) {
71 *listener << "Expected: " << SolutionToString(lhs)
72 << " != actual: " << SolutionToString(rhs_);
73 return false;
74 }
75 return true;
76 }
77
78 void DescribeTo(std::ostream* os) const override {
79 *os << "solution is term-wise within " << tolerance_ << " of "
80 << SolutionToString(rhs_);
81 }
82
83 void DescribeNegationTo(std::ostream* os) const override {
84 *os << "solution differs by at least " << tolerance_ << " from "
85 << SolutionToString(rhs_);
86 }
87
88 private:
90 const double tolerance_;
91};
92
93void AssertOptimalWithASolution(const GScipResult& actual_result,
94 const double expected_objective_value,
95 const double tolerance) {
96 ASSERT_EQ(actual_result.gscip_output.status(), GScipOutput::OPTIMAL);
97 EXPECT_NEAR(actual_result.gscip_output.stats().best_bound(),
98 expected_objective_value, tolerance);
99 EXPECT_NEAR(actual_result.gscip_output.stats().best_objective(),
100 expected_objective_value, tolerance);
101 ASSERT_GE(actual_result.solutions.size(), 1);
102 ASSERT_GE(actual_result.objective_values.size(), 1);
103 EXPECT_NEAR(actual_result.objective_values[0], expected_objective_value,
104 tolerance);
105 EXPECT_THAT(actual_result.primal_ray, ::testing::IsEmpty());
106}
107
108} // namespace
109
110testing::Matcher<GScipSolution> GScipSolutionEquals(const GScipSolution& rhs) {
111 return MakeMatcher(new GScipSolutionNearMatcher(rhs, 0.0));
112}
113testing::Matcher<GScipSolution> GScipSolutionAlmostEquals(
114 const GScipSolution& rhs, double tolerance) {
115 return MakeMatcher(new GScipSolutionNearMatcher(rhs, tolerance));
116}
117
119 const double expected_objective_value,
120 const GScipSolution& expected_solution,
121 const double tolerance) {
122 ASSERT_NO_FATAL_FAILURE(AssertOptimalWithASolution(
123 actual_result, expected_objective_value, tolerance));
124 EXPECT_THAT(actual_result.solutions[0],
125 GScipSolutionAlmostEquals(expected_solution, tolerance));
126}
127
129 const GScipResult& actual_result, const double expected_objective_value,
130 const GScipSolution& expected_solution, const double tolerance) {
131 ASSERT_NO_FATAL_FAILURE(AssertOptimalWithASolution(
132 actual_result, expected_objective_value, tolerance));
133 // TODO(user): this should have some kind of matcher, it will give a better
134 // error message.
135 for (const auto& expected_var_val : expected_solution) {
136 ASSERT_TRUE(actual_result.solutions[0].contains(expected_var_val.first));
137 EXPECT_NEAR(actual_result.solutions[0].at(expected_var_val.first),
138 expected_var_val.second, tolerance);
139 }
140}
141
142} // namespace operations_research
static constexpr Status OPTIMAL
Definition gscip.pb.h:1464
EXPECT_THAT(ComputeInfeasibleSubsystem(model, GetParam().solver_type), IsOkAndHolds(IsInfeasible(true, ModelSubset{ .variable_bounds={{x, ModelSubset::Bounds{.lower=false,.upper=true}}},.linear_constraints={ {c, ModelSubset::Bounds{.lower=true,.upper=false}}}})))
OR-Tools root namespace.
void GScipSetOutputEnabled(GScipParameters *parameters, bool output_enabled)
void AssertOptimalWithBestSolution(const GScipResult &actual_result, const double expected_objective_value, const GScipSolution &expected_solution, const double tolerance)
Select next search node to expand Select next item_i to add this new search node to the search Generate a new search node where item_i is not in the knapsack Check validity of this new partial solution(using propagators) - If valid
bool SolutionsAlmostEqual(const GScipSolution &left, const GScipSolution &right, const double tolerance)
std::string SolutionToString(const GScipSolution &solution)
void AssertOptimalWithPartialBestSolution(const GScipResult &actual_result, const double expected_objective_value, const GScipSolution &expected_solution, const double tolerance)
GScipParameters TestGScipParameters()
absl::flat_hash_map< SCIP_VAR *, double > GScipSolution
Definition gscip.h:89
testing::Matcher< GScipSolution > GScipSolutionEquals(const GScipSolution &rhs)
testing::Matcher< GScipSolution > GScipSolutionAlmostEquals(const GScipSolution &rhs, double tolerance)
std::vector< GScipSolution > solutions
Definition gscip.h:98