You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

233 lines
16 KiB

  1. #include "gtest/gtest.h"
  2. #include "storm-config.h"
  3. #ifdef STORM_HAVE_GLPK
  4. #include "src/solver/GlpkLpSolver.h"
  5. #include "src/exceptions/InvalidStateException.h"
  6. #include "src/exceptions/InvalidAccessException.h"
  7. #include "src/settings/SettingsManager.h"
  8. TEST(GlpkLpSolver, LPOptimizeMax) {
  9. storm::solver::GlpkLpSolver solver(storm::solver::LpSolver::ModelSense::Maximize);
  10. ASSERT_NO_THROW(solver.addBoundedContinuousVariable("x", 0, 1, -1));
  11. ASSERT_NO_THROW(solver.addLowerBoundedContinuousVariable("y", 0, 2));
  12. ASSERT_NO_THROW(solver.addLowerBoundedContinuousVariable("z", 0, 1));
  13. ASSERT_NO_THROW(solver.update());
  14. solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("x") + storm::expressions::Expression::createDoubleVariable("y") + storm::expressions::Expression::createDoubleVariable("z") <= storm::expressions::Expression::createDoubleLiteral(12));
  15. ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("x") + storm::expressions::Expression::createDoubleVariable("y") + storm::expressions::Expression::createDoubleVariable("z") <= storm::expressions::Expression::createDoubleLiteral(12)));
  16. ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleLiteral(0.5) * storm::expressions::Expression::createDoubleVariable("y") + storm::expressions::Expression::createDoubleVariable("z") - storm::expressions::Expression::createDoubleVariable("x") == storm::expressions::Expression::createDoubleLiteral(5)));
  17. ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("y") - storm::expressions::Expression::createDoubleVariable("x") <= storm::expressions::Expression::createDoubleLiteral(5.5)));
  18. ASSERT_NO_THROW(solver.update());
  19. ASSERT_NO_THROW(solver.optimize());
  20. ASSERT_TRUE(solver.isOptimal());
  21. ASSERT_FALSE(solver.isUnbounded());
  22. ASSERT_FALSE(solver.isInfeasible());
  23. double xValue = 0;
  24. ASSERT_NO_THROW(xValue = solver.getContinuousValue("x"));
  25. ASSERT_LT(std::abs(xValue - 1), storm::settings::generalSettings().getPrecision());
  26. double yValue = 0;
  27. ASSERT_NO_THROW(yValue = solver.getContinuousValue("y"));
  28. ASSERT_LT(std::abs(yValue - 6.5), storm::settings::generalSettings().getPrecision());
  29. double zValue = 0;
  30. ASSERT_NO_THROW(zValue = solver.getContinuousValue("z"));
  31. ASSERT_LT(std::abs(zValue - 2.75), storm::settings::generalSettings().getPrecision());
  32. double objectiveValue = 0;
  33. ASSERT_NO_THROW(objectiveValue = solver.getObjectiveValue());
  34. ASSERT_LT(std::abs(objectiveValue - 14.75), storm::settings::generalSettings().getPrecision());
  35. }
  36. TEST(GlpkLpSolver, LPOptimizeMin) {
  37. storm::solver::GlpkLpSolver solver(storm::solver::LpSolver::ModelSense::Minimize);
  38. ASSERT_NO_THROW(solver.addBoundedContinuousVariable("x", 0, 1, -1));
  39. ASSERT_NO_THROW(solver.addLowerBoundedContinuousVariable("y", 0, 2));
  40. ASSERT_NO_THROW(solver.addBoundedContinuousVariable("z", 1, 5.7, -1));
  41. ASSERT_NO_THROW(solver.update());
  42. ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("x") + storm::expressions::Expression::createDoubleVariable("y") + storm::expressions::Expression::createDoubleVariable("z") <= storm::expressions::Expression::createDoubleLiteral(12)));
  43. ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleLiteral(0.5) * storm::expressions::Expression::createDoubleVariable("y") + storm::expressions::Expression::createDoubleVariable("z") - storm::expressions::Expression::createDoubleVariable("x") <= storm::expressions::Expression::createDoubleLiteral(5)));
  44. ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("y") - storm::expressions::Expression::createDoubleVariable("x") <= storm::expressions::Expression::createDoubleLiteral(5.5)));
  45. ASSERT_NO_THROW(solver.update());
  46. ASSERT_NO_THROW(solver.optimize());
  47. ASSERT_TRUE(solver.isOptimal());
  48. ASSERT_FALSE(solver.isUnbounded());
  49. ASSERT_FALSE(solver.isInfeasible());
  50. double xValue = 0;
  51. ASSERT_NO_THROW(xValue = solver.getContinuousValue("x"));
  52. ASSERT_LT(std::abs(xValue - 1), storm::settings::generalSettings().getPrecision());
  53. double yValue = 0;
  54. ASSERT_NO_THROW(yValue = solver.getContinuousValue("y"));
  55. ASSERT_LT(std::abs(yValue - 0), storm::settings::generalSettings().getPrecision());
  56. double zValue = 0;
  57. ASSERT_NO_THROW(zValue = solver.getContinuousValue("z"));
  58. ASSERT_LT(std::abs(zValue - 5.7), storm::settings::generalSettings().getPrecision());
  59. double objectiveValue = 0;
  60. ASSERT_NO_THROW(objectiveValue = solver.getObjectiveValue());
  61. ASSERT_LT(std::abs(objectiveValue - (-6.7)), storm::settings::generalSettings().getPrecision());
  62. }
  63. TEST(GlpkLpSolver, MILPOptimizeMax) {
  64. storm::solver::GlpkLpSolver solver(storm::solver::LpSolver::ModelSense::Maximize);
  65. ASSERT_NO_THROW(solver.addBinaryVariable("x", -1));
  66. ASSERT_NO_THROW(solver.addLowerBoundedIntegerVariable("y", 0, 2));
  67. ASSERT_NO_THROW(solver.addLowerBoundedContinuousVariable("z", 0, 1));
  68. ASSERT_NO_THROW(solver.update());
  69. ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("x") + storm::expressions::Expression::createDoubleVariable("y") + storm::expressions::Expression::createDoubleVariable("z") <= storm::expressions::Expression::createDoubleLiteral(12)));
  70. ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleLiteral(0.5) * storm::expressions::Expression::createDoubleVariable("y") + storm::expressions::Expression::createDoubleVariable("z") - storm::expressions::Expression::createDoubleVariable("x") == storm::expressions::Expression::createDoubleLiteral(5)));
  71. ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("y") - storm::expressions::Expression::createDoubleVariable("x") <= storm::expressions::Expression::createDoubleLiteral(5.5)));
  72. ASSERT_NO_THROW(solver.update());
  73. ASSERT_NO_THROW(solver.optimize());
  74. ASSERT_TRUE(solver.isOptimal());
  75. ASSERT_FALSE(solver.isUnbounded());
  76. ASSERT_FALSE(solver.isInfeasible());
  77. bool xValue = false;
  78. ASSERT_NO_THROW(xValue = solver.getBinaryValue("x"));
  79. ASSERT_EQ(true, xValue);
  80. int_fast64_t yValue = 0;
  81. ASSERT_NO_THROW(yValue = solver.getIntegerValue("y"));
  82. ASSERT_EQ(6, yValue);
  83. double zValue = 0;
  84. ASSERT_NO_THROW(zValue = solver.getContinuousValue("z"));
  85. ASSERT_LT(std::abs(zValue - 3), storm::settings::generalSettings().getPrecision());
  86. double objectiveValue = 0;
  87. ASSERT_NO_THROW(objectiveValue = solver.getObjectiveValue());
  88. ASSERT_LT(std::abs(objectiveValue - 14), storm::settings::generalSettings().getPrecision());
  89. }
  90. TEST(GlpkLpSolver, MILPOptimizeMin) {
  91. storm::solver::GlpkLpSolver solver(storm::solver::LpSolver::ModelSense::Minimize);
  92. ASSERT_NO_THROW(solver.addBinaryVariable("x", -1));
  93. ASSERT_NO_THROW(solver.addLowerBoundedIntegerVariable("y", 0, 2));
  94. ASSERT_NO_THROW(solver.addBoundedContinuousVariable("z", 0, 5, -1));
  95. ASSERT_NO_THROW(solver.update());
  96. ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("x") + storm::expressions::Expression::createDoubleVariable("y") + storm::expressions::Expression::createDoubleVariable("z") <= storm::expressions::Expression::createDoubleLiteral(12)));
  97. ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleLiteral(0.5) * storm::expressions::Expression::createDoubleVariable("y") + storm::expressions::Expression::createDoubleVariable("z") - storm::expressions::Expression::createDoubleVariable("x") <= storm::expressions::Expression::createDoubleLiteral(5)));
  98. ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("y") - storm::expressions::Expression::createDoubleVariable("x") <= storm::expressions::Expression::createDoubleLiteral(5.5)));
  99. ASSERT_NO_THROW(solver.update());
  100. ASSERT_NO_THROW(solver.optimize());
  101. ASSERT_TRUE(solver.isOptimal());
  102. ASSERT_FALSE(solver.isUnbounded());
  103. ASSERT_FALSE(solver.isInfeasible());
  104. bool xValue = false;
  105. ASSERT_NO_THROW(xValue = solver.getBinaryValue("x"));
  106. ASSERT_EQ(true, xValue);
  107. int_fast64_t yValue = 0;
  108. ASSERT_NO_THROW(yValue = solver.getIntegerValue("y"));
  109. ASSERT_EQ(0, yValue);
  110. double zValue = 0;
  111. ASSERT_NO_THROW(zValue = solver.getContinuousValue("z"));
  112. ASSERT_LT(std::abs(zValue - 5), storm::settings::generalSettings().getPrecision());
  113. double objectiveValue = 0;
  114. ASSERT_NO_THROW(objectiveValue = solver.getObjectiveValue());
  115. ASSERT_LT(std::abs(objectiveValue - (-6)), storm::settings::generalSettings().getPrecision());
  116. }
  117. TEST(GlpkLpSolver, LPInfeasible) {
  118. storm::solver::GlpkLpSolver solver(storm::solver::LpSolver::ModelSense::Maximize);
  119. ASSERT_NO_THROW(solver.addBoundedContinuousVariable("x", 0, 1, -1));
  120. ASSERT_NO_THROW(solver.addLowerBoundedContinuousVariable("y", 0, 2));
  121. ASSERT_NO_THROW(solver.addLowerBoundedContinuousVariable("z", 0, 1));
  122. ASSERT_NO_THROW(solver.update());
  123. ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("x") + storm::expressions::Expression::createDoubleVariable("y") + storm::expressions::Expression::createDoubleVariable("z") <= storm::expressions::Expression::createDoubleLiteral(12)));
  124. ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleLiteral(0.5) * storm::expressions::Expression::createDoubleVariable("y") + storm::expressions::Expression::createDoubleVariable("z") - storm::expressions::Expression::createDoubleVariable("x") == storm::expressions::Expression::createDoubleLiteral(5)));
  125. ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("y") - storm::expressions::Expression::createDoubleVariable("x") <= storm::expressions::Expression::createDoubleLiteral(5.5)));
  126. ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("y") > storm::expressions::Expression::createDoubleLiteral(7)));
  127. ASSERT_NO_THROW(solver.update());
  128. ASSERT_NO_THROW(solver.optimize());
  129. ASSERT_FALSE(solver.isOptimal());
  130. ASSERT_FALSE(solver.isUnbounded());
  131. ASSERT_TRUE(solver.isInfeasible());
  132. double xValue = 0;
  133. ASSERT_THROW(xValue = solver.getContinuousValue("x"), storm::exceptions::InvalidAccessException);
  134. double yValue = 0;
  135. ASSERT_THROW(yValue = solver.getContinuousValue("y"), storm::exceptions::InvalidAccessException);
  136. double zValue = 0;
  137. ASSERT_THROW(zValue = solver.getContinuousValue("z"), storm::exceptions::InvalidAccessException);
  138. double objectiveValue = 0;
  139. ASSERT_THROW(objectiveValue = solver.getObjectiveValue(), storm::exceptions::InvalidAccessException);
  140. }
  141. TEST(GlpkLpSolver, MILPInfeasible) {
  142. storm::solver::GlpkLpSolver solver(storm::solver::LpSolver::ModelSense::Maximize);
  143. ASSERT_NO_THROW(solver.addBinaryVariable("x", -1));
  144. ASSERT_NO_THROW(solver.addLowerBoundedContinuousVariable("y", 0, 2));
  145. ASSERT_NO_THROW(solver.addLowerBoundedContinuousVariable("z", 0, 1));
  146. ASSERT_NO_THROW(solver.update());
  147. ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("x") + storm::expressions::Expression::createDoubleVariable("y") + storm::expressions::Expression::createDoubleVariable("z") <= storm::expressions::Expression::createDoubleLiteral(12)));
  148. ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleLiteral(0.5) * storm::expressions::Expression::createDoubleVariable("y") + storm::expressions::Expression::createDoubleVariable("z") - storm::expressions::Expression::createDoubleVariable("x") == storm::expressions::Expression::createDoubleLiteral(5)));
  149. ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("y") - storm::expressions::Expression::createDoubleVariable("x") <= storm::expressions::Expression::createDoubleLiteral(5.5)));
  150. ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("y") > storm::expressions::Expression::createDoubleLiteral(7)));
  151. ASSERT_NO_THROW(solver.update());
  152. ASSERT_NO_THROW(solver.optimize());
  153. ASSERT_FALSE(solver.isOptimal());
  154. ASSERT_FALSE(solver.isUnbounded());
  155. ASSERT_TRUE(solver.isInfeasible());
  156. bool xValue = false;
  157. ASSERT_THROW(xValue = solver.getBinaryValue("x"), storm::exceptions::InvalidAccessException);
  158. int_fast64_t yValue = 0;
  159. ASSERT_THROW(yValue = solver.getIntegerValue("y"), storm::exceptions::InvalidAccessException);
  160. double zValue = 0;
  161. ASSERT_THROW(zValue = solver.getContinuousValue("z"), storm::exceptions::InvalidAccessException);
  162. double objectiveValue = 0;
  163. ASSERT_THROW(objectiveValue = solver.getObjectiveValue(), storm::exceptions::InvalidAccessException);
  164. }
  165. TEST(GlpkLpSolver, LPUnbounded) {
  166. storm::solver::GlpkLpSolver solver(storm::solver::LpSolver::ModelSense::Maximize);
  167. ASSERT_NO_THROW(solver.addBoundedContinuousVariable("x", 0, 1, -1));
  168. ASSERT_NO_THROW(solver.addLowerBoundedContinuousVariable("y", 0, 2));
  169. ASSERT_NO_THROW(solver.addLowerBoundedContinuousVariable("z", 0, 1));
  170. ASSERT_NO_THROW(solver.update());
  171. ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("x") + storm::expressions::Expression::createDoubleVariable("y") - storm::expressions::Expression::createDoubleVariable("z") <= storm::expressions::Expression::createDoubleLiteral(12)));
  172. ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("y") - storm::expressions::Expression::createDoubleVariable("x") <= storm::expressions::Expression::createDoubleLiteral(5.5)));
  173. ASSERT_NO_THROW(solver.update());
  174. ASSERT_NO_THROW(solver.optimize());
  175. ASSERT_FALSE(solver.isOptimal());
  176. ASSERT_TRUE(solver.isUnbounded());
  177. ASSERT_FALSE(solver.isInfeasible());
  178. double xValue = 0;
  179. ASSERT_THROW(xValue = solver.getContinuousValue("x"), storm::exceptions::InvalidAccessException);
  180. double yValue = 0;
  181. ASSERT_THROW(yValue = solver.getContinuousValue("y"), storm::exceptions::InvalidAccessException);
  182. double zValue = 0;
  183. ASSERT_THROW(zValue = solver.getContinuousValue("z"), storm::exceptions::InvalidAccessException);
  184. double objectiveValue = 0;
  185. ASSERT_THROW(objectiveValue = solver.getObjectiveValue(), storm::exceptions::InvalidAccessException);
  186. }
  187. TEST(GlpkLpSolver, MILPUnbounded) {
  188. storm::solver::GlpkLpSolver solver(storm::solver::LpSolver::ModelSense::Maximize);
  189. ASSERT_NO_THROW(solver.addBinaryVariable("x", -1));
  190. ASSERT_NO_THROW(solver.addLowerBoundedContinuousVariable("y", 0, 2));
  191. ASSERT_NO_THROW(solver.addLowerBoundedContinuousVariable("z", 0, 1));
  192. ASSERT_NO_THROW(solver.update());
  193. ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("x") + storm::expressions::Expression::createDoubleVariable("y") - storm::expressions::Expression::createDoubleVariable("z") <= storm::expressions::Expression::createDoubleLiteral(12)));
  194. ASSERT_NO_THROW(solver.addConstraint("", storm::expressions::Expression::createDoubleVariable("y") - storm::expressions::Expression::createDoubleVariable("x") <= storm::expressions::Expression::createDoubleLiteral(5.5)));
  195. ASSERT_NO_THROW(solver.update());
  196. ASSERT_NO_THROW(solver.optimize());
  197. ASSERT_FALSE(solver.isOptimal());
  198. ASSERT_TRUE(solver.isUnbounded());
  199. ASSERT_FALSE(solver.isInfeasible());
  200. bool xValue = false;
  201. ASSERT_THROW(xValue = solver.getBinaryValue("x"), storm::exceptions::InvalidAccessException);
  202. int_fast64_t yValue = 0;
  203. ASSERT_THROW(yValue = solver.getIntegerValue("y"), storm::exceptions::InvalidAccessException);
  204. double zValue = 0;
  205. ASSERT_THROW(zValue = solver.getContinuousValue("z"), storm::exceptions::InvalidAccessException);
  206. double objectiveValue = 0;
  207. ASSERT_THROW(objectiveValue = solver.getObjectiveValue(), storm::exceptions::InvalidAccessException);
  208. }
  209. #endif