1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.hipparchus.optim.linear;
23
24 import org.hipparchus.exception.MathIllegalArgumentException;
25 import org.hipparchus.exception.MathIllegalStateException;
26 import org.hipparchus.optim.MaxIter;
27 import org.hipparchus.optim.PointValuePair;
28 import org.hipparchus.optim.nonlinear.scalar.GoalType;
29 import org.hipparchus.util.Precision;
30 import org.junit.jupiter.api.Test;
31
32 import java.util.ArrayList;
33 import java.util.Collection;
34 import java.util.List;
35
36 import static org.junit.jupiter.api.Assertions.assertEquals;
37 import static org.junit.jupiter.api.Assertions.assertFalse;
38 import static org.junit.jupiter.api.Assertions.assertNotNull;
39 import static org.junit.jupiter.api.Assertions.assertNull;
40 import static org.junit.jupiter.api.Assertions.assertThrows;
41 import static org.junit.jupiter.api.Assertions.assertTrue;
42 import static org.junit.jupiter.api.Assertions.fail;
43
44 class SimplexSolverTest {
45 private static final MaxIter DEFAULT_MAX_ITER = new MaxIter(100);
46
47 @Test
48 void testMath842Cycle() {
49
50
51
52
53
54
55
56
57 LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 10, -57, -9, -24}, 0);
58
59 ArrayList<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
60
61 constraints.add(new LinearConstraint(new double[] {0.5, -5.5, -2.5, 9}, Relationship.LEQ, 0));
62 constraints.add(new LinearConstraint(new double[] {0.5, -1.5, -0.5, 1}, Relationship.LEQ, 0));
63 constraints.add(new LinearConstraint(new double[] { 1, 0, 0, 0}, Relationship.LEQ, 1));
64
65 double epsilon = 1e-6;
66 SimplexSolver solver = new SimplexSolver();
67 PointValuePair solution = solver.optimize(f, new LinearConstraintSet(constraints),
68 GoalType.MAXIMIZE,
69 new NonNegativeConstraint(true),
70 PivotSelectionRule.BLAND);
71 assertEquals(1.0d, solution.getValue(), epsilon);
72 assertTrue(validSolution(solution, constraints, epsilon));
73 }
74
75 @Test
76 void testMath828() {
77 LinearObjectiveFunction f = new LinearObjectiveFunction(
78 new double[] { 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, 0.0);
79
80 ArrayList <LinearConstraint>constraints = new ArrayList<LinearConstraint>();
81
82 constraints.add(new LinearConstraint(new double[] {0.0, 39.0, 23.0, 96.0, 15.0, 48.0, 9.0, 21.0, 48.0, 36.0, 76.0, 19.0, 88.0, 17.0, 16.0, 36.0,}, Relationship.GEQ, 15.0));
83 constraints.add(new LinearConstraint(new double[] {0.0, 59.0, 93.0, 12.0, 29.0, 78.0, 73.0, 87.0, 32.0, 70.0, 68.0, 24.0, 11.0, 26.0, 65.0, 25.0,}, Relationship.GEQ, 29.0));
84 constraints.add(new LinearConstraint(new double[] {0.0, 74.0, 5.0, 82.0, 6.0, 97.0, 55.0, 44.0, 52.0, 54.0, 5.0, 93.0, 91.0, 8.0, 20.0, 97.0,}, Relationship.GEQ, 6.0));
85 constraints.add(new LinearConstraint(new double[] {8.0, -3.0, -28.0, -72.0, -8.0, -31.0, -31.0, -74.0, -47.0, -59.0, -24.0, -57.0, -56.0, -16.0, -92.0, -59.0,}, Relationship.GEQ, 0.0));
86 constraints.add(new LinearConstraint(new double[] {25.0, -7.0, -99.0, -78.0, -25.0, -14.0, -16.0, -89.0, -39.0, -56.0, -53.0, -9.0, -18.0, -26.0, -11.0, -61.0,}, Relationship.GEQ, 0.0));
87 constraints.add(new LinearConstraint(new double[] {33.0, -95.0, -15.0, -4.0, -33.0, -3.0, -20.0, -96.0, -27.0, -13.0, -80.0, -24.0, -3.0, -13.0, -57.0, -76.0,}, Relationship.GEQ, 0.0));
88 constraints.add(new LinearConstraint(new double[] {7.0, -95.0, -39.0, -93.0, -7.0, -94.0, -94.0, -62.0, -76.0, -26.0, -53.0, -57.0, -31.0, -76.0, -53.0, -52.0,}, Relationship.GEQ, 0.0));
89
90 double epsilon = 1e-6;
91 PointValuePair solution = new SimplexSolver().optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
92 GoalType.MINIMIZE, new NonNegativeConstraint(true));
93 assertEquals(1.0d, solution.getValue(), epsilon);
94 assertTrue(validSolution(solution, constraints, epsilon));
95 }
96
97 @Test
98 void testMath828Cycle() {
99 LinearObjectiveFunction f = new LinearObjectiveFunction(
100 new double[] { 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, 0.0);
101
102 ArrayList <LinearConstraint>constraints = new ArrayList<LinearConstraint>();
103
104 constraints.add(new LinearConstraint(new double[] {0.0, 16.0, 14.0, 69.0, 1.0, 85.0, 52.0, 43.0, 64.0, 97.0, 14.0, 74.0, 89.0, 28.0, 94.0, 58.0, 13.0, 22.0, 21.0, 17.0, 30.0, 25.0, 1.0, 59.0, 91.0, 78.0, 12.0, 74.0, 56.0, 3.0, 88.0,}, Relationship.GEQ, 91.0));
105 constraints.add(new LinearConstraint(new double[] {0.0, 60.0, 40.0, 81.0, 71.0, 72.0, 46.0, 45.0, 38.0, 48.0, 40.0, 17.0, 33.0, 85.0, 64.0, 32.0, 84.0, 3.0, 54.0, 44.0, 71.0, 67.0, 90.0, 95.0, 54.0, 99.0, 99.0, 29.0, 52.0, 98.0, 9.0,}, Relationship.GEQ, 54.0));
106 constraints.add(new LinearConstraint(new double[] {0.0, 41.0, 12.0, 86.0, 90.0, 61.0, 31.0, 41.0, 23.0, 89.0, 17.0, 74.0, 44.0, 27.0, 16.0, 47.0, 80.0, 32.0, 11.0, 56.0, 68.0, 82.0, 11.0, 62.0, 62.0, 53.0, 39.0, 16.0, 48.0, 1.0, 63.0,}, Relationship.GEQ, 62.0));
107 constraints.add(new LinearConstraint(new double[] {83.0, -76.0, -94.0, -19.0, -15.0, -70.0, -72.0, -57.0, -63.0, -65.0, -22.0, -94.0, -22.0, -88.0, -86.0, -89.0, -72.0, -16.0, -80.0, -49.0, -70.0, -93.0, -95.0, -17.0, -83.0, -97.0, -31.0, -47.0, -31.0, -13.0, -23.0,}, Relationship.GEQ, 0.0));
108 constraints.add(new LinearConstraint(new double[] {41.0, -96.0, -41.0, -48.0, -70.0, -43.0, -43.0, -43.0, -97.0, -37.0, -85.0, -70.0, -45.0, -67.0, -87.0, -69.0, -94.0, -54.0, -54.0, -92.0, -79.0, -10.0, -35.0, -20.0, -41.0, -41.0, -65.0, -25.0, -12.0, -8.0, -46.0,}, Relationship.GEQ, 0.0));
109 constraints.add(new LinearConstraint(new double[] {27.0, -42.0, -65.0, -49.0, -53.0, -42.0, -17.0, -2.0, -61.0, -31.0, -76.0, -47.0, -8.0, -93.0, -86.0, -62.0, -65.0, -63.0, -22.0, -43.0, -27.0, -23.0, -32.0, -74.0, -27.0, -63.0, -47.0, -78.0, -29.0, -95.0, -73.0,}, Relationship.GEQ, 0.0));
110 constraints.add(new LinearConstraint(new double[] {15.0, -46.0, -41.0, -83.0, -98.0, -99.0, -21.0, -35.0, -7.0, -14.0, -80.0, -63.0, -18.0, -42.0, -5.0, -34.0, -56.0, -70.0, -16.0, -18.0, -74.0, -61.0, -47.0, -41.0, -15.0, -79.0, -18.0, -47.0, -88.0, -68.0, -55.0,}, Relationship.GEQ, 0.0));
111
112 double epsilon = 1e-6;
113 PointValuePair solution = new SimplexSolver().optimize(DEFAULT_MAX_ITER, f,
114 new LinearConstraintSet(constraints),
115 GoalType.MINIMIZE, new NonNegativeConstraint(true),
116 PivotSelectionRule.BLAND);
117 assertEquals(1.0d, solution.getValue(), epsilon);
118 assertTrue(validSolution(solution, constraints, epsilon));
119 }
120
121 @Test
122 void testMath781() {
123 LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 2, 6, 7 }, 0);
124
125 ArrayList<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
126 constraints.add(new LinearConstraint(new double[] { 1, 2, 1 }, Relationship.LEQ, 2));
127 constraints.add(new LinearConstraint(new double[] { -1, 1, 1 }, Relationship.LEQ, -1));
128 constraints.add(new LinearConstraint(new double[] { 2, -3, 1 }, Relationship.LEQ, -1));
129
130 double epsilon = 1e-6;
131 SimplexSolver solver = new SimplexSolver();
132 PointValuePair solution = solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
133 GoalType.MAXIMIZE, new NonNegativeConstraint(false));
134
135 assertTrue(Precision.compareTo(solution.getPoint()[0], 0.0d, epsilon) > 0);
136 assertTrue(Precision.compareTo(solution.getPoint()[1], 0.0d, epsilon) > 0);
137 assertTrue(Precision.compareTo(solution.getPoint()[2], 0.0d, epsilon) < 0);
138 assertEquals(2.0d, solution.getValue(), epsilon);
139 }
140
141 @Test
142 void testMath713NegativeVariable() {
143 LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] {1.0, 1.0}, 0.0d);
144 ArrayList<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
145 constraints.add(new LinearConstraint(new double[] {1, 0}, Relationship.EQ, 1));
146
147 double epsilon = 1e-6;
148 SimplexSolver solver = new SimplexSolver();
149 PointValuePair solution = solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
150 GoalType.MINIMIZE, new NonNegativeConstraint(true));
151
152 assertTrue(Precision.compareTo(solution.getPoint()[0], 0.0d, epsilon) >= 0);
153 assertTrue(Precision.compareTo(solution.getPoint()[1], 0.0d, epsilon) >= 0);
154 }
155
156 @Test
157 void testMath434NegativeVariable() {
158 LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] {0.0, 0.0, 1.0}, 0.0d);
159 ArrayList<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
160 constraints.add(new LinearConstraint(new double[] {1, 1, 0}, Relationship.EQ, 5));
161 constraints.add(new LinearConstraint(new double[] {0, 0, 1}, Relationship.GEQ, -10));
162
163 double epsilon = 1e-6;
164 SimplexSolver solver = new SimplexSolver();
165 PointValuePair solution = solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
166 GoalType.MINIMIZE, new NonNegativeConstraint(false));
167
168 assertEquals(5.0, solution.getPoint()[0] + solution.getPoint()[1], epsilon);
169 assertEquals(-10.0, solution.getPoint()[2], epsilon);
170 assertEquals(-10.0, solution.getValue(), epsilon);
171
172 }
173
174 @Test
175 void testMath434UnfeasibleSolution() {
176 assertThrows(MathIllegalStateException.class, () -> {
177 double epsilon = 1e-6;
178
179 LinearObjectiveFunction f = new LinearObjectiveFunction(new double[]{1.0, 0.0}, 0.0);
180 ArrayList<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
181 constraints.add(new LinearConstraint(new double[]{epsilon / 2, 0.5}, Relationship.EQ, 0));
182 constraints.add(new LinearConstraint(new double[]{1e-3, 0.1}, Relationship.EQ, 10));
183
184 SimplexSolver solver = new SimplexSolver();
185
186 solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
187 GoalType.MINIMIZE, new NonNegativeConstraint(true));
188 });
189 }
190
191 @Test
192 void testMath434PivotRowSelection() {
193 LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] {1.0}, 0.0);
194
195 double epsilon = 1e-6;
196 ArrayList<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
197 constraints.add(new LinearConstraint(new double[] {200}, Relationship.GEQ, 1));
198 constraints.add(new LinearConstraint(new double[] {100}, Relationship.GEQ, 0.499900001));
199
200 SimplexSolver solver = new SimplexSolver();
201 PointValuePair solution = solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
202 GoalType.MINIMIZE, new NonNegativeConstraint(false));
203
204 assertTrue(Precision.compareTo(solution.getPoint()[0] * 200.d, 1.d, epsilon) >= 0);
205 assertEquals(0.0050, solution.getValue(), epsilon);
206 }
207
208 @Test
209 void testMath434PivotRowSelection2() {
210 LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] {0.0d, 1.0d, 1.0d, 0.0d, 0.0d, 0.0d, 0.0d}, 0.0d);
211
212 ArrayList<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
213 constraints.add(new LinearConstraint(new double[] {1.0d, -0.1d, 0.0d, 0.0d, 0.0d, 0.0d, 0.0d}, Relationship.EQ, -0.1d));
214 constraints.add(new LinearConstraint(new double[] {1.0d, 0.0d, 0.0d, 0.0d, 0.0d, 0.0d, 0.0d}, Relationship.GEQ, -1e-18d));
215 constraints.add(new LinearConstraint(new double[] {0.0d, 1.0d, 0.0d, 0.0d, 0.0d, 0.0d, 0.0d}, Relationship.GEQ, 0.0d));
216 constraints.add(new LinearConstraint(new double[] {0.0d, 0.0d, 0.0d, 1.0d, 0.0d, -0.0128588d, 1e-5d}, Relationship.EQ, 0.0d));
217 constraints.add(new LinearConstraint(new double[] {0.0d, 0.0d, 0.0d, 0.0d, 1.0d, 1e-5d, -0.0128586d}, Relationship.EQ, 1e-10d));
218 constraints.add(new LinearConstraint(new double[] {0.0d, 0.0d, 1.0d, -1.0d, 0.0d, 0.0d, 0.0d}, Relationship.GEQ, 0.0d));
219 constraints.add(new LinearConstraint(new double[] {0.0d, 0.0d, 1.0d, 1.0d, 0.0d, 0.0d, 0.0d}, Relationship.GEQ, 0.0d));
220 constraints.add(new LinearConstraint(new double[] {0.0d, 0.0d, 1.0d, 0.0d, -1.0d, 0.0d, 0.0d}, Relationship.GEQ, 0.0d));
221 constraints.add(new LinearConstraint(new double[] {0.0d, 0.0d, 1.0d, 0.0d, 1.0d, 0.0d, 0.0d}, Relationship.GEQ, 0.0d));
222
223 double epsilon = 1e-7;
224 SimplexSolver simplex = new SimplexSolver();
225 PointValuePair solution = simplex.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
226 GoalType.MINIMIZE, new NonNegativeConstraint(false));
227
228 assertTrue(Precision.compareTo(solution.getPoint()[0], -1e-18d, epsilon) >= 0);
229 assertEquals(1.0d, solution.getPoint()[1], epsilon);
230 assertEquals(0.0d, solution.getPoint()[2], epsilon);
231 assertEquals(1.0d, solution.getValue(), epsilon);
232 }
233
234 @Test
235 void testMath272() {
236 LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 2, 2, 1 }, 0);
237 Collection<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
238 constraints.add(new LinearConstraint(new double[] { 1, 1, 0 }, Relationship.GEQ, 1));
239 constraints.add(new LinearConstraint(new double[] { 1, 0, 1 }, Relationship.GEQ, 1));
240 constraints.add(new LinearConstraint(new double[] { 0, 1, 0 }, Relationship.GEQ, 1));
241
242 SimplexSolver solver = new SimplexSolver();
243 PointValuePair solution = solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
244 GoalType.MINIMIZE, new NonNegativeConstraint(true));
245
246 assertEquals(0.0, solution.getPoint()[0], .0000001);
247 assertEquals(1.0, solution.getPoint()[1], .0000001);
248 assertEquals(1.0, solution.getPoint()[2], .0000001);
249 assertEquals(3.0, solution.getValue(), .0000001);
250 }
251
252 @Test
253 void testMath286() {
254 LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 0.8, 0.2, 0.7, 0.3, 0.6, 0.4 }, 0 );
255 Collection<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
256 constraints.add(new LinearConstraint(new double[] { 1, 0, 1, 0, 1, 0 }, Relationship.EQ, 23.0));
257 constraints.add(new LinearConstraint(new double[] { 0, 1, 0, 1, 0, 1 }, Relationship.EQ, 23.0));
258 constraints.add(new LinearConstraint(new double[] { 1, 0, 0, 0, 0, 0 }, Relationship.GEQ, 10.0));
259 constraints.add(new LinearConstraint(new double[] { 0, 0, 1, 0, 0, 0 }, Relationship.GEQ, 8.0));
260 constraints.add(new LinearConstraint(new double[] { 0, 0, 0, 0, 1, 0 }, Relationship.GEQ, 5.0));
261
262 SimplexSolver solver = new SimplexSolver();
263 PointValuePair solution = solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
264 GoalType.MAXIMIZE, new NonNegativeConstraint(true));
265
266 assertEquals(25.8, solution.getValue(), .0000001);
267 assertEquals(23.0, solution.getPoint()[0] + solution.getPoint()[2] + solution.getPoint()[4], 0.0000001);
268 assertEquals(23.0, solution.getPoint()[1] + solution.getPoint()[3] + solution.getPoint()[5], 0.0000001);
269 assertTrue(solution.getPoint()[0] >= 10.0 - 0.0000001);
270 assertTrue(solution.getPoint()[2] >= 8.0 - 0.0000001);
271 assertTrue(solution.getPoint()[4] >= 5.0 - 0.0000001);
272 }
273
274 @Test
275 void testDegeneracy() {
276 LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 0.8, 0.7 }, 0 );
277 Collection<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
278 constraints.add(new LinearConstraint(new double[] { 1, 1 }, Relationship.LEQ, 18.0));
279 constraints.add(new LinearConstraint(new double[] { 1, 0 }, Relationship.GEQ, 10.0));
280 constraints.add(new LinearConstraint(new double[] { 0, 1 }, Relationship.GEQ, 8.0));
281
282 SimplexSolver solver = new SimplexSolver();
283 PointValuePair solution = solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
284 GoalType.MINIMIZE, new NonNegativeConstraint(true));
285 assertEquals(13.6, solution.getValue(), .0000001);
286 }
287
288 @Test
289 void testMath288() {
290 LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 7, 3, 0, 0 }, 0 );
291 Collection<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
292 constraints.add(new LinearConstraint(new double[] { 3, 0, -5, 0 }, Relationship.LEQ, 0.0));
293 constraints.add(new LinearConstraint(new double[] { 2, 0, 0, -5 }, Relationship.LEQ, 0.0));
294 constraints.add(new LinearConstraint(new double[] { 0, 3, 0, -5 }, Relationship.LEQ, 0.0));
295 constraints.add(new LinearConstraint(new double[] { 1, 0, 0, 0 }, Relationship.LEQ, 1.0));
296 constraints.add(new LinearConstraint(new double[] { 0, 1, 0, 0 }, Relationship.LEQ, 1.0));
297
298 SimplexSolver solver = new SimplexSolver();
299 PointValuePair solution = solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
300 GoalType.MAXIMIZE, new NonNegativeConstraint(true));
301 assertEquals(10.0, solution.getValue(), .0000001);
302 }
303
304 @Test
305 void testMath290GEQ() {
306 LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 1, 5 }, 0 );
307 Collection<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
308 constraints.add(new LinearConstraint(new double[] { 2, 0 }, Relationship.GEQ, -1.0));
309 SimplexSolver solver = new SimplexSolver();
310 PointValuePair solution = solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
311 GoalType.MINIMIZE, new NonNegativeConstraint(true));
312 assertEquals(0, solution.getValue(), .0000001);
313 assertEquals(0, solution.getPoint()[0], .0000001);
314 assertEquals(0, solution.getPoint()[1], .0000001);
315 }
316
317 @Test
318 void testMath290LEQ() {
319 assertThrows(MathIllegalStateException.class, () -> {
320 LinearObjectiveFunction f = new LinearObjectiveFunction(new double[]{1, 5}, 0 );
321 Collection<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
322 constraints.add(new LinearConstraint(new double[]{2, 0}, Relationship.LEQ, -1.0));
323 SimplexSolver solver = new SimplexSolver();
324 solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
325 GoalType.MINIMIZE, new NonNegativeConstraint(true));
326 });
327 }
328
329 @Test
330 void testMath293() {
331 LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 0.8, 0.2, 0.7, 0.3, 0.4, 0.6}, 0 );
332 Collection<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
333 constraints.add(new LinearConstraint(new double[] { 1, 0, 1, 0, 1, 0 }, Relationship.EQ, 30.0));
334 constraints.add(new LinearConstraint(new double[] { 0, 1, 0, 1, 0, 1 }, Relationship.EQ, 30.0));
335 constraints.add(new LinearConstraint(new double[] { 0.8, 0.2, 0.0, 0.0, 0.0, 0.0 }, Relationship.GEQ, 10.0));
336 constraints.add(new LinearConstraint(new double[] { 0.0, 0.0, 0.7, 0.3, 0.0, 0.0 }, Relationship.GEQ, 10.0));
337 constraints.add(new LinearConstraint(new double[] { 0.0, 0.0, 0.0, 0.0, 0.4, 0.6 }, Relationship.GEQ, 10.0));
338
339 SimplexSolver solver = new SimplexSolver();
340 PointValuePair solution1 = solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
341 GoalType.MAXIMIZE, new NonNegativeConstraint(true));
342
343 assertEquals(15.7143, solution1.getPoint()[0], .0001);
344 assertEquals(0.0, solution1.getPoint()[1], .0001);
345 assertEquals(14.2857, solution1.getPoint()[2], .0001);
346 assertEquals(0.0, solution1.getPoint()[3], .0001);
347 assertEquals(0.0, solution1.getPoint()[4], .0001);
348 assertEquals(30.0, solution1.getPoint()[5], .0001);
349 assertEquals(40.57143, solution1.getValue(), .0001);
350
351 double valA = 0.8 * solution1.getPoint()[0] + 0.2 * solution1.getPoint()[1];
352 double valB = 0.7 * solution1.getPoint()[2] + 0.3 * solution1.getPoint()[3];
353 double valC = 0.4 * solution1.getPoint()[4] + 0.6 * solution1.getPoint()[5];
354
355 f = new LinearObjectiveFunction(new double[] { 0.8, 0.2, 0.7, 0.3, 0.4, 0.6}, 0 );
356 constraints = new ArrayList<LinearConstraint>();
357 constraints.add(new LinearConstraint(new double[] { 1, 0, 1, 0, 1, 0 }, Relationship.EQ, 30.0));
358 constraints.add(new LinearConstraint(new double[] { 0, 1, 0, 1, 0, 1 }, Relationship.EQ, 30.0));
359 constraints.add(new LinearConstraint(new double[] { 0.8, 0.2, 0.0, 0.0, 0.0, 0.0 }, Relationship.GEQ, valA));
360 constraints.add(new LinearConstraint(new double[] { 0.0, 0.0, 0.7, 0.3, 0.0, 0.0 }, Relationship.GEQ, valB));
361 constraints.add(new LinearConstraint(new double[] { 0.0, 0.0, 0.0, 0.0, 0.4, 0.6 }, Relationship.GEQ, valC));
362
363 PointValuePair solution2 = solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
364 GoalType.MAXIMIZE, new NonNegativeConstraint(true));
365 assertEquals(40.57143, solution2.getValue(), .0001);
366 }
367
368 @Test
369 void testMath930() {
370 Collection<LinearConstraint> constraints = createMath930Constraints();
371
372 double[] objFunctionCoeff = new double[33];
373 objFunctionCoeff[3] = 1;
374 LinearObjectiveFunction f = new LinearObjectiveFunction(objFunctionCoeff, 0);
375 SimplexSolver solver = new SimplexSolver(1e-4, 10, 1e-6);
376
377 PointValuePair solution = solver.optimize(new MaxIter(1000), f, new LinearConstraintSet(constraints),
378 GoalType.MINIMIZE, new NonNegativeConstraint(true));
379 assertEquals(0.3752298, solution.getValue(), 1e-4);
380 }
381
382 private List<LinearConstraint> createMath930Constraints() {
383 List<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
384 constraints.add(new LinearConstraint(new double[] {1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 0}, Relationship.GEQ, 0.0));
385 constraints.add(new LinearConstraint(new double[] {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, Relationship.GEQ, 0.0));
386 constraints.add(new LinearConstraint(new double[] {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, Relationship.LEQ, 0.0));
387 constraints.add(new LinearConstraint(new double[] {0, 1, 0, -1, 0, -1, 0, 1, 0, -1, 0, 1, 0, 1, 0, -1, 0, -1, 0, 1, 0, 1, 0, -1, 0, 1, 0, -1, 0, -1, 0, 1, 0}, Relationship.GEQ, 0.0));
388 constraints.add(new LinearConstraint(new double[] {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.628803}, Relationship.GEQ, 0.0));
389 constraints.add(new LinearConstraint(new double[] {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.676993}, Relationship.LEQ, 0.0));
390 constraints.add(new LinearConstraint(new double[] {0, 0, 1, -1, 0, 0, -1, 1, 0, 0, -1, 1, 0, 0, 1, -1, 0, 0, -1, 1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, -1, 1, 0}, Relationship.GEQ, 0.0));
391 constraints.add(new LinearConstraint(new double[] {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.136677}, Relationship.GEQ, 0.0));
392 constraints.add(new LinearConstraint(new double[] {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.444434}, Relationship.LEQ, 0.0));
393 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, -1, 0}, Relationship.GEQ, 0.0));
394 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.254028}, Relationship.GEQ, 0.0));
395 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.302218}, Relationship.LEQ, 0.0));
396 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 1, -1, -1, 1, 0, 0, 0, 0, -1, 1, 1, -1, 0, 0, 0, 0, -1, 1, 1, -1, 0, 0, 0, 0, 1, -1, -1, 1, 0}, Relationship.GEQ, 0.0));
397 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.653981}, Relationship.GEQ, 0.0));
398 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.690437}, Relationship.LEQ, 0.0));
399 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 1, 0, -1, 0}, Relationship.GEQ, 0.0));
400 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.423786}, Relationship.GEQ, 0.0));
401 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.486717}, Relationship.LEQ, 0.0));
402 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 1, -1, 0}, Relationship.GEQ, 0.0));
403 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.049232}, Relationship.GEQ, 0.0));
404 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.304747}, Relationship.LEQ, 0.0));
405 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 1, 0}, Relationship.GEQ, 0.0));
406 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.129826}, Relationship.GEQ, 0.0));
407 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.205625}, Relationship.LEQ, 0.0));
408 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 1, -1, -1, 1, -1, 1, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 1, -1, 1, -1, -1, 1, 0}, Relationship.GEQ, 0.0));
409 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.621944}, Relationship.GEQ, 0.0));
410 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.764385}, Relationship.LEQ, 0.0));
411 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -1, 0, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 1, 0, -1, 0}, Relationship.GEQ, 0.0));
412 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.432572}, Relationship.GEQ, 0.0));
413 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.480762}, Relationship.LEQ, 0.0));
414 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 1, -1, 0}, Relationship.GEQ, 0.0));
415 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.055983}, Relationship.GEQ, 0.0));
416 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.11378}, Relationship.LEQ, 0.0));
417 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 1, 0}, Relationship.GEQ, 0.0));
418 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.009607}, Relationship.GEQ, 0.0));
419 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.057797}, Relationship.LEQ, 0.0));
420 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 1, -1, 0}, Relationship.GEQ, 0.0));
421 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.407308}, Relationship.GEQ, 0.0));
422 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.452749}, Relationship.LEQ, 0.0));
423 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0}, Relationship.GEQ, 0.0));
424 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.269677}, Relationship.GEQ, 0.0));
425 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.321806}, Relationship.LEQ, 0.0));
426 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0}, Relationship.GEQ, 0.0));
427 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.049232}, Relationship.GEQ, 0.0));
428 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.06902}, Relationship.LEQ, 0.0));
429 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0}, Relationship.GEQ, 0.0));
430 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0}, Relationship.GEQ, 0.0));
431 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.028754}, Relationship.LEQ, 0.0));
432 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 0}, Relationship.GEQ, 0.0));
433 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.484254}, Relationship.GEQ, 0.0));
434 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.524607}, Relationship.LEQ, 0.0));
435 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -1, 0, -1, 0, 1, 0, -1, 0, 1, 0, 1, 0, -1, 0}, Relationship.GEQ, 0.0));
436 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.385492}, Relationship.GEQ, 0.0));
437 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.430134}, Relationship.LEQ, 0.0));
438 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, -1, 1, 0, 0, -1, 1, 0, 0, 1, -1, 0}, Relationship.GEQ, 0.0));
439 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.34983}, Relationship.GEQ, 0.0));
440 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.375781}, Relationship.LEQ, 0.0));
441 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0, 1, 0}, Relationship.GEQ, 0.0));
442 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.254028}, Relationship.GEQ, 0.0));
443 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.281308}, Relationship.LEQ, 0.0));
444 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, -1, 1, 0, 0, 0, 0, -1, 1, 1, -1, 0}, Relationship.GEQ, 0.0));
445 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.304995}, Relationship.GEQ, 0.0));
446 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.345347}, Relationship.LEQ, 0.0));
447 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0, 0, -1, 0, 1, 0}, Relationship.GEQ, 0.0));
448 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.288899}, Relationship.GEQ, 0.0));
449 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.332212}, Relationship.LEQ, 0.0));
450 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 0, 0, -1, 1, 0}, Relationship.GEQ, 0.0));
451 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.14351}, Relationship.GEQ, 0.0));
452 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.17057}, Relationship.LEQ, 0.0));
453 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -1, 0}, Relationship.GEQ, 0.0));
454 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -0.129826}, Relationship.GEQ, 0.0));
455 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -0.157435}, Relationship.LEQ, 0.0));
456 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, -1, 1, -1, 1, 1, -1, 0}, Relationship.GEQ, 0.0));
457 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -0}, Relationship.GEQ, 0.0));
458 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -1}, Relationship.LEQ, 0.0));
459 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -1, 0, -1, 0, 1, 0}, Relationship.GEQ, 0.0));
460 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, -0.141071}, Relationship.GEQ, 0.0));
461 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, -0.232574}, Relationship.LEQ, 0.0));
462 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, -1, 1, 0}, Relationship.GEQ, 0.0));
463 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0}, Relationship.GEQ, 0.0));
464 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, -1}, Relationship.LEQ, 0.0));
465 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, -1, 0}, Relationship.GEQ, 0.0));
466 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, -0.009607}, Relationship.GEQ, 0.0));
467 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, -0.057797}, Relationship.LEQ, 0.0));
468 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, -1, 1, 0}, Relationship.GEQ, 0.0));
469 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, -0}, Relationship.GEQ, 0.0));
470 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, -1}, Relationship.LEQ, 0.0));
471 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -1, 0}, Relationship.GEQ, 0.0));
472 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -0.091644}, Relationship.GEQ, 0.0));
473 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -0.203531}, Relationship.LEQ, 0.0));
474 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0}, Relationship.GEQ, 0.0));
475 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -0}, Relationship.GEQ, 0.0));
476 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -1}, Relationship.LEQ, 0.0));
477 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}, Relationship.GEQ, 0.0));
478 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}, Relationship.GEQ, 0.0));
479 constraints.add(new LinearConstraint(new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -0.028754}, Relationship.LEQ, 0.0));
480 constraints.add(new LinearConstraint(new double[] {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, Relationship.EQ, 1.0));
481 return constraints;
482 }
483
484 @Test
485 void testSimplexSolver() {
486 LinearObjectiveFunction f =
487 new LinearObjectiveFunction(new double[] { 15, 10 }, 7);
488 Collection<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
489 constraints.add(new LinearConstraint(new double[] { 1, 0 }, Relationship.LEQ, 2));
490 constraints.add(new LinearConstraint(new double[] { 0, 1 }, Relationship.LEQ, 3));
491 constraints.add(new LinearConstraint(new double[] { 1, 1 }, Relationship.EQ, 4));
492
493 SimplexSolver solver = new SimplexSolver();
494 PointValuePair solution = solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
495 GoalType.MAXIMIZE, new NonNegativeConstraint(true));
496 assertEquals(2.0, solution.getPoint()[0], 0.0);
497 assertEquals(2.0, solution.getPoint()[1], 0.0);
498 assertEquals(57.0, solution.getValue(), 0.0);
499 }
500
501 @Test
502 void testSingleVariableAndConstraint() {
503 LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 3 }, 0);
504 Collection<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
505 constraints.add(new LinearConstraint(new double[] { 1 }, Relationship.LEQ, 10));
506
507 SimplexSolver solver = new SimplexSolver();
508 PointValuePair solution = solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
509 GoalType.MAXIMIZE, new NonNegativeConstraint(false));
510 assertEquals(10.0, solution.getPoint()[0], 0.0);
511 assertEquals(30.0, solution.getValue(), 0.0);
512 }
513
514
515
516
517
518 @Test
519 void testModelWithNoArtificialVars() {
520 LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 15, 10 }, 0);
521 Collection<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
522 constraints.add(new LinearConstraint(new double[] { 1, 0 }, Relationship.LEQ, 2));
523 constraints.add(new LinearConstraint(new double[] { 0, 1 }, Relationship.LEQ, 3));
524 constraints.add(new LinearConstraint(new double[] { 1, 1 }, Relationship.LEQ, 4));
525
526 SimplexSolver solver = new SimplexSolver();
527 PointValuePair solution = solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
528 GoalType.MAXIMIZE, new NonNegativeConstraint(false));
529 assertEquals(2.0, solution.getPoint()[0], 0.0);
530 assertEquals(2.0, solution.getPoint()[1], 0.0);
531 assertEquals(50.0, solution.getValue(), 0.0);
532 }
533
534 @Test
535 void testMinimization() {
536 LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { -2, 1 }, -5);
537 Collection<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
538 constraints.add(new LinearConstraint(new double[] { 1, 2 }, Relationship.LEQ, 6));
539 constraints.add(new LinearConstraint(new double[] { 3, 2 }, Relationship.LEQ, 12));
540 constraints.add(new LinearConstraint(new double[] { 0, 1 }, Relationship.GEQ, 0));
541
542 SimplexSolver solver = new SimplexSolver();
543 PointValuePair solution = solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
544 GoalType.MINIMIZE, new NonNegativeConstraint(false));
545 assertEquals(4.0, solution.getPoint()[0], 0.0);
546 assertEquals(0.0, solution.getPoint()[1], 0.0);
547 assertEquals(-13.0, solution.getValue(), 0.0);
548 }
549
550 @Test
551 void testSolutionWithNegativeDecisionVariable() {
552 LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { -2, 1 }, 0);
553 Collection<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
554 constraints.add(new LinearConstraint(new double[] { 1, 1 }, Relationship.GEQ, 6));
555 constraints.add(new LinearConstraint(new double[] { 1, 2 }, Relationship.LEQ, 14));
556
557 SimplexSolver solver = new SimplexSolver();
558 PointValuePair solution = solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
559 GoalType.MAXIMIZE, new NonNegativeConstraint(false));
560 assertEquals(-2.0, solution.getPoint()[0], 0.0);
561 assertEquals(8.0, solution.getPoint()[1], 0.0);
562 assertEquals(12.0, solution.getValue(), 0.0);
563 }
564
565 @Test
566 void testInfeasibleSolution() {
567 assertThrows(MathIllegalStateException.class, () -> {
568 LinearObjectiveFunction f = new LinearObjectiveFunction(new double[]{15}, 0);
569 Collection<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
570 constraints.add(new LinearConstraint(new double[]{1}, Relationship.LEQ, 1));
571 constraints.add(new LinearConstraint(new double[]{1}, Relationship.GEQ, 3));
572
573 SimplexSolver solver = new SimplexSolver();
574 solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
575 GoalType.MAXIMIZE, new NonNegativeConstraint(false));
576 });
577 }
578
579 @Test
580 void testUnboundedSolution() {
581 assertThrows(MathIllegalStateException.class, () -> {
582 LinearObjectiveFunction f = new LinearObjectiveFunction(new double[]{15, 10}, 0);
583 Collection<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
584 constraints.add(new LinearConstraint(new double[]{1, 0}, Relationship.EQ, 2));
585
586 SimplexSolver solver = new SimplexSolver();
587 solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
588 GoalType.MAXIMIZE, new NonNegativeConstraint(false));
589 });
590 }
591
592 @Test
593 void testRestrictVariablesToNonNegative() {
594 LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 409, 523, 70, 204, 339 }, 0);
595 Collection<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
596 constraints.add(new LinearConstraint(new double[] { 43, 56, 345, 56, 5 }, Relationship.LEQ, 4567456));
597 constraints.add(new LinearConstraint(new double[] { 12, 45, 7, 56, 23 }, Relationship.LEQ, 56454));
598 constraints.add(new LinearConstraint(new double[] { 8, 768, 0, 34, 7456 }, Relationship.LEQ, 1923421));
599 constraints.add(new LinearConstraint(new double[] { 12342, 2342, 34, 678, 2342 }, Relationship.GEQ, 4356));
600 constraints.add(new LinearConstraint(new double[] { 45, 678, 76, 52, 23 }, Relationship.EQ, 456356));
601
602 SimplexSolver solver = new SimplexSolver();
603 PointValuePair solution = solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
604 GoalType.MAXIMIZE, new NonNegativeConstraint(true));
605 assertEquals(2902.92783505155, solution.getPoint()[0], .0000001);
606 assertEquals(480.419243986254, solution.getPoint()[1], .0000001);
607 assertEquals(0.0, solution.getPoint()[2], .0000001);
608 assertEquals(0.0, solution.getPoint()[3], .0000001);
609 assertEquals(0.0, solution.getPoint()[4], .0000001);
610 assertEquals(1438556.7491409, solution.getValue(), .0000001);
611 }
612
613 @Test
614 void testEpsilon() {
615 LinearObjectiveFunction f =
616 new LinearObjectiveFunction(new double[] { 10, 5, 1 }, 0);
617 Collection<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
618 constraints.add(new LinearConstraint(new double[] { 9, 8, 0 }, Relationship.EQ, 17));
619 constraints.add(new LinearConstraint(new double[] { 0, 7, 8 }, Relationship.LEQ, 7));
620 constraints.add(new LinearConstraint(new double[] { 10, 0, 2 }, Relationship.LEQ, 10));
621
622 SimplexSolver solver = new SimplexSolver();
623 PointValuePair solution = solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
624 GoalType.MAXIMIZE, new NonNegativeConstraint(false));
625 assertEquals(1.0, solution.getPoint()[0], 0.0);
626 assertEquals(1.0, solution.getPoint()[1], 0.0);
627 assertEquals(0.0, solution.getPoint()[2], 0.0);
628 assertEquals(15.0, solution.getValue(), 0.0);
629 }
630
631 @Test
632 void testTrivialModel() {
633 LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 1, 1 }, 0);
634 Collection<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
635 constraints.add(new LinearConstraint(new double[] { 1, 1 }, Relationship.EQ, 0));
636
637 SimplexSolver solver = new SimplexSolver();
638 PointValuePair solution = solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
639 GoalType.MAXIMIZE, new NonNegativeConstraint(true));
640 assertEquals(0, solution.getValue(), .0000001);
641 }
642
643 @Test
644 void testLargeModel() {
645 double[] objective = new double[] {
646 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
647 1, 1, 12, 1, 1, 1, 1, 1, 1, 1,
648 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
649 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
650 12, 1, 1, 1, 1, 1, 1, 1, 1, 1,
651 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
652 1, 1, 1, 1, 1, 1, 1, 1, 12, 1,
653 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
654 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
655 1, 1, 1, 1, 1, 1, 12, 1, 1, 1,
656 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
657 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
658 1, 1, 1, 1, 12, 1, 1, 1, 1, 1,
659 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
660 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
661 1, 1, 12, 1, 1, 1, 1, 1, 1, 1,
662 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
663 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
664 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
665 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
666 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
667 1, 1, 1, 1, 1, 1};
668
669 LinearObjectiveFunction f = new LinearObjectiveFunction(objective, 0);
670 Collection<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
671 constraints.add(equationFromString(objective.length, "x0 + x1 + x2 + x3 - x12 = 0"));
672 constraints.add(equationFromString(objective.length, "x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 - x13 = 0"));
673 constraints.add(equationFromString(objective.length, "x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 >= 49"));
674 constraints.add(equationFromString(objective.length, "x0 + x1 + x2 + x3 >= 42"));
675 constraints.add(equationFromString(objective.length, "x14 + x15 + x16 + x17 - x26 = 0"));
676 constraints.add(equationFromString(objective.length, "x18 + x19 + x20 + x21 + x22 + x23 + x24 + x25 - x27 = 0"));
677 constraints.add(equationFromString(objective.length, "x14 + x15 + x16 + x17 - x12 = 0"));
678 constraints.add(equationFromString(objective.length, "x18 + x19 + x20 + x21 + x22 + x23 + x24 + x25 - x13 = 0"));
679 constraints.add(equationFromString(objective.length, "x28 + x29 + x30 + x31 - x40 = 0"));
680 constraints.add(equationFromString(objective.length, "x32 + x33 + x34 + x35 + x36 + x37 + x38 + x39 - x41 = 0"));
681 constraints.add(equationFromString(objective.length, "x32 + x33 + x34 + x35 + x36 + x37 + x38 + x39 >= 49"));
682 constraints.add(equationFromString(objective.length, "x28 + x29 + x30 + x31 >= 42"));
683 constraints.add(equationFromString(objective.length, "x42 + x43 + x44 + x45 - x54 = 0"));
684 constraints.add(equationFromString(objective.length, "x46 + x47 + x48 + x49 + x50 + x51 + x52 + x53 - x55 = 0"));
685 constraints.add(equationFromString(objective.length, "x42 + x43 + x44 + x45 - x40 = 0"));
686 constraints.add(equationFromString(objective.length, "x46 + x47 + x48 + x49 + x50 + x51 + x52 + x53 - x41 = 0"));
687 constraints.add(equationFromString(objective.length, "x56 + x57 + x58 + x59 - x68 = 0"));
688 constraints.add(equationFromString(objective.length, "x60 + x61 + x62 + x63 + x64 + x65 + x66 + x67 - x69 = 0"));
689 constraints.add(equationFromString(objective.length, "x60 + x61 + x62 + x63 + x64 + x65 + x66 + x67 >= 51"));
690 constraints.add(equationFromString(objective.length, "x56 + x57 + x58 + x59 >= 44"));
691 constraints.add(equationFromString(objective.length, "x70 + x71 + x72 + x73 - x82 = 0"));
692 constraints.add(equationFromString(objective.length, "x74 + x75 + x76 + x77 + x78 + x79 + x80 + x81 - x83 = 0"));
693 constraints.add(equationFromString(objective.length, "x70 + x71 + x72 + x73 - x68 = 0"));
694 constraints.add(equationFromString(objective.length, "x74 + x75 + x76 + x77 + x78 + x79 + x80 + x81 - x69 = 0"));
695 constraints.add(equationFromString(objective.length, "x84 + x85 + x86 + x87 - x96 = 0"));
696 constraints.add(equationFromString(objective.length, "x88 + x89 + x90 + x91 + x92 + x93 + x94 + x95 - x97 = 0"));
697 constraints.add(equationFromString(objective.length, "x88 + x89 + x90 + x91 + x92 + x93 + x94 + x95 >= 51"));
698 constraints.add(equationFromString(objective.length, "x84 + x85 + x86 + x87 >= 44"));
699 constraints.add(equationFromString(objective.length, "x98 + x99 + x100 + x101 - x110 = 0"));
700 constraints.add(equationFromString(objective.length, "x102 + x103 + x104 + x105 + x106 + x107 + x108 + x109 - x111 = 0"));
701 constraints.add(equationFromString(objective.length, "x98 + x99 + x100 + x101 - x96 = 0"));
702 constraints.add(equationFromString(objective.length, "x102 + x103 + x104 + x105 + x106 + x107 + x108 + x109 - x97 = 0"));
703 constraints.add(equationFromString(objective.length, "x112 + x113 + x114 + x115 - x124 = 0"));
704 constraints.add(equationFromString(objective.length, "x116 + x117 + x118 + x119 + x120 + x121 + x122 + x123 - x125 = 0"));
705 constraints.add(equationFromString(objective.length, "x116 + x117 + x118 + x119 + x120 + x121 + x122 + x123 >= 49"));
706 constraints.add(equationFromString(objective.length, "x112 + x113 + x114 + x115 >= 42"));
707 constraints.add(equationFromString(objective.length, "x126 + x127 + x128 + x129 - x138 = 0"));
708 constraints.add(equationFromString(objective.length, "x130 + x131 + x132 + x133 + x134 + x135 + x136 + x137 - x139 = 0"));
709 constraints.add(equationFromString(objective.length, "x126 + x127 + x128 + x129 - x124 = 0"));
710 constraints.add(equationFromString(objective.length, "x130 + x131 + x132 + x133 + x134 + x135 + x136 + x137 - x125 = 0"));
711 constraints.add(equationFromString(objective.length, "x140 + x141 + x142 + x143 - x152 = 0"));
712 constraints.add(equationFromString(objective.length, "x144 + x145 + x146 + x147 + x148 + x149 + x150 + x151 - x153 = 0"));
713 constraints.add(equationFromString(objective.length, "x144 + x145 + x146 + x147 + x148 + x149 + x150 + x151 >= 59"));
714 constraints.add(equationFromString(objective.length, "x140 + x141 + x142 + x143 >= 42"));
715 constraints.add(equationFromString(objective.length, "x154 + x155 + x156 + x157 - x166 = 0"));
716 constraints.add(equationFromString(objective.length, "x158 + x159 + x160 + x161 + x162 + x163 + x164 + x165 - x167 = 0"));
717 constraints.add(equationFromString(objective.length, "x154 + x155 + x156 + x157 - x152 = 0"));
718 constraints.add(equationFromString(objective.length, "x158 + x159 + x160 + x161 + x162 + x163 + x164 + x165 - x153 = 0"));
719 constraints.add(equationFromString(objective.length, "x83 + x82 - x168 = 0"));
720 constraints.add(equationFromString(objective.length, "x111 + x110 - x169 = 0"));
721 constraints.add(equationFromString(objective.length, "x170 - x182 = 0"));
722 constraints.add(equationFromString(objective.length, "x171 - x183 = 0"));
723 constraints.add(equationFromString(objective.length, "x172 - x184 = 0"));
724 constraints.add(equationFromString(objective.length, "x173 - x185 = 0"));
725 constraints.add(equationFromString(objective.length, "x174 - x186 = 0"));
726 constraints.add(equationFromString(objective.length, "x175 + x176 - x187 = 0"));
727 constraints.add(equationFromString(objective.length, "x177 - x188 = 0"));
728 constraints.add(equationFromString(objective.length, "x178 - x189 = 0"));
729 constraints.add(equationFromString(objective.length, "x179 - x190 = 0"));
730 constraints.add(equationFromString(objective.length, "x180 - x191 = 0"));
731 constraints.add(equationFromString(objective.length, "x181 - x192 = 0"));
732 constraints.add(equationFromString(objective.length, "x170 - x26 = 0"));
733 constraints.add(equationFromString(objective.length, "x171 - x27 = 0"));
734 constraints.add(equationFromString(objective.length, "x172 - x54 = 0"));
735 constraints.add(equationFromString(objective.length, "x173 - x55 = 0"));
736 constraints.add(equationFromString(objective.length, "x174 - x168 = 0"));
737 constraints.add(equationFromString(objective.length, "x177 - x169 = 0"));
738 constraints.add(equationFromString(objective.length, "x178 - x138 = 0"));
739 constraints.add(equationFromString(objective.length, "x179 - x139 = 0"));
740 constraints.add(equationFromString(objective.length, "x180 - x166 = 0"));
741 constraints.add(equationFromString(objective.length, "x181 - x167 = 0"));
742 constraints.add(equationFromString(objective.length, "x193 - x205 = 0"));
743 constraints.add(equationFromString(objective.length, "x194 - x206 = 0"));
744 constraints.add(equationFromString(objective.length, "x195 - x207 = 0"));
745 constraints.add(equationFromString(objective.length, "x196 - x208 = 0"));
746 constraints.add(equationFromString(objective.length, "x197 - x209 = 0"));
747 constraints.add(equationFromString(objective.length, "x198 + x199 - x210 = 0"));
748 constraints.add(equationFromString(objective.length, "x200 - x211 = 0"));
749 constraints.add(equationFromString(objective.length, "x201 - x212 = 0"));
750 constraints.add(equationFromString(objective.length, "x202 - x213 = 0"));
751 constraints.add(equationFromString(objective.length, "x203 - x214 = 0"));
752 constraints.add(equationFromString(objective.length, "x204 - x215 = 0"));
753 constraints.add(equationFromString(objective.length, "x193 - x182 = 0"));
754 constraints.add(equationFromString(objective.length, "x194 - x183 = 0"));
755 constraints.add(equationFromString(objective.length, "x195 - x184 = 0"));
756 constraints.add(equationFromString(objective.length, "x196 - x185 = 0"));
757 constraints.add(equationFromString(objective.length, "x197 - x186 = 0"));
758 constraints.add(equationFromString(objective.length, "x198 + x199 - x187 = 0"));
759 constraints.add(equationFromString(objective.length, "x200 - x188 = 0"));
760 constraints.add(equationFromString(objective.length, "x201 - x189 = 0"));
761 constraints.add(equationFromString(objective.length, "x202 - x190 = 0"));
762 constraints.add(equationFromString(objective.length, "x203 - x191 = 0"));
763 constraints.add(equationFromString(objective.length, "x204 - x192 = 0"));
764
765 SimplexSolver solver = new SimplexSolver();
766 PointValuePair solution = solver.optimize(DEFAULT_MAX_ITER, f, new LinearConstraintSet(constraints),
767 GoalType.MINIMIZE, new NonNegativeConstraint(true));
768 assertEquals(7518.0, solution.getValue(), .0000001);
769 }
770
771 @Test
772 void testSolutionCallback() {
773
774
775
776 LinearObjectiveFunction f = new LinearObjectiveFunction(new double[] { 7, 3, 0, 0 }, 0 );
777
778 List<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
779 constraints.add(new LinearConstraint(new double[] { 3, 0, -5, 0 }, Relationship.LEQ, 0.0));
780 constraints.add(new LinearConstraint(new double[] { 2, 0, 0, -5 }, Relationship.LEQ, 0.0));
781 constraints.add(new LinearConstraint(new double[] { 0, 3, 0, -5 }, Relationship.LEQ, 0.0));
782 constraints.add(new LinearConstraint(new double[] { 1, 0, 0, 0 }, Relationship.LEQ, 1.0));
783 constraints.add(new LinearConstraint(new double[] { 0, 1, 0, 0 }, Relationship.LEQ, 1.0));
784
785 final SimplexSolver solver = new SimplexSolver();
786 final SolutionCallback callback = new SolutionCallback();
787
788 assertNull(callback.getSolution());
789 assertFalse(callback.isSolutionOptimal());
790
791 try {
792 solver.optimize(new MaxIter(3), f, new LinearConstraintSet(constraints),
793 GoalType.MAXIMIZE, new NonNegativeConstraint(true), callback);
794 fail("expected MathIllegalStateException");
795 } catch (MathIllegalStateException ex) {
796
797 }
798
799 final PointValuePair solution = callback.getSolution();
800 assertNotNull(solution);
801 assertTrue(validSolution(solution, constraints, 1e-4));
802 assertFalse(callback.isSolutionOptimal());
803
804 assertEquals(7.0, solution.getValue(), 1e-4);
805 }
806
807 @Test
808 void testDimensionMatch() {
809 assertThrows(MathIllegalArgumentException.class, () -> {
810
811
812
813
814
815
816
817
818 LinearObjectiveFunction f = new LinearObjectiveFunction(new double[]{2, 15, 18}, 0);
819 Collection<LinearConstraint> constraints = new ArrayList<LinearConstraint>();
820
821 constraints.add(new LinearConstraint(new double[]{-1, 2 - 6}, Relationship.LEQ, -10));
822 constraints.add(new LinearConstraint(new double[]{0, 1, 2}, Relationship.LEQ, 6));
823 constraints.add(new LinearConstraint(new double[]{2, 0, 10}, Relationship.LEQ, 19));
824 constraints.add(new LinearConstraint(new double[]{-1, 1, 0}, Relationship.LEQ, -2));
825
826 SimplexSolver solver = new SimplexSolver();
827 solver.optimize(f,
828 new LinearConstraintSet(constraints),
829 new NonNegativeConstraint(true),
830 PivotSelectionRule.BLAND);
831 });
832 }
833
834
835
836
837
838 private LinearConstraint equationFromString(int numCoefficients, String s) {
839 Relationship relationship;
840 if (s.contains(">=")) {
841 relationship = Relationship.GEQ;
842 } else if (s.contains("<=")) {
843 relationship = Relationship.LEQ;
844 } else if (s.contains("=")) {
845 relationship = Relationship.EQ;
846 } else {
847 throw new IllegalArgumentException();
848 }
849
850 String[] equationParts = s.split("[>|<]?=");
851 double rhs = Double.parseDouble(equationParts[1].trim());
852
853 double[] lhs = new double[numCoefficients];
854 String left = equationParts[0].replaceAll(" ?x", "");
855 String[] coefficients = left.split(" ");
856 for (String coefficient : coefficients) {
857 double value = coefficient.charAt(0) == '-' ? -1 : 1;
858 int index = Integer.parseInt(coefficient.replaceFirst("[+|-]", "").trim());
859 lhs[index] = value;
860 }
861 return new LinearConstraint(lhs, relationship, rhs);
862 }
863
864 private static boolean validSolution(PointValuePair solution, List<LinearConstraint> constraints, double epsilon) {
865 double[] vals = solution.getPoint();
866 for (LinearConstraint c : constraints) {
867 double[] coeffs = c.getCoefficients().toArray();
868 double result = 0.0d;
869 for (int i = 0; i < vals.length; i++) {
870 result += vals[i] * coeffs[i];
871 }
872
873 switch (c.getRelationship()) {
874 case EQ:
875 if (!Precision.equals(result, c.getValue(), epsilon)) {
876 return false;
877 }
878 break;
879
880 case GEQ:
881 if (Precision.compareTo(result, c.getValue(), epsilon) < 0) {
882 return false;
883 }
884 break;
885
886 case LEQ:
887 if (Precision.compareTo(result, c.getValue(), epsilon) > 0) {
888 return false;
889 }
890 break;
891 }
892 }
893
894 return true;
895 }
896
897 }