1#include "storm-config.h"
19class DefaultEnvironment {
21 typedef double ValueType;
22 static const bool isExact =
false;
23 static const storm::solver::LpSolverTypeSelection solverSelection = storm::solver::LpSolverTypeSelection::FROMSETTINGS;
24 static const bool IntegerSupport =
true;
25 static const bool IncrementalSupport =
true;
26 static const bool strictRelationSupport =
true;
27 static const bool IndicatorSupport =
false;
30#ifdef STORM_HAVE_LP_SOLVER
38class GlpkEnvironment {
40 typedef double ValueType;
41 static const bool isExact =
false;
42 static const storm::solver::LpSolverTypeSelection solverSelection = storm::solver::LpSolverTypeSelection::Glpk;
43 static const bool IntegerSupport =
true;
44 static const bool IncrementalSupport =
true;
45 static const bool strictRelationSupport =
true;
46 static const bool IndicatorSupport =
false;
53#ifdef STORM_HAVE_GUROBI
54class GurobiEnvironment {
57 static const bool isExact =
false;
58 static const storm::solver::LpSolverTypeSelection solverSelection = storm::solver::LpSolverTypeSelection::Gurobi;
59 static const bool IntegerSupport =
true;
60 static const bool IncrementalSupport =
true;
61 static const bool strictRelationSupport =
true;
62 static const bool IndicatorSupport =
true;
72 typedef storm::RationalNumber ValueType;
73 static const bool isExact =
true;
74 static const storm::solver::LpSolverTypeSelection solverSelection = storm::solver::LpSolverTypeSelection::Z3;
75 static const bool IntegerSupport =
true;
76 static const bool IncrementalSupport =
true;
77 static const bool strictRelationSupport =
true;
78 static const bool IndicatorSupport =
true;
85#ifdef STORM_HAVE_SOPLEX
86class SoplexEnvironment {
89 static const bool isExact =
false;
90 static const storm::solver::LpSolverTypeSelection solverSelection = storm::solver::LpSolverTypeSelection::Soplex;
91 static const bool IntegerSupport =
false;
92 static const bool IncrementalSupport =
false;
93 static const bool strictRelationSupport =
false;
94 static const bool IndicatorSupport =
false;
101class SoplexExactEnvironment {
104 static const bool isExact =
true;
105 static const storm::solver::LpSolverTypeSelection solverSelection = storm::solver::LpSolverTypeSelection::Soplex;
106 static const bool IntegerSupport =
false;
107 static const bool IncrementalSupport =
false;
108 static const bool strictRelationSupport =
false;
109 static const bool IndicatorSupport =
false;
117#ifdef STORM_HAVE_HIGHS
118class HighsEnvironment {
121 static const bool isExact =
false;
122 static const storm::solver::LpSolverTypeSelection solverSelection = storm::solver::LpSolverTypeSelection::Highs;
123 static const bool IntegerSupport =
true;
124 static const bool IncrementalSupport =
false;
125 static const bool strictRelationSupport =
false;
126 static const bool IndicatorSupport =
true;
134template<
typename TestType>
135class LpSolverTest :
public ::testing::Test {
137 typedef typename TestType::ValueType ValueType;
139 void SetUp()
override {
145 storm::solver::LpSolverTypeSelection solverSelection()
const {
146 return TestType::solverSelection;
149 storm::Environment env()
const {
150 return storm::Environment();
153 std::unique_ptr<storm::utility::solver::LpSolverFactory<ValueType>> factory()
const {
157 ValueType
parseNumber(std::string
const& input)
const {
161 ValueType precision()
const {
165 bool supportsInteger()
const {
166 return TestType::IntegerSupport;
169 bool supportsIncremental()
const {
170 return TestType::IncrementalSupport;
173 bool supportsStrictRelation()
const {
174 return TestType::strictRelationSupport;
177 bool supportsIndicator()
const {
178 return TestType::IndicatorSupport;
186 std::string
const& rhs, storm::expressions::Variable& x,
187 storm::expressions::Variable& b) {
188 auto solver = this->factory()->create(this->env(),
"");
189 solver->setOptimizationDirection(dir);
190 x = solver->addBoundedContinuousVariable(
"x", 0, this->
parseNumber(
"5"), 1);
191 b = solver->addBinaryVariable(
"b");
192 if (fixedB.has_value()) {
193 solver->addConstraint(
"", b == solver->getConstant(*fixedB ? 1 : 0));
195 storm::expressions::Expression rhsExpression = solver->getConstant(this->
parseNumber(rhs));
196 storm::expressions::Expression constraint;
198 constraint = x <= rhsExpression;
200 constraint = x >= rhsExpression;
202 constraint = x == rhsExpression;
204 solver->addIndicatorConstraint(
"", b, indicatorValue, constraint);
210 bool skipped()
const {
211 return TestType::skip();
215typedef ::testing::Types<DefaultEnvironment
216#ifdef STORM_HAVE_GLPK
220#ifdef STORM_HAVE_GUROBI
224#ifdef STORM_HAVE_HIGHS
228#ifdef STORM_HAVE_SOPLEX
230 SoplexEnvironment, SoplexExactEnvironment
242 auto solver = this->factory()->create(this->env(),
"");
243 solver->setOptimizationDirection(storm::OptimizationDirection::Maximize);
247 ASSERT_NO_THROW(x = solver->addBoundedContinuousVariable(
"x", 0, 1, -1));
248 ASSERT_NO_THROW(y = solver->addLowerBoundedContinuousVariable(
"y", 0, 2));
249 ASSERT_NO_THROW(z = solver->addLowerBoundedContinuousVariable(
"z", 0, 1));
250 ASSERT_NO_THROW(solver->update());
252 ASSERT_NO_THROW(solver->addConstraint(
"", x + y + z <= solver->getConstant(12)));
253 ASSERT_NO_THROW(solver->addConstraint(
"", solver->getConstant(this->parseNumber(
"1/2")) * y + z - x == solver->getConstant(5)));
254 ASSERT_NO_THROW(solver->addConstraint(
"", y - x <= solver->getConstant(this->
parseNumber(
"11/2"))));
255 ASSERT_NO_THROW(solver->update());
257 ASSERT_NO_THROW(solver->optimize());
258 ASSERT_TRUE(solver->isOptimal());
259 ASSERT_FALSE(solver->isUnbounded());
260 ASSERT_FALSE(solver->isInfeasible());
261 EXPECT_NEAR(this->
parseNumber(
"1"), solver->getContinuousValue(x), this->precision());
262 EXPECT_NEAR(this->
parseNumber(
"13/2"), solver->getContinuousValue(y), this->precision());
263 EXPECT_NEAR(this->
parseNumber(
"11/4"), solver->getContinuousValue(z), this->precision());
264 EXPECT_NEAR(this->
parseNumber(
"59/4"), solver->getObjectiveValue(), this->precision());
268 typedef typename TestFixture::ValueType
ValueType;
269 auto solver = this->factory()->createRaw(this->env(),
"");
270 solver->setOptimizationDirection(storm::OptimizationDirection::Maximize);
271 ASSERT_EQ(0u, solver->addBoundedContinuousVariable(
"x", 0, 1, -1));
272 ASSERT_EQ(1u, solver->addLowerBoundedContinuousVariable(
"y", 0, 2));
273 ASSERT_EQ(2u, solver->addLowerBoundedContinuousVariable(
"z", 0, 1));
274 ASSERT_NO_THROW(solver->update());
281 ASSERT_NO_THROW(solver->addConstraint(
"", constraint1));
287 ASSERT_NO_THROW(solver->addConstraint(
"", constraint2));
292 ASSERT_NO_THROW(solver->addConstraint(
"", constraint3));
293 ASSERT_NO_THROW(solver->update());
295 ASSERT_NO_THROW(solver->optimize());
296 ASSERT_TRUE(solver->isOptimal());
297 ASSERT_FALSE(solver->isUnbounded());
298 ASSERT_FALSE(solver->isInfeasible());
299 EXPECT_NEAR(this->
parseNumber(
"1"), solver->getContinuousValue(0), this->precision());
300 EXPECT_NEAR(this->
parseNumber(
"13/2"), solver->getContinuousValue(1), this->precision());
301 EXPECT_NEAR(this->
parseNumber(
"11/4"), solver->getContinuousValue(2), this->precision());
302 EXPECT_NEAR(this->
parseNumber(
"59/4"), solver->getObjectiveValue(), this->precision());
306 auto solver = this->factory()->create(this->env(),
"");
307 solver->setOptimizationDirection(storm::OptimizationDirection::Minimize);
311 ASSERT_NO_THROW(x = solver->addBoundedContinuousVariable(
"x", 0, 1, -1));
312 ASSERT_NO_THROW(y = solver->addLowerBoundedContinuousVariable(
"y", 0, 2));
313 ASSERT_NO_THROW(z = solver->addBoundedContinuousVariable(
"z", 1, this->parseNumber(
"57/10"), -1));
314 ASSERT_NO_THROW(solver->update());
316 ASSERT_NO_THROW(solver->addConstraint(
"", x + y + z <= solver->getConstant(12)));
317 ASSERT_NO_THROW(solver->addConstraint(
"", solver->getConstant(this->parseNumber(
"1/2")) * y + z - x <= solver->getConstant(5)));
318 ASSERT_NO_THROW(solver->addConstraint(
"", y - x <= solver->getConstant(this->
parseNumber(
"11/2"))));
319 ASSERT_NO_THROW(solver->update());
321 ASSERT_NO_THROW(solver->optimize());
322 ASSERT_TRUE(solver->isOptimal());
323 ASSERT_FALSE(solver->isUnbounded());
324 ASSERT_FALSE(solver->isInfeasible());
326 EXPECT_NEAR(this->
parseNumber(
"1"), solver->getContinuousValue(x), this->precision());
327 EXPECT_NEAR(this->
parseNumber(
"0"), solver->getContinuousValue(y), this->precision());
328 EXPECT_NEAR(this->
parseNumber(
"57/10"), solver->getContinuousValue(z), this->precision());
329 EXPECT_NEAR(this->
parseNumber(
"-67/10"), solver->getObjectiveValue(), this->precision());
333 typedef typename TestFixture::ValueType
ValueType;
334 auto solver = this->factory()->createRaw(this->env(),
"");
335 solver->setOptimizationDirection(storm::OptimizationDirection::Minimize);
337 ASSERT_EQ(0u, solver->addBoundedContinuousVariable(
"x", 0, 1, -1));
338 ASSERT_EQ(1u, solver->addLowerBoundedContinuousVariable(
"y", 0, 2));
339 ASSERT_EQ(2u, solver->addBoundedContinuousVariable(
"z", 1, this->parseNumber(
"57/10"), -1));
340 ASSERT_NO_THROW(solver->update());
347 ASSERT_NO_THROW(solver->addConstraint(
"", constraint1));
353 ASSERT_NO_THROW(solver->addConstraint(
"", constraint2));
358 ASSERT_NO_THROW(solver->addConstraint(
"", constraint3));
359 ASSERT_NO_THROW(solver->update());
361 ASSERT_NO_THROW(solver->optimize());
362 ASSERT_TRUE(solver->isOptimal());
363 ASSERT_FALSE(solver->isUnbounded());
364 ASSERT_FALSE(solver->isInfeasible());
366 EXPECT_NEAR(this->
parseNumber(
"1"), solver->getContinuousValue(0), this->precision());
367 EXPECT_NEAR(this->
parseNumber(
"0"), solver->getContinuousValue(1), this->precision());
368 EXPECT_NEAR(this->
parseNumber(
"57/10"), solver->getContinuousValue(2), this->precision());
369 EXPECT_NEAR(this->
parseNumber(
"-67/10"), solver->getObjectiveValue(), this->precision());
373 if (!this->supportsInteger()) {
376 auto solver = this->factory()->create(this->env(),
"");
377 solver->setOptimizationDirection(storm::OptimizationDirection::Maximize);
381 ASSERT_NO_THROW(x = solver->addBinaryVariable(
"x", -1));
382 ASSERT_NO_THROW(y = solver->addLowerBoundedIntegerVariable(
"y", 0, 2));
383 ASSERT_NO_THROW(z = solver->addLowerBoundedContinuousVariable(
"z", 0, 1));
384 ASSERT_NO_THROW(solver->update());
386 ASSERT_NO_THROW(solver->addConstraint(
"", x + y + z <= solver->getConstant(12)));
387 ASSERT_NO_THROW(solver->addConstraint(
"", solver->getConstant(this->parseNumber(
"1/2")) * y + z - x == solver->getConstant(5)));
388 ASSERT_NO_THROW(solver->addConstraint(
"", y - x <= solver->getConstant(this->
parseNumber(
"11/2"))));
389 ASSERT_NO_THROW(solver->update());
390 ASSERT_NO_THROW(solver->optimize());
391 ASSERT_TRUE(solver->isOptimal());
392 ASSERT_FALSE(solver->isUnbounded());
393 ASSERT_FALSE(solver->isInfeasible());
395 EXPECT_TRUE(solver->getBinaryValue(x));
396 EXPECT_EQ(6, solver->getIntegerValue(y));
397 EXPECT_NEAR(this->
parseNumber(
"3"), solver->getContinuousValue(z), this->precision());
398 EXPECT_NEAR(this->
parseNumber(
"14"), solver->getObjectiveValue(), this->precision());
402 if (!this->supportsInteger()) {
405 typedef typename TestFixture::ValueType
ValueType;
406 auto solver = this->factory()->createRaw(this->env(),
"");
407 solver->setOptimizationDirection(storm::OptimizationDirection::Maximize);
411 ASSERT_EQ(0u, solver->addBinaryVariable(
"x", -1));
412 ASSERT_EQ(1u, solver->addLowerBoundedIntegerVariable(
"y", 0, 2));
413 ASSERT_EQ(2u, solver->addLowerBoundedContinuousVariable(
"z", 0, 1));
414 ASSERT_NO_THROW(solver->update());
421 ASSERT_NO_THROW(solver->addConstraint(
"", constraint1));
427 ASSERT_NO_THROW(solver->addConstraint(
"", constraint2));
432 ASSERT_NO_THROW(solver->addConstraint(
"", constraint3));
433 ASSERT_NO_THROW(solver->update());
435 ASSERT_NO_THROW(solver->optimize());
436 ASSERT_TRUE(solver->isOptimal());
437 ASSERT_FALSE(solver->isUnbounded());
438 ASSERT_FALSE(solver->isInfeasible());
439 EXPECT_TRUE(solver->getBinaryValue(0));
440 EXPECT_EQ(6, solver->getIntegerValue(1));
441 EXPECT_NEAR(this->
parseNumber(
"3"), solver->getContinuousValue(2), this->precision());
442 EXPECT_NEAR(this->
parseNumber(
"14"), solver->getObjectiveValue(), this->precision());
446 if (!this->supportsInteger()) {
449 auto solver = this->factory()->create(this->env(),
"");
450 solver->setOptimizationDirection(storm::OptimizationDirection::Minimize);
454 ASSERT_NO_THROW(x = solver->addBinaryVariable(
"x", -1));
455 ASSERT_NO_THROW(y = solver->addLowerBoundedIntegerVariable(
"y", 0, 2));
456 ASSERT_NO_THROW(z = solver->addBoundedContinuousVariable(
"z", 0, 5, -1));
457 ASSERT_NO_THROW(solver->update());
459 ASSERT_NO_THROW(solver->addConstraint(
"", x + y + z <= solver->getConstant(12)));
460 ASSERT_NO_THROW(solver->addConstraint(
"", solver->getConstant(this->parseNumber(
"1/2")) * y + z - x <= solver->getConstant(5)));
461 ASSERT_NO_THROW(solver->addConstraint(
"", y - x <= solver->getConstant(this->
parseNumber(
"11/2"))));
462 ASSERT_NO_THROW(solver->update());
465 if (this->solverSelection() == storm::solver::LpSolverTypeSelection::Z3 && storm::test::z3AtLeastVersion(4, 8, 8) &&
466 !storm::test::z3AtLeastVersion(4, 13, 3)) {
468 GTEST_SKIP() <<
"Test disabled since it triggers a bug in the installed version of z3.";
472 ASSERT_NO_THROW(solver->optimize());
473 ASSERT_TRUE(solver->isOptimal());
474 ASSERT_FALSE(solver->isUnbounded());
475 ASSERT_FALSE(solver->isInfeasible());
477 EXPECT_TRUE(solver->getBinaryValue(x));
478 EXPECT_EQ(0, solver->getIntegerValue(y));
479 EXPECT_NEAR(this->
parseNumber(
"5"), solver->getContinuousValue(z), this->precision());
480 EXPECT_NEAR(this->
parseNumber(
"-6"), solver->getObjectiveValue(), this->precision());
484 auto solver = this->factory()->create(this->env(),
"");
485 solver->setOptimizationDirection(storm::OptimizationDirection::Maximize);
489 ASSERT_NO_THROW(x = solver->addBoundedContinuousVariable(
"x", 0, 1, -1));
490 ASSERT_NO_THROW(y = solver->addLowerBoundedContinuousVariable(
"y", 0, 2));
491 ASSERT_NO_THROW(z = solver->addLowerBoundedContinuousVariable(
"z", 0, 1));
492 ASSERT_NO_THROW(solver->update());
494 ASSERT_NO_THROW(solver->addConstraint(
"", x + y + z <= solver->getConstant(12)));
495 ASSERT_NO_THROW(solver->addConstraint(
"", solver->getConstant(this->parseNumber(
"1/2")) * y + z - x == solver->getConstant(5)));
496 ASSERT_NO_THROW(solver->addConstraint(
"", y - x <= solver->getConstant(this->
parseNumber(
"11/2"))));
497 if (this->supportsStrictRelation()) {
498 ASSERT_NO_THROW(solver->addConstraint(
"", y > solver->getConstant((this->parseNumber(
"7")))));
500 ASSERT_NO_THROW(solver->addConstraint(
"", y >= solver->getConstant(this->parseNumber(
"7") + this->precision())));
502 ASSERT_NO_THROW(solver->update());
504 ASSERT_NO_THROW(solver->optimize());
505 ASSERT_FALSE(solver->isOptimal());
506 ASSERT_FALSE(solver->isUnbounded());
507 ASSERT_TRUE(solver->isInfeasible());
515 if (!this->supportsInteger()) {
518 auto solver = this->factory()->create(this->env(),
"");
519 solver->setOptimizationDirection(storm::OptimizationDirection::Maximize);
523 ASSERT_NO_THROW(x = solver->addBinaryVariable(
"x", -1));
524 ASSERT_NO_THROW(y = solver->addLowerBoundedContinuousVariable(
"y", 0, 2));
525 ASSERT_NO_THROW(z = solver->addLowerBoundedContinuousVariable(
"z", 0, 1));
526 ASSERT_NO_THROW(solver->update());
528 ASSERT_NO_THROW(solver->addConstraint(
"", x + y + z <= solver->getConstant(12)));
529 ASSERT_NO_THROW(solver->addConstraint(
"", solver->getConstant(this->parseNumber(
"1/2")) * y + z - x == solver->getConstant(5)));
530 ASSERT_NO_THROW(solver->addConstraint(
"", y - x <= solver->getConstant(this->
parseNumber(
"11/2"))));
531 if (this->supportsStrictRelation()) {
532 ASSERT_NO_THROW(solver->addConstraint(
"", y > solver->getConstant((this->parseNumber(
"7")))));
534 ASSERT_NO_THROW(solver->addConstraint(
"", y >= solver->getConstant(this->parseNumber(
"7") + this->precision())));
536 ASSERT_NO_THROW(solver->update());
538 ASSERT_NO_THROW(solver->optimize());
539 ASSERT_FALSE(solver->isOptimal());
540 ASSERT_FALSE(solver->isUnbounded());
541 ASSERT_TRUE(solver->isInfeasible());
549 auto solver = this->factory()->create(this->env(),
"");
550 solver->setOptimizationDirection(storm::OptimizationDirection::Maximize);
554 ASSERT_NO_THROW(x = solver->addBoundedContinuousVariable(
"x", 0, 1, -1));
555 ASSERT_NO_THROW(y = solver->addLowerBoundedContinuousVariable(
"y", 0, 2));
556 ASSERT_NO_THROW(z = solver->addLowerBoundedContinuousVariable(
"z", 0, 1));
557 ASSERT_NO_THROW(solver->update());
559 ASSERT_NO_THROW(solver->addConstraint(
"", x + y - z <= solver->getConstant(12)));
560 ASSERT_NO_THROW(solver->addConstraint(
"", y - x <= solver->getConstant(this->
parseNumber(
"11/2"))));
561 ASSERT_NO_THROW(solver->update());
563 ASSERT_NO_THROW(solver->optimize());
564 ASSERT_FALSE(solver->isOptimal());
565 ASSERT_TRUE(solver->isUnbounded());
566 ASSERT_FALSE(solver->isInfeasible());
574 if (!this->supportsInteger()) {
577 auto solver = this->factory()->create(this->env(),
"");
578 solver->setOptimizationDirection(storm::OptimizationDirection::Maximize);
582 ASSERT_NO_THROW(x = solver->addBinaryVariable(
"x", -1));
583 ASSERT_NO_THROW(y = solver->addLowerBoundedContinuousVariable(
"y", 0, 2));
584 ASSERT_NO_THROW(z = solver->addLowerBoundedContinuousVariable(
"z", 0, 1));
585 ASSERT_NO_THROW(solver->update());
587 ASSERT_NO_THROW(solver->addConstraint(
"", x + y - z <= solver->getConstant(12)));
588 ASSERT_NO_THROW(solver->addConstraint(
"", y - x <= solver->getConstant(this->
parseNumber(
"11/2"))));
589 ASSERT_NO_THROW(solver->update());
591 ASSERT_NO_THROW(solver->optimize());
592 ASSERT_FALSE(solver->isOptimal());
593 ASSERT_TRUE(solver->isUnbounded());
594 ASSERT_FALSE(solver->isInfeasible());
602 if (!this->supportsIncremental()) {
605 auto solver = this->factory()->create(this->env(),
"");
606 solver->setOptimizationDirection(storm::OptimizationDirection::Maximize);
608 ASSERT_NO_THROW(x = solver->addUnboundedContinuousVariable(
"x", 1));
611 ASSERT_NO_THROW(solver->addConstraint(
"", x <= solver->getConstant(12)));
612 ASSERT_NO_THROW(solver->optimize());
614 ASSERT_TRUE(solver->isOptimal());
615 EXPECT_NEAR(this->
parseNumber(
"12"), solver->getContinuousValue(x), this->precision());
618 ASSERT_NO_THROW(y = solver->addUnboundedContinuousVariable(
"y"));
619 ASSERT_NO_THROW(solver->addConstraint(
"", y <= solver->getConstant(6)));
620 ASSERT_NO_THROW(solver->addConstraint(
"", x <= y));
622 ASSERT_NO_THROW(solver->optimize());
623 ASSERT_TRUE(solver->isOptimal());
624 EXPECT_NEAR(this->
parseNumber(
"6"), solver->getContinuousValue(x), this->precision());
625 EXPECT_NEAR(this->
parseNumber(
"6"), solver->getContinuousValue(y), this->precision());
627 ASSERT_NO_THROW(solver->optimize());
629 ASSERT_TRUE(solver->isOptimal());
630 EXPECT_NEAR(this->
parseNumber(
"12"), solver->getContinuousValue(x), this->precision());
633 ASSERT_NO_THROW(y = solver->addUnboundedContinuousVariable(
"y", 10));
634 ASSERT_NO_THROW(solver->addConstraint(
"", y <= solver->getConstant(20)));
635 ASSERT_NO_THROW(solver->addConstraint(
"", y <= -x));
637 ASSERT_NO_THROW(solver->optimize());
638 ASSERT_TRUE(solver->isOptimal());
639 EXPECT_NEAR(this->
parseNumber(
"-20"), solver->getContinuousValue(x), this->precision());
640 EXPECT_NEAR(this->
parseNumber(
"20"), solver->getContinuousValue(y), this->precision());
643 ASSERT_NO_THROW(solver->optimize());
645 ASSERT_TRUE(solver->isOptimal());
646 EXPECT_NEAR(this->
parseNumber(
"12"), solver->getContinuousValue(x), this->precision());
649 ASSERT_NO_THROW(z = solver->addUnboundedIntegerVariable(
"z"));
650 ASSERT_NO_THROW(solver->addConstraint(
"", z <= solver->getConstant(6)));
651 ASSERT_NO_THROW(solver->addConstraint(
"", x <= z));
652 ASSERT_NO_THROW(solver->optimize());
654 ASSERT_TRUE(solver->isOptimal());
655 EXPECT_NEAR(this->
parseNumber(
"6"), solver->getContinuousValue(x), this->precision());
656 EXPECT_EQ(6, solver->getIntegerValue(z));
659 ASSERT_NO_THROW(solver->optimize());
661 ASSERT_TRUE(solver->isOptimal());
662 EXPECT_NEAR(this->
parseNumber(
"12"), solver->getContinuousValue(x), this->precision());
666 ASSERT_NO_THROW(solver->optimize());
667 ASSERT_FALSE(solver->isOptimal());
668 ASSERT_TRUE(solver->isUnbounded());
669 ASSERT_FALSE(solver->isInfeasible());
672TYPED_TEST(LpSolverTest, IndicatorConstraintLeq) {
673 if (!this->supportsIndicator()) {
680 auto enforced = this->solveIndicatorScenario(storm::OptimizationDirection::Maximize,
true, std::optional<bool>(
true),
682 ASSERT_TRUE(enforced->isOptimal());
683 EXPECT_TRUE(enforced->getBinaryValue(b));
684 EXPECT_NEAR(this->
parseNumber(
"2"), enforced->getContinuousValue(x), this->precision());
687 auto relaxed = this->solveIndicatorScenario(storm::OptimizationDirection::Maximize,
true, std::optional<bool>(
false),
689 ASSERT_TRUE(relaxed->isOptimal());
690 EXPECT_FALSE(relaxed->getBinaryValue(b));
691 EXPECT_NEAR(this->
parseNumber(
"5"), relaxed->getContinuousValue(x), this->precision());
694TYPED_TEST(LpSolverTest, IndicatorConstraintLeqInactive) {
695 if (!this->supportsIndicator()) {
702 auto relaxed = this->solveIndicatorScenario(storm::OptimizationDirection::Maximize,
false, std::optional<bool>(
true),
704 ASSERT_TRUE(relaxed->isOptimal());
705 EXPECT_TRUE(relaxed->getBinaryValue(b));
706 EXPECT_NEAR(this->
parseNumber(
"5"), relaxed->getContinuousValue(x), this->precision());
709 auto enforced = this->solveIndicatorScenario(storm::OptimizationDirection::Maximize,
false, std::optional<bool>(
false),
711 ASSERT_TRUE(enforced->isOptimal());
712 EXPECT_FALSE(enforced->getBinaryValue(b));
713 EXPECT_NEAR(this->
parseNumber(
"2"), enforced->getContinuousValue(x), this->precision());
716TYPED_TEST(LpSolverTest, IndicatorConstraintGeq) {
717 if (!this->supportsIndicator()) {
724 auto enforced = this->solveIndicatorScenario(storm::OptimizationDirection::Minimize,
true, std::optional<bool>(
true),
726 ASSERT_TRUE(enforced->isOptimal());
727 EXPECT_TRUE(enforced->getBinaryValue(b));
728 EXPECT_NEAR(this->
parseNumber(
"3"), enforced->getContinuousValue(x), this->precision());
731 auto relaxed = this->solveIndicatorScenario(storm::OptimizationDirection::Minimize,
true, std::optional<bool>(
false),
733 ASSERT_TRUE(relaxed->isOptimal());
734 EXPECT_FALSE(relaxed->getBinaryValue(b));
735 EXPECT_NEAR(this->
parseNumber(
"0"), relaxed->getContinuousValue(x), this->precision());
738TYPED_TEST(LpSolverTest, IndicatorConstraintEq) {
739 if (!this->supportsIndicator()) {
746 auto enforcedMin = this->solveIndicatorScenario(storm::OptimizationDirection::Minimize,
true, std::optional<bool>(
true),
748 ASSERT_TRUE(enforcedMin->isOptimal());
749 EXPECT_TRUE(enforcedMin->getBinaryValue(b));
750 EXPECT_NEAR(this->
parseNumber(
"3"), enforcedMin->getContinuousValue(x), this->precision());
751 auto enforcedMax = this->solveIndicatorScenario(storm::OptimizationDirection::Maximize,
true, std::optional<bool>(
true),
753 ASSERT_TRUE(enforcedMax->isOptimal());
754 EXPECT_TRUE(enforcedMax->getBinaryValue(b));
755 EXPECT_NEAR(this->
parseNumber(
"3"), enforcedMax->getContinuousValue(x), this->precision());
758 auto relaxedMin = this->solveIndicatorScenario(storm::OptimizationDirection::Minimize,
true, std::optional<bool>(
false),
760 ASSERT_TRUE(relaxedMin->isOptimal());
761 EXPECT_FALSE(relaxedMin->getBinaryValue(b));
762 EXPECT_NEAR(this->
parseNumber(
"0"), relaxedMin->getContinuousValue(x), this->precision());
763 auto relaxedMax = this->solveIndicatorScenario(storm::OptimizationDirection::Maximize,
true, std::optional<bool>(
false),
765 ASSERT_TRUE(relaxedMax->isOptimal());
766 EXPECT_FALSE(relaxedMax->getBinaryValue(b));
767 EXPECT_NEAR(this->
parseNumber(
"5"), relaxedMax->getContinuousValue(x), this->precision());
SFTBDDChecker::ValueType ValueType
RelationType
An enum type specifying the different relations applicable.
NumberType parseNumber(std::string const &value)
Parse number from string.
std::unique_ptr< LpSolverFactory< ValueType > > getLpSolverFactory(storm::Environment const &env, storm::solver::LpSolverTypeSelection solvType)
TargetType convertNumber(SourceType const &number)
solver::OptimizationDirection OptimizationDirection
TYPED_TEST(GraphTestAR, SymbolicProb01StochasticGameDieSmall)
TYPED_TEST_SUITE(GraphTestAR, TestingTypes,)
::testing::Types< Cudd, Sylvan > TestingTypes
#define STORM_SILENT_ASSERT_THROW(statement, expected_exception)