OR-Tools  9.3
test_util.cc
Go to the documentation of this file.
1// Copyright 2010-2021 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 <cstdint>
17#include <limits>
18#include <string>
19#include <vector>
20
21#include "Eigen/Core"
22#include "Eigen/SparseCore"
23#include "gmock/gmock.h"
25
27
28using ::testing::ElementsAre;
29
30constexpr double kInfinity = std::numeric_limits<double>::infinity();
31
33 QuadraticProgram lp(4, 4);
34 lp.constraint_lower_bounds << 12, -kInfinity, -4, -1;
35 lp.constraint_upper_bounds << 12, 7, kInfinity, 1;
38 std::vector<Eigen::Triplet<double, int64_t>> triplets = {
39 {0, 0, 2}, {0, 1, 1}, {0, 2, 1}, {0, 3, 2}, {1, 0, 1},
40 {1, 2, 1}, {2, 0, 4}, {3, 2, 1.5}, {3, 3, -1}};
41 lp.constraint_matrix.setFromTriplets(triplets.begin(), triplets.end());
42
43 lp.objective_vector << 5.5, -2, -1, 1;
44 lp.objective_offset = -14;
45 return lp;
46}
47
48void VerifyTestLp(const QuadraticProgram& qp, bool maximize) {
49 const double objective_sign = maximize ? -1 : 1;
50 EXPECT_THAT(objective_sign * qp.objective_offset, testing::DoubleEq(-14));
51 EXPECT_THAT(objective_sign * qp.objective_vector,
52 ElementsAre(5.5, -2, -1, 1));
53 EXPECT_EQ(qp.objective_scaling_factor, objective_sign);
54 EXPECT_FALSE(qp.objective_matrix.has_value());
55 EXPECT_THAT(qp.variable_lower_bounds,
56 ElementsAre(-kInfinity, -2, -kInfinity, 2.5));
57 EXPECT_THAT(qp.variable_upper_bounds,
58 ElementsAre(kInfinity, kInfinity, 6, 3.5));
59 EXPECT_THAT(qp.constraint_lower_bounds, ElementsAre(12, -kInfinity, -4, -1));
60 EXPECT_THAT(qp.constraint_upper_bounds, ElementsAre(12, 7, kInfinity, 1));
61 EXPECT_THAT(ToDense(qp.constraint_matrix),
62 EigenArrayEq<double>(
63 {{2, 1, 1, 2}, {1, 0, 1, 0}, {4, 0, 0, 0}, {0, 0, 1.5, -1}}));
64}
65
67 QuadraticProgram lp(4, 3);
68 lp.objective_offset = -14;
69 lp.objective_vector << 5, 2, 1, 1;
70 lp.constraint_lower_bounds << 12, 7, 1;
72 lp.variable_lower_bounds << 0, 0, 0, 0;
73 lp.variable_upper_bounds << 2, 4, 6, 3;
74 lp.constraint_matrix.coeffRef(0, 0) = 2.0;
75 lp.constraint_matrix.coeffRef(0, 1) = 1.0;
76 lp.constraint_matrix.coeffRef(0, 2) = 1.0;
77 lp.constraint_matrix.coeffRef(0, 3) = 2.0;
78 lp.constraint_matrix.coeffRef(1, 0) = 1.0;
79 lp.constraint_matrix.coeffRef(1, 2) = 1.0;
80 lp.constraint_matrix.coeffRef(2, 2) = 1.0;
81 lp.constraint_matrix.coeffRef(2, 3) = -1.0;
82 lp.constraint_matrix.makeCompressed();
83 return lp;
84}
85
87 QuadraticProgram lp(6, 3);
88 lp.objective_offset = 4;
89 lp.objective_vector << -1.0, -1.0, 1.0, -1.0, 1.0, -1.0;
90 lp.constraint_lower_bounds << -1.0, -1.0, -1.0;
92 lp.variable_lower_bounds << 0.0, 0.0, 0.0, 0.0, 0.0, 0.0;
93 lp.variable_upper_bounds << 1.0, 1.0, 1.0, 1.0, 1.0, 1.0;
94 lp.constraint_matrix.coeffRef(0, 1) = -1.0;
95 lp.constraint_matrix.coeffRef(0, 2) = 1.0;
96 lp.constraint_matrix.coeffRef(0, 5) = -1.0;
97 lp.constraint_matrix.coeffRef(1, 3) = -1.0;
98 lp.constraint_matrix.coeffRef(1, 4) = 1.0;
99 lp.constraint_matrix.coeffRef(1, 5) = -1.0;
100 lp.constraint_matrix.coeffRef(2, 0) = -1.0;
101 lp.constraint_matrix.coeffRef(2, 1) = -1.0;
102 lp.constraint_matrix.coeffRef(2, 3) = 1.0;
103 lp.constraint_matrix.makeCompressed();
104 return lp;
105}
106
108 QuadraticProgram lp(6, 3);
109 lp.objective_offset = 3;
110 lp.objective_vector << -1.0, -1.0, -1.0, 1.0, 1.0, 1.0;
111 lp.constraint_lower_bounds << -1.0, -1.0, -1.0;
113 lp.variable_lower_bounds << 0.0, 0.0, 0.0, 0.0, 0.0, 0.0;
114 lp.variable_upper_bounds << 1.0, 1.0, 1.0, 1.0, 1.0, 1.0;
115 lp.constraint_matrix.coeffRef(0, 0) = -1.0;
116 lp.constraint_matrix.coeffRef(0, 1) = -1.0;
117 lp.constraint_matrix.coeffRef(0, 3) = 1.0;
118 lp.constraint_matrix.coeffRef(1, 0) = -1.0;
119 lp.constraint_matrix.coeffRef(1, 2) = -1.0;
120 lp.constraint_matrix.coeffRef(1, 4) = 1.0;
121 lp.constraint_matrix.coeffRef(2, 1) = -1.0;
122 lp.constraint_matrix.coeffRef(2, 2) = -1.0;
123 lp.constraint_matrix.coeffRef(2, 5) = 1.0;
124 lp.constraint_matrix.makeCompressed();
125 return lp;
126}
127
128namespace {
129
130Eigen::DiagonalMatrix<double, Eigen::Dynamic> ConstructDiagonal(
131 const std::vector<double>& vec) {
132 Eigen::DiagonalMatrix<double, Eigen::Dynamic> diag;
133 diag.resize(vec.size());
134 for (int i = 0; i < vec.size(); ++i) {
135 diag.diagonal()[i] = vec[i];
136 }
137 return diag;
138}
139
140} // namespace
141
143 QuadraticProgram qp(2, 1);
146 qp.variable_lower_bounds << 1, -2;
147 qp.variable_upper_bounds << 2, 4;
148 qp.objective_vector << -1, -1;
149 qp.objective_offset = 5;
150 std::vector<Eigen::Triplet<double, int64_t>> constraint_triplets = {
151 {0, 0, 1}, {0, 1, 1}};
152 qp.constraint_matrix.setFromTriplets(constraint_triplets.begin(),
153 constraint_triplets.end());
154 qp.objective_matrix = ConstructDiagonal({4.0, 1.0});
155 return qp;
156}
157
159 QuadraticProgram qp(2, 1);
162 qp.variable_lower_bounds << 0, 0;
164 qp.objective_vector << -3, -1;
165 qp.objective_offset = 0;
166 std::vector<Eigen::Triplet<double, int64_t>> constraint_triplets = {
167 {0, 0, 1}, {0, 1, -1}};
168 qp.constraint_matrix.setFromTriplets(constraint_triplets.begin(),
169 constraint_triplets.end());
170 qp.objective_matrix = ConstructDiagonal({1.0, 1.0});
171 return qp;
172}
173
175 QuadraticProgram qp(3, 2);
176 qp.constraint_lower_bounds << 1, 4;
177 qp.constraint_upper_bounds << 1, 4;
178 qp.variable_lower_bounds << 0, 0, 0;
180 qp.objective_vector << 1, 0, -1;
181 qp.objective_offset = 0;
182 std::vector<Eigen::Triplet<double, int64_t>> constraint_triplets = {
183 {0, 0, 1}, {0, 2, -1}, {1, 0, 2}};
184 qp.constraint_matrix.setFromTriplets(constraint_triplets.begin(),
185 constraint_triplets.end());
186 qp.objective_matrix = ConstructDiagonal({0.0, 1.0, 2.0});
187 return qp;
188}
189
191 QuadraticProgram lp(2, 1);
192 lp.constraint_matrix.coeffRef(0, 0) = 1.0;
193 lp.constraint_matrix.coeffRef(0, 1) = -1.0;
194 lp.constraint_lower_bounds << 2.0;
195 lp.constraint_upper_bounds << 1.0;
196 lp.variable_lower_bounds << 0.0, 0.0;
198 lp.constraint_matrix.makeCompressed();
199 lp.objective_vector << 1.0, 1.0;
200 return lp;
201}
202
204 QuadraticProgram lp(2, 1);
205 lp.constraint_matrix.coeffRef(0, 0) = 1.0;
206 lp.constraint_matrix.coeffRef(0, 1) = -1.0;
207 lp.constraint_matrix.makeCompressed();
209 lp.constraint_upper_bounds << 1.0;
210 lp.variable_lower_bounds << 2.0, 0.0;
212 lp.objective_vector << 1.0, 1.0;
213 return lp;
214}
215
217 QuadraticProgram lp(2, 2);
218 lp.constraint_matrix.coeffRef(0, 0) = 1.0;
219 lp.constraint_matrix.coeffRef(0, 1) = -1.0;
220 lp.constraint_matrix.coeffRef(1, 0) = -1.0;
221 lp.constraint_matrix.coeffRef(1, 1) = 1.0;
223 lp.variable_lower_bounds << 0.0, 0.0;
225 lp.constraint_matrix.makeCompressed();
226
227 lp.constraint_upper_bounds << 1.0, -2.0;
228 lp.objective_vector << 1.0, 1.0;
229 return lp;
230}
231
234 lp.constraint_upper_bounds(1) = 2.0;
235 lp.objective_vector *= -1.0;
236 return lp;
237}
238
241 lp.objective_vector *= -1.0;
242 return lp;
243}
244
246 QuadraticProgram lp(2, 2);
247 lp.constraint_matrix.coeffRef(0, 0) = 1.0;
248 lp.constraint_matrix.coeffRef(0, 1) = 1.0;
249 lp.constraint_matrix.coeffRef(1, 0) = 1.0;
250 lp.constraint_matrix.coeffRef(1, 1) = 2.0;
252 lp.constraint_upper_bounds << 2.0, 2.0;
253 lp.variable_lower_bounds << 0.5, 0.5;
254 lp.variable_upper_bounds << 2.0, 2.0;
255 lp.constraint_matrix.makeCompressed();
256
257 lp.objective_vector << -4.0, 0.0;
258 return lp;
259}
260
262 QuadraticProgram lp(2, 0);
265 lp.objective_vector << 4.0, 0.0;
266 return lp;
267}
268
269void VerifyTestQp(const QuadraticProgram& qp, bool maximize) {
270 const double objective_sign = maximize ? -1 : 1;
271 EXPECT_EQ(qp.objective_scaling_factor, objective_sign);
272 EXPECT_THAT(objective_sign * qp.objective_offset, testing::DoubleEq(5));
273 EXPECT_THAT(objective_sign * qp.objective_vector, ElementsAre(-1, -1));
274 ASSERT_TRUE(qp.objective_matrix.has_value());
275 EXPECT_THAT(objective_sign * qp.objective_matrix->diagonal(),
276 EigenArrayEq<double>({4, 1}));
277 EXPECT_THAT(qp.variable_lower_bounds, ElementsAre(1, -2));
278 EXPECT_THAT(qp.variable_upper_bounds, ElementsAre(2, 4));
279 EXPECT_THAT(qp.constraint_lower_bounds, ElementsAre(-kInfinity));
280 EXPECT_THAT(qp.constraint_upper_bounds, ElementsAre(1));
281 EXPECT_THAT(ToDense(qp.constraint_matrix), EigenArrayEq<double>({{1, 1}}));
282}
283
284::Eigen::ArrayXXd ToDense(
285 const Eigen::SparseMatrix<double, Eigen::ColMajor, int64_t>& sparse_mat) {
286 return ::Eigen::ArrayXXd(::Eigen::MatrixXd(sparse_mat));
287}
288
289} // namespace operations_research::pdlp
const double kInfinity
Definition: lp_types.h:84
QuadraticProgram SmallDualInfeasibleLp()
Definition: test_util.cc:232
QuadraticProgram TestDiagonalQp2()
Definition: test_util.cc:158
::Eigen::ArrayXXd ToDense(const Eigen::SparseMatrix< double, Eigen::ColMajor, int64_t > &sparse_mat)
Definition: test_util.cc:284
void VerifyTestQp(const QuadraticProgram &qp, bool maximize)
Definition: test_util.cc:269
QuadraticProgram CorrelationClusteringStarLp()
Definition: test_util.cc:107
QuadraticProgram TestDiagonalQp3()
Definition: test_util.cc:174
QuadraticProgram TinyLp()
Definition: test_util.cc:66
void VerifyTestLp(const QuadraticProgram &qp, bool maximize)
Definition: test_util.cc:48
QuadraticProgram LpWithoutConstraints()
Definition: test_util.cc:261
QuadraticProgram SmallInvalidProblemLp()
Definition: test_util.cc:190
QuadraticProgram SmallPrimalDualInfeasibleLp()
Definition: test_util.cc:239
QuadraticProgram TestLp()
Definition: test_util.cc:32
QuadraticProgram SmallInitializationLp()
Definition: test_util.cc:245
QuadraticProgram SmallPrimalInfeasibleLp()
Definition: test_util.cc:216
QuadraticProgram SmallInconsistentVariableBoundsLp()
Definition: test_util.cc:203
QuadraticProgram TestDiagonalQp1()
Definition: test_util.cc:142
QuadraticProgram CorrelationClusteringLp()
Definition: test_util.cc:86
Eigen::SparseMatrix< double, Eigen::ColMajor, int64_t > constraint_matrix
std::optional< Eigen::DiagonalMatrix< double, Eigen::Dynamic > > objective_matrix