Java Reference

Java Reference

LinearSolverTest.java
Go to the documentation of this file.
1 // Copyright 2010-2022 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 package com.google.ortools.linearsolver;
15 
16 import static com.google.common.truth.Truth.assertThat;
17 import static org.junit.jupiter.api.Assertions.assertEquals;
18 import static org.junit.jupiter.api.Assertions.assertFalse;
19 import static org.junit.jupiter.api.Assertions.assertNotNull;
20 import static org.junit.jupiter.api.Assertions.assertTrue;
21 
22 import com.google.ortools.Loader;
23 import com.google.ortools.linearsolver.MPConstraintProto;
24 import com.google.ortools.linearsolver.MPModelProto;
25 import com.google.ortools.linearsolver.MPModelRequest;
26 import com.google.ortools.linearsolver.MPSolutionResponse;
27 import com.google.ortools.linearsolver.MPSolverResponseStatus;
28 import com.google.ortools.linearsolver.MPVariableProto;
29 import com.google.ortools.linearsolver.PartialVariableAssignment;
30 import org.junit.jupiter.api.BeforeEach;
31 import org.junit.jupiter.api.Test;
32 
34 public final class LinearSolverTest {
35  // Numerical tolerance for checking primal, dual, objective values
36  // and other values.
37  private static final double NUM_TOLERANCE = 1e-5;
38 
39  @BeforeEach
40  public void setUp() {
42  }
43 
44  private void runBasicCtor(MPSolver.OptimizationProblemType solverType) {
45  if (!MPSolver.supportsProblemType(solverType)) {
46  return;
47  }
48  final MPSolver solver = new MPSolver("testBasicCtor", solverType);
49  assertNotNull(solver);
50  solver.solve();
51  }
52 
53  @Test
54  public void testMPSolver_basicCtor() {
55  runBasicCtor(MPSolver.OptimizationProblemType.GLOP_LINEAR_PROGRAMMING);
56  runBasicCtor(MPSolver.OptimizationProblemType.GLPK_LINEAR_PROGRAMMING);
57  runBasicCtor(MPSolver.OptimizationProblemType.GLPK_MIXED_INTEGER_PROGRAMMING);
58  runBasicCtor(MPSolver.OptimizationProblemType.CLP_LINEAR_PROGRAMMING);
59  runBasicCtor(MPSolver.OptimizationProblemType.CBC_MIXED_INTEGER_PROGRAMMING);
60  }
61 
62  @Test
63  public void testMPSolver_destructor() {
64  final MPSolver solver =
65  new MPSolver("testDestructor", MPSolver.OptimizationProblemType.GLOP_LINEAR_PROGRAMMING);
66  assertNotNull(solver);
67  solver.delete();
68  }
69 
70  private void runLinearSolver(
71  MPSolver.OptimizationProblemType problemType, boolean integerVariables) {
72  if (!MPSolver.supportsProblemType(problemType)) {
73  return;
74  }
75  final MPSolver solver = new MPSolver("Solver", problemType);
76  assertNotNull(solver);
77 
78  final double infinity = MPSolver.infinity();
79  final MPVariable x1 = solver.makeNumVar(0.0, infinity, "x1");
80  final MPVariable x2 = solver.makeNumVar(0.0, infinity, "x2");
81  final MPVariable x3 = solver.makeNumVar(0.0, infinity, "x3");
82  if (integerVariables) {
83  x1.setInteger(true);
84  x2.setInteger(true);
85  x3.setInteger(true);
86  }
87  assertEquals(3, solver.numVariables());
88 
89  final MPObjective objective = solver.objective();
90  objective.setCoefficient(x1, 10);
91  objective.setCoefficient(x2, 6);
92  objective.setCoefficient(x3, 4);
93  objective.setMaximization();
94  assertEquals(6.0, objective.getCoefficient(x2), 1e-6);
95  assertTrue(objective.maximization());
96  assertFalse(objective.minimization());
97 
98  final MPConstraint c0 = solver.makeConstraint(-1000, 100.0);
99  c0.setCoefficient(x1, 1);
100  c0.setCoefficient(x2, 1);
101  c0.setCoefficient(x3, 1);
102 
103  final MPConstraint c1 = solver.makeConstraint(-1000, 600.0);
104  c1.setCoefficient(x1, 10);
105  c1.setCoefficient(x2, 4);
106  c1.setCoefficient(x3, 5);
107  assertEquals(4.0, c1.getCoefficient(x2), 1e-6);
108 
109  final MPConstraint c2 = solver.makeConstraint(-1000, 300.0);
110  c2.setCoefficient(x1, 2);
111  c2.setCoefficient(x2, 2);
112  c2.setCoefficient(x3, 6);
113 
114  assertEquals(MPSolver.ResultStatus.OPTIMAL, solver.solve());
115  if (integerVariables) {
116  assertEquals(732.0, objective.value(), NUM_TOLERANCE);
117  assertEquals(33.0, x1.solutionValue(), NUM_TOLERANCE);
118  assertEquals(67.0, x2.solutionValue(), NUM_TOLERANCE);
119  assertEquals(0.0, x3.solutionValue(), NUM_TOLERANCE);
120  } else {
121  assertEquals(733.333333, objective.value(), NUM_TOLERANCE);
122  assertEquals(33.333333, x1.solutionValue(), NUM_TOLERANCE);
123  assertEquals(66.666667, x2.solutionValue(), NUM_TOLERANCE);
124  assertEquals(0, x3.solutionValue(), NUM_TOLERANCE);
125  }
126  }
127 
128  @Test
130  runLinearSolver(MPSolver.OptimizationProblemType.GLOP_LINEAR_PROGRAMMING, false);
131  runLinearSolver(MPSolver.OptimizationProblemType.CLP_LINEAR_PROGRAMMING, false);
132  runLinearSolver(MPSolver.OptimizationProblemType.GLPK_LINEAR_PROGRAMMING, false);
133 
134  runLinearSolver(MPSolver.OptimizationProblemType.CBC_MIXED_INTEGER_PROGRAMMING, true);
135  runLinearSolver(MPSolver.OptimizationProblemType.GLPK_MIXED_INTEGER_PROGRAMMING, true);
136  runLinearSolver(MPSolver.OptimizationProblemType.SCIP_MIXED_INTEGER_PROGRAMMING, true);
137  }
138 
139  private void runFirstLinearExample(MPSolver.OptimizationProblemType problemType) {
140  if (!MPSolver.supportsProblemType(problemType)) {
141  return;
142  }
143  final MPSolver solver = new MPSolver("Solver", problemType);
144  assertNotNull(solver);
145 
146  final MPVariable x1 = solver.makeNumVar(0.0, Double.POSITIVE_INFINITY, "x1");
147  final MPVariable x2 = solver.makeNumVar(0.0, Double.POSITIVE_INFINITY, "x2");
148  final MPVariable x3 = solver.makeNumVar(0.0, Double.POSITIVE_INFINITY, "x3");
149  assertEquals(3, solver.numVariables());
150 
151  final double[] obj = {10.0, 6.0, 4.0};
152  final MPObjective objective = solver.objective();
153  objective.setCoefficient(x1, obj[0]);
154  objective.setCoefficient(x2, obj[1]);
155  objective.setCoefficient(x3, obj[2]);
156  objective.setMaximization();
157 
158  final double rhs0 = 100.0;
159  final MPConstraint c0 = solver.makeConstraint(-Double.POSITIVE_INFINITY, rhs0, "c0");
160  final double[] coef0 = {1.0, 1.0, 1.0};
161  c0.setCoefficient(x1, coef0[0]);
162  c0.setCoefficient(x2, coef0[1]);
163  c0.setCoefficient(x3, coef0[2]);
164  final double rhs1 = 600.0;
165  final MPConstraint c1 = solver.makeConstraint(-Double.POSITIVE_INFINITY, rhs1, "c1");
166  final double[] coef1 = {10.0, 4.0, 5.0};
167  c1.setCoefficient(x1, coef1[0]);
168  c1.setCoefficient(x2, coef1[1]);
169  c1.setCoefficient(x3, coef1[2]);
170  final double rhs2 = 300.0;
171  final MPConstraint c2 = solver.makeConstraint(-Double.POSITIVE_INFINITY, rhs2);
172  final double[] coef2 = {2.0, 2.0, 6.0};
173  c2.setCoefficient(x1, coef2[0]);
174  c2.setCoefficient(x2, coef2[1]);
175  c2.setCoefficient(x3, coef2[2]);
176  assertEquals(3, solver.numConstraints());
177  assertEquals("c0", c0.name());
178  assertEquals("c1", c1.name());
179  assertEquals("auto_c_000000002", c2.name());
180 
181  // The problem has an optimal solution.;
182  assertEquals(MPSolver.ResultStatus.OPTIMAL, solver.solve());
183 
184  assertEquals(733.333333, objective.value(), NUM_TOLERANCE);
185  assertEquals(33.333333, x1.solutionValue(), NUM_TOLERANCE);
186  assertEquals(66.666667, x2.solutionValue(), NUM_TOLERANCE);
187  assertEquals(0, x3.solutionValue(), NUM_TOLERANCE);
188 
189  // c0 and c1 are binding;
190  final double[] activities = solver.computeConstraintActivities();
191  assertEquals(3, activities.length);
192  assertEquals(3.333333, c0.dualValue(), NUM_TOLERANCE);
193  assertEquals(0.666667, c1.dualValue(), NUM_TOLERANCE);
194  assertEquals(rhs0, activities[c0.index()], NUM_TOLERANCE);
195  assertEquals(rhs1, activities[c1.index()], NUM_TOLERANCE);
196  assertEquals(MPSolver.BasisStatus.AT_UPPER_BOUND, c0.basisStatus());
197  assertEquals(MPSolver.BasisStatus.AT_UPPER_BOUND, c1.basisStatus());
198  // c2 is not binding;
199  assertEquals(0.0, c2.dualValue(), NUM_TOLERANCE);
200  assertEquals(200.0, activities[c2.index()], NUM_TOLERANCE);
201  assertEquals(MPSolver.BasisStatus.BASIC, c2.basisStatus());
202  // The optimum of the dual problem is equal to the optimum of the;
203  // primal problem.;
204  final double dualObjectiveValue = c0.dualValue() * rhs0 + c1.dualValue() * rhs1;
205  assertEquals(objective.value(), dualObjectiveValue, NUM_TOLERANCE);
206 
207  // x1 and x2 are basic;
208  assertEquals(0.0, x1.reducedCost(), NUM_TOLERANCE);
209  assertEquals(0.0, x2.reducedCost(), NUM_TOLERANCE);
210  assertEquals(MPSolver.BasisStatus.BASIC, x1.basisStatus());
211  assertEquals(MPSolver.BasisStatus.BASIC, x2.basisStatus());
212  // x3 is non-basic;
213  final double x3ExpectedReducedCost =
214  (obj[2] - coef0[2] * c0.dualValue() - coef1[2] * c1.dualValue());
215  assertEquals(x3ExpectedReducedCost, x3.reducedCost(), NUM_TOLERANCE);
216  assertEquals(MPSolver.BasisStatus.AT_LOWER_BOUND, x3.basisStatus());
217 
218  if (solver.problemType() == MPSolver.OptimizationProblemType.GLPK_LINEAR_PROGRAMMING) {
219  assertEquals(56.333333, solver.computeExactConditionNumber(), NUM_TOLERANCE);
220  }
221  }
222 
223  @Test
225  runFirstLinearExample(MPSolver.OptimizationProblemType.GLOP_LINEAR_PROGRAMMING);
226  runFirstLinearExample(MPSolver.OptimizationProblemType.CLP_LINEAR_PROGRAMMING);
227  runFirstLinearExample(MPSolver.OptimizationProblemType.GLPK_LINEAR_PROGRAMMING);
228  runFirstLinearExample(MPSolver.OptimizationProblemType.GUROBI_LINEAR_PROGRAMMING);
229  }
230 
231  private void runFirstMIPExample(MPSolver.OptimizationProblemType problemType) {
232  if (!MPSolver.supportsProblemType(problemType)) {
233  return;
234  }
235  final MPSolver solver = new MPSolver("Solver", problemType);
236  assertNotNull(solver);
237 
238  // Integer variables shouldn't have infinite bounds, nor really large bounds:
239  // it can make your solver behave erratically. If you have integer variables
240  // with a truly large dynamic range you should consider making it non-integer.
241  final double upperBound = 1000;
242  final MPVariable x1 = solver.makeIntVar(0.0, upperBound, "x1");
243  final MPVariable x2 = solver.makeIntVar(0.0, upperBound, "x2");
244 
245  solver.objective().setCoefficient(x1, 1);
246  solver.objective().setCoefficient(x2, 2);
247 
248  final MPConstraint ct = solver.makeConstraint(17, Double.POSITIVE_INFINITY);
249  ct.setCoefficient(x1, 3);
250  ct.setCoefficient(x2, 2);
251 
252  // Check the solution.
253  assertEquals(MPSolver.ResultStatus.OPTIMAL, solver.solve());
254  final double optObjValue = 6.0;
255  assertEquals(optObjValue, solver.objective().value(), 1e-6);
256  assertEquals(optObjValue, solver.objective().bestBound(), 1e-6);
257  final double optRowActivity = 18.0;
258  assertEquals(optRowActivity, solver.computeConstraintActivities()[ct.index()], NUM_TOLERANCE);
259  // BOP does not support nodes().
260  if (solver.problemType() != MPSolver.OptimizationProblemType.BOP_INTEGER_PROGRAMMING) {
261  assertThat(solver.nodes()).isAtLeast(0);
262  }
263  }
264 
265  @Test
267  runFirstMIPExample(MPSolver.OptimizationProblemType.BOP_INTEGER_PROGRAMMING);
268  runFirstMIPExample(MPSolver.OptimizationProblemType.CBC_MIXED_INTEGER_PROGRAMMING);
269  runFirstMIPExample(MPSolver.OptimizationProblemType.GLPK_MIXED_INTEGER_PROGRAMMING);
270  runFirstMIPExample(MPSolver.OptimizationProblemType.SCIP_MIXED_INTEGER_PROGRAMMING);
271  runFirstMIPExample(MPSolver.OptimizationProblemType.SAT_INTEGER_PROGRAMMING);
272  runFirstMIPExample(MPSolver.OptimizationProblemType.GUROBI_MIXED_INTEGER_PROGRAMMING);
273  }
274 
275  private void runSuccessiveObjectives(MPSolver.OptimizationProblemType problemType) {
276  if (!MPSolver.supportsProblemType(problemType)) {
277  return;
278  }
279  final MPSolver solver = new MPSolver("Solver", problemType);
280  assertNotNull(solver);
281 
282  final MPVariable x1 = solver.makeNumVar(0, 10, "var1");
283  final MPVariable x2 = solver.makeNumVar(0, 10, "var2");
284  final MPConstraint ct = solver.makeConstraint(0, 10);
285  ct.setCoefficient(x1, 1);
286  ct.setCoefficient(x2, 2);
287 
288  final MPObjective objective = solver.objective();
289  objective.setCoefficient(x1, 1);
290  objective.setCoefficient(x2, 0);
291  objective.setOptimizationDirection(true);
292 
293  // Check the solution.
294  assertEquals(MPSolver.ResultStatus.OPTIMAL, solver.solve());
295  assertEquals(10.0, x1.solutionValue(), NUM_TOLERANCE);
296  assertEquals(0.0, x2.solutionValue(), NUM_TOLERANCE);
297 
298  objective.setCoefficient(x1, 0);
299  objective.setCoefficient(x2, 1);
300  objective.setOptimizationDirection(true);
301 
302  // Check the solution
303  assertEquals(MPSolver.ResultStatus.OPTIMAL, solver.solve());
304  assertEquals(0.0, x1.solutionValue(), NUM_TOLERANCE);
305  assertEquals(5.0, x2.solutionValue(), NUM_TOLERANCE);
306 
307  objective.setCoefficient(x1, -1);
308  objective.setCoefficient(x2, 0);
309  objective.setOptimizationDirection(false);
310 
311  // Check the solution.
312  assertEquals(MPSolver.ResultStatus.OPTIMAL, solver.solve());
313  assertEquals(10.0, x1.solutionValue(), NUM_TOLERANCE);
314  assertEquals(0.0, x2.solutionValue(), NUM_TOLERANCE);
315  }
316 
317  @Test
319  runSuccessiveObjectives(MPSolver.OptimizationProblemType.GLOP_LINEAR_PROGRAMMING);
320  runSuccessiveObjectives(MPSolver.OptimizationProblemType.CLP_LINEAR_PROGRAMMING);
321  runSuccessiveObjectives(MPSolver.OptimizationProblemType.GLPK_LINEAR_PROGRAMMING);
322  runSuccessiveObjectives(MPSolver.OptimizationProblemType.GUROBI_LINEAR_PROGRAMMING);
323 
324  runSuccessiveObjectives(MPSolver.OptimizationProblemType.CBC_MIXED_INTEGER_PROGRAMMING);
325  runSuccessiveObjectives(MPSolver.OptimizationProblemType.GLPK_MIXED_INTEGER_PROGRAMMING);
326  runSuccessiveObjectives(MPSolver.OptimizationProblemType.SCIP_MIXED_INTEGER_PROGRAMMING);
327  runSuccessiveObjectives(MPSolver.OptimizationProblemType.SAT_INTEGER_PROGRAMMING);
328  runSuccessiveObjectives(MPSolver.OptimizationProblemType.GUROBI_MIXED_INTEGER_PROGRAMMING);
329  }
330 
331  private void runObjectiveOffset(MPSolver.OptimizationProblemType problemType) {
332  if (!MPSolver.supportsProblemType(problemType)) {
333  return;
334  }
335  final MPSolver solver = new MPSolver("Solver", problemType);
336  assertNotNull(solver);
337 
338  final MPVariable x1 = solver.makeIntVar(1.0, 10.0, "x1");
339  final MPVariable x2 = solver.makeIntVar(1.0, 10.0, "x2");
340 
341  final MPConstraint ct = solver.makeConstraint(0, 4.0);
342  ct.setCoefficient(x1, 1);
343  ct.setCoefficient(x2, 2);
344 
345  final double objectiveOffset = 10.0;
346  // Simple minimization.
347  final MPObjective objective = solver.objective();
348  objective.setCoefficient(x1, 1.0);
349  objective.setCoefficient(x2, 1.0);
350  objective.setOffset(objectiveOffset);
351  objective.setOptimizationDirection(false);
352 
353  assertEquals(MPSolver.ResultStatus.OPTIMAL, solver.solve());
354  assertEquals(2.0 + objectiveOffset, objective.value(), 1e-6);
355 
356  // Offset is provided in several separate constants.
357  objective.setCoefficient(x1, 1.0);
358  objective.setCoefficient(x2, 1.0);
359  objective.setOffset(-1.0);
360  objective.setOffset(objectiveOffset + objective.offset());
361  objective.setOffset(1.0 + objective.offset());
362  assertEquals(MPSolver.ResultStatus.OPTIMAL, solver.solve());
363  assertEquals(2.0 + objectiveOffset, objective.value(), 1e-6);
364 
365  // Simple maximization.
366  objective.setCoefficient(x1, 1.0);
367  objective.setCoefficient(x2, 1.0);
368  objective.setOffset(objectiveOffset);
369  objective.setOptimizationDirection(true);
370  assertEquals(MPSolver.ResultStatus.OPTIMAL, solver.solve());
371  assertEquals(3.0 + objectiveOffset, objective.value(), 1e-6);
372  }
373 
374  @Test
376  runObjectiveOffset(MPSolver.OptimizationProblemType.GLOP_LINEAR_PROGRAMMING);
377  runObjectiveOffset(MPSolver.OptimizationProblemType.CLP_LINEAR_PROGRAMMING);
378  runObjectiveOffset(MPSolver.OptimizationProblemType.GLPK_LINEAR_PROGRAMMING);
379  runObjectiveOffset(MPSolver.OptimizationProblemType.GUROBI_LINEAR_PROGRAMMING);
380 
381  runObjectiveOffset(MPSolver.OptimizationProblemType.CBC_MIXED_INTEGER_PROGRAMMING);
382  runObjectiveOffset(MPSolver.OptimizationProblemType.GLPK_MIXED_INTEGER_PROGRAMMING);
383  runObjectiveOffset(MPSolver.OptimizationProblemType.SCIP_MIXED_INTEGER_PROGRAMMING);
384  runObjectiveOffset(MPSolver.OptimizationProblemType.SAT_INTEGER_PROGRAMMING);
385  runObjectiveOffset(MPSolver.OptimizationProblemType.GUROBI_MIXED_INTEGER_PROGRAMMING);
386  }
387 
388  @Test
390  final MPSolver.OptimizationProblemType problemType =
391  MPSolver.OptimizationProblemType.SCIP_MIXED_INTEGER_PROGRAMMING;
392  if (!MPSolver.supportsProblemType(problemType)) {
393  return;
394  }
395  final MPSolver solver = new MPSolver("testLazyConstraints", problemType);
396  assertNotNull(solver);
397 
398  final double infinity = MPSolver.infinity();
399  final MPVariable x = solver.makeIntVar(0, infinity, "x");
400  final MPVariable y = solver.makeIntVar(0, infinity, "y");
401  final MPConstraint ct1 = solver.makeConstraint(0, 10.0);
402  ct1.setCoefficient(x, 2.0);
403  ct1.setCoefficient(y, 1.0);
404  final MPConstraint ct2 = solver.makeConstraint(0, 10.0);
405  ct2.setCoefficient(x, 1.0);
406  ct2.setCoefficient(y, 2.0);
407  ct2.setIsLazy(true);
408  assertFalse(ct1.isLazy());
409  assertTrue(ct2.isLazy());
410  final MPObjective objective = solver.objective();
411  objective.setCoefficient(x, 1.0);
412  objective.setCoefficient(y, 1.0);
413  objective.setOptimizationDirection(true);
414  assertEquals(MPSolver.ResultStatus.OPTIMAL, solver.solve());
415  assertEquals(solver.objective().value(), 6.0, NUM_TOLERANCE);
416  }
417 
418  @Test
420  MPSolver solver = MPSolver.createSolver("GLOP");
421  assertNotNull(solver);
422  boolean success = true;
423  solver.makeConstraint("my_const_name");
424  try {
425  solver.makeConstraint("my_const_name");
426  } catch (Throwable e) {
427  System.out.println(e);
428  success = false;
429  }
430  assertTrue(success);
431  }
432  @Test
434  final MPSolver.OptimizationProblemType problemType =
435  MPSolver.OptimizationProblemType.GLOP_LINEAR_PROGRAMMING;
436  if (!MPSolver.supportsProblemType(problemType)) {
437  return;
438  }
439  final MPSolver solver = new MPSolver("testExportModelToProto", problemType);
440  assertNotNull(solver);
441  solver.makeNumVar(0.0, 10.0, "x1");
442  solver.makeConstraint(0.0, 0.0);
443  solver.objective().setOptimizationDirection(true);
444  final MPModelProto model = solver.exportModelToProto();
445  assertEquals(1, model.getVariableCount());
446  assertEquals(1, model.getConstraintCount());
447  assertTrue(model.getMaximize());
448  }
449 
450  @Test
452  final MPSolver.OptimizationProblemType problemType =
453  MPSolver.OptimizationProblemType.GLOP_LINEAR_PROGRAMMING;
454  if (!MPSolver.supportsProblemType(problemType)) {
455  return;
456  }
457  final MPSolver solver = new MPSolver("testCreateSolutionResponseProto", problemType);
458  assertNotNull(solver);
459  final MPVariable x1 = solver.makeNumVar(0.0, 10.0, "x1");
460  solver.objective().setCoefficient(x1, 1.0);
461  solver.objective().setOptimizationDirection(true);
462  solver.solve();
463  final MPSolutionResponse response = solver.createSolutionResponseProto();
464  assertEquals(MPSolverResponseStatus.MPSOLVER_OPTIMAL, response.getStatus());
465  assertEquals(10.0, response.getObjectiveValue(), 1e-6);
466  }
467 
468  @Test
470  final MPSolver.OptimizationProblemType problemType =
471  MPSolver.OptimizationProblemType.GLOP_LINEAR_PROGRAMMING;
472  if (!MPSolver.supportsProblemType(problemType)) {
473  return;
474  }
475  final MPModelProto.Builder modelBuilder = MPModelProto.newBuilder().setMaximize(true);
476  final MPVariableProto variable = MPVariableProto.newBuilder()
477  .setLowerBound(0.0)
478  .setUpperBound(10.0)
479  .setName("x1")
480  .setIsInteger(false)
481  .setObjectiveCoefficient(1.0)
482  .build();
483  modelBuilder.addVariable(variable);
484  final MPModelRequest request =
485  MPModelRequest.newBuilder()
486  .setModel(modelBuilder.build())
487  .setSolverType(MPModelRequest.SolverType.GLOP_LINEAR_PROGRAMMING)
488  .build();
489  final MPSolutionResponse response = MPSolver.solveWithProto(request);
490  assertEquals(MPSolverResponseStatus.MPSOLVER_OPTIMAL, response.getStatus());
491  assertEquals(10.0, response.getObjectiveValue(), 1e-6);
492  }
493 
494  @Test
495  public void testModelExport() {
496  final MPSolver.OptimizationProblemType problemType =
497  MPSolver.OptimizationProblemType.GLOP_LINEAR_PROGRAMMING;
498  if (!MPSolver.supportsProblemType(problemType)) {
499  return;
500  }
501  final MPSolver solver = new MPSolver("tesModelExport", problemType);
502  assertNotNull(solver);
503  final double infinity = MPSolver.infinity();
504  // x1, x2 and x3 are continuous non-negative variables.
505  final MPVariable x1 = solver.makeNumVar(0.0, infinity, "x1");
506 
507  // Maximize 10 * x1.
508  solver.objective().setCoefficient(x1, 10);
509  solver.objective().setMinimization();
510 
511  // 5 * x1 <= 30.
512  final MPConstraint c0 = solver.makeConstraint(-infinity, 100.0);
513  c0.setCoefficient(x1, 5);
514 
515  final MPModelExportOptions obfuscate = new MPModelExportOptions();
516  obfuscate.setObfuscate(true);
517  String out = solver.exportModelAsLpFormat();
518  assertThat(out).isNotEmpty();
519  out = solver.exportModelAsLpFormat(obfuscate);
520  assertThat(out).isNotEmpty();
521  out = solver.exportModelAsMpsFormat();
522  assertThat(out).isNotEmpty();
523  out = solver.exportModelAsMpsFormat(obfuscate);
524  assertThat(out).isNotEmpty();
525  }
526 
527  @Test
529  final MPSolver.OptimizationProblemType problemType =
530  MPSolver.OptimizationProblemType.GLOP_LINEAR_PROGRAMMING;
531  if (!MPSolver.supportsProblemType(problemType)) {
532  return;
533  }
534  final MPSolver solver = new MPSolver("testWrongModelExport", problemType);
535  assertNotNull(solver);
536  // Test that forbidden names are renamed.
537  solver.makeBoolVar("<-%$#!&~-+ ⌂"); // Some illegal name.
538  String out = solver.exportModelAsLpFormat();
539  assertThat(out).isNotEmpty();
540  out = solver.exportModelAsMpsFormat();
541  assertThat(out).isNotEmpty();
542  }
543 
544  @Test
545  public void testMPSolver_setHint() {
546  final MPSolver.OptimizationProblemType problemType =
547  MPSolver.OptimizationProblemType.GLOP_LINEAR_PROGRAMMING;
548  if (!MPSolver.supportsProblemType(problemType)) {
549  return;
550  }
551  final MPSolver solver = new MPSolver("testSetHint", problemType);
552  assertNotNull(solver);
553  final MPVariable[] variables = {
554  solver.makeNumVar(0.0, 10.0, "x1"), solver.makeNumVar(0.0, 10.0, "x2")};
555  final double[] values = {5.0, 6.0};
556  solver.setHint(variables, values);
557 
558  final MPModelProto model = solver.exportModelToProto();
559  final PartialVariableAssignment hint = model.getSolutionHint();
560  assertEquals(2, hint.getVarIndexCount());
561  assertEquals(2, hint.getVarValueCount());
562  assertEquals(0, hint.getVarIndex(0));
563  assertEquals(5.0, hint.getVarValue(0), 1e-6);
564  assertEquals(1, hint.getVarIndex(1));
565  assertEquals(6.0, hint.getVarValue(1), 1e-6);
566  }
567 
568  @Test
569  public void testMPSolver_issue132() {
570  final MPSolver.OptimizationProblemType problemType =
571  MPSolver.OptimizationProblemType.CLP_LINEAR_PROGRAMMING;
572  if (!MPSolver.supportsProblemType(problemType)) {
573  return;
574  }
575  final MPSolver solver = new MPSolver("CoinError", problemType);
576  assertNotNull(solver);
577  final double infinity = MPSolver.infinity();
578  final MPVariable x0 = solver.makeNumVar(0.0, 1.0, "x0");
579  final MPVariable x1 = solver.makeNumVar(0.0, 0.3, "x1");
580  final MPVariable x2 = solver.makeNumVar(0.0, 0.3, "x2");
581  final MPVariable x3 = solver.makeNumVar(-infinity, infinity, "x3");
582 
583  final MPObjective obj = solver.objective();
584  obj.setCoefficient(x1, 2.655523);
585  obj.setCoefficient(x2, -2.70917);
586  obj.setCoefficient(x3, 1);
587  obj.setMaximization();
588 
589  final MPConstraint c0 = solver.makeConstraint(-infinity, 0.302499);
590  c0.setCoefficient(x3, 1);
591  c0.setCoefficient(x0, -3.484345);
592 
593  final MPConstraint c1 = solver.makeConstraint(-infinity, 0.507194);
594  c1.setCoefficient(x3, 1);
595  c1.setCoefficient(x0, -3.074807);
596 
597  final MPConstraint c2 = solver.makeConstraint(0.594, 0.594);
598  c2.setCoefficient(x0, 1);
599  c2.setCoefficient(x1, 1.01);
600  c2.setCoefficient(x2, -0.99);
601 
602  System.out.println("Number of variables = " + solver.numVariables());
603  System.out.println("Number of constraints = " + solver.numConstraints());
604 
605  solver.enableOutput();
606  System.out.println(solver.exportModelAsLpFormat());
607  System.out.println(solver.solve());
608  }
609 
610  @Test
612  final MPSolver.OptimizationProblemType problemType =
613  MPSolver.OptimizationProblemType.GLOP_LINEAR_PROGRAMMING;
614  if (!MPSolver.supportsProblemType(problemType)) {
615  return;
616  }
617  final MPSolver solver = new MPSolver("glop", problemType);
618  assertNotNull(solver);
619 
620  // x and y are continuous non-negative variables.
621  final MPVariable x = solver.makeIntVar(0.0, Double.POSITIVE_INFINITY, "x");
622  final MPVariable y = solver.makeIntVar(0.0, Double.POSITIVE_INFINITY, "y");
623 
624  // Objectif function: Maximize x + 10 * y.
625  final MPObjective objective = solver.objective();
626  objective.setCoefficient(x, 1);
627  objective.setCoefficient(y, 10);
628  objective.setMaximization();
629 
630  // x + 7 * y <= 17.5.
631  final MPConstraint c0 = solver.makeConstraint(-Double.POSITIVE_INFINITY, 17.5, "c0");
632  c0.setCoefficient(x, 1);
633  c0.setCoefficient(y, 7);
634 
635  // x <= 3.5.
636  final MPConstraint c1 = solver.makeConstraint(-Double.POSITIVE_INFINITY, 3.5, "c1");
637  c1.setCoefficient(x, 1);
638  c1.setCoefficient(y, 0);
639 
640  // Test solver getters.
641  final MPVariable[] variables = solver.variables();
642  assertThat(variables).hasLength(2);
643  final MPConstraint[] constraints = solver.constraints();
644  assertThat(constraints).hasLength(2);
645 
646  // Test API compiles.
647  solver.setHint(variables, new double[] {2.0, 3.0});
648  assertEquals("y", variables[1].name());
649  assertEquals("c0", constraints[0].name());
650  // TODO(user): Add API to query the hint.
651 
652  assertFalse(solver.setNumThreads(4));
653  }
654 }
Load native libraries needed for using ortools-java.
Definition: Loader.java:33
static synchronized void loadNativeLibraries()
Definition: Loader.java:104
Test the Linear Solver java interface.