1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 package org.sat4j.pb;
31
32 import java.math.BigInteger;
33
34 import org.sat4j.specs.ContradictionException;
35 import org.sat4j.specs.IConstr;
36 import org.sat4j.specs.IVec;
37 import org.sat4j.specs.IVecInt;
38 import org.sat4j.specs.IteratorInt;
39 import org.sat4j.specs.TimeoutException;
40 import org.sat4j.tools.DimacsStringSolver;
41
42
43
44
45
46
47
48
49
50
51
52
53 public class LPStringSolver extends DimacsStringSolver implements IPBSolver {
54
55 private static final String FAKE_I_CONSTR_MSG = "Fake IConstr";
56
57
58
59
60 private static final long serialVersionUID = 1L;
61
62 private int indxConstrObj;
63
64 private int nbOfConstraints;
65
66 private ObjectiveFunction obj;
67
68 private boolean inserted = false;
69
70 private static final IConstr FAKE_CONSTR = new IConstr() {
71
72 public int size() {
73 throw new UnsupportedOperationException(FAKE_I_CONSTR_MSG);
74 }
75
76 public boolean learnt() {
77 throw new UnsupportedOperationException(FAKE_I_CONSTR_MSG);
78 }
79
80 public double getActivity() {
81 throw new UnsupportedOperationException(FAKE_I_CONSTR_MSG);
82 }
83
84 public int get(int i) {
85 throw new UnsupportedOperationException(FAKE_I_CONSTR_MSG);
86 }
87
88 public boolean canBePropagatedMultipleTimes() {
89 throw new UnsupportedOperationException(FAKE_I_CONSTR_MSG);
90 }
91 };
92
93
94
95
96 public LPStringSolver() {
97 }
98
99
100
101
102 public LPStringSolver(int initSize) {
103 super(initSize);
104 }
105
106 @Override
107 public boolean isSatisfiable(IVecInt assumps) throws TimeoutException {
108 for (IteratorInt it = assumps.iterator(); it.hasNext();) {
109 int p = it.next();
110 if (p > 0) {
111 getOut().append("x" + p + " >= 1 \n");
112 } else {
113 getOut().append("- x" + -p + " >= 0 \n");
114 }
115 this.nbOfConstraints++;
116 }
117 throw new TimeoutException();
118 }
119
120 @Override
121 public boolean isSatisfiable(IVecInt assumps, boolean global)
122 throws TimeoutException {
123 return super.isSatisfiable(assumps, global);
124 }
125
126 public IConstr addPseudoBoolean(IVecInt lits, IVec<BigInteger> coeffs,
127 boolean moreThan, BigInteger d) throws ContradictionException {
128 if (moreThan) {
129 return addAtLeast(lits, coeffs, d);
130 }
131 return addAtMost(lits, coeffs, d);
132 }
133
134 public void setObjectiveFunction(ObjectiveFunction obj) {
135 this.obj = obj;
136 }
137
138 @Override
139 public IConstr addAtLeast(IVecInt literals, int degree)
140 throws ContradictionException {
141 StringBuffer out = getOut();
142 this.nbOfConstraints++;
143 int negationweight = 0;
144 int p;
145 boolean first = true;
146 for (IteratorInt iterator = literals.iterator(); iterator.hasNext();) {
147 p = iterator.next();
148 assert p != 0;
149 if (first) {
150 if (p > 0) {
151 getOut().append("x" + p + " ");
152 } else {
153 getOut().append("- x" + -p + " ");
154 negationweight++;
155 }
156 first = false;
157 } else {
158 if (p > 0) {
159 out.append("+ x" + p + " ");
160 } else {
161 out.append("- x" + -p + " ");
162 negationweight++;
163 }
164 }
165 }
166 out.append(">= " + (degree - negationweight) + " \n");
167 return FAKE_CONSTR;
168 }
169
170 @Override
171 public IConstr addAtMost(IVecInt literals, int degree)
172 throws ContradictionException {
173 StringBuffer out = getOut();
174 this.nbOfConstraints++;
175 int negationweight = 0;
176 int p;
177 boolean first = true;
178 for (IteratorInt iterator = literals.iterator(); iterator.hasNext();) {
179 p = iterator.next();
180 assert p != 0;
181 if (first) {
182 if (p > 0) {
183 getOut().append("- x" + p + " ");
184 } else {
185 getOut().append("x" + -p + " ");
186 negationweight++;
187 }
188 first = false;
189 } else {
190 if (p > 0) {
191 out.append("- x" + p + " ");
192 } else {
193 out.append("+ x" + -p + " ");
194 negationweight++;
195 }
196 }
197 }
198 out.append(">= " + (-degree + negationweight) + " \n");
199 return FAKE_CONSTR;
200 }
201
202 @Override
203 public IConstr addClause(IVecInt literals) throws ContradictionException {
204 StringBuffer out = getOut();
205 this.nbOfConstraints++;
206 int lit;
207 boolean first = true;
208 int negationweight = 0;
209 for (IteratorInt iterator = literals.iterator(); iterator.hasNext();) {
210 lit = iterator.next();
211
212 if (first) {
213 if (lit > 0) {
214 out.append("x" + lit + " ");
215 } else {
216 out.append("-x" + -lit + " ");
217 negationweight++;
218 }
219 first = false;
220 } else {
221 if (lit > 0) {
222 out.append("+ x" + lit + " ");
223 } else {
224 out.append("- x" + -lit + " ");
225 negationweight++;
226 }
227 }
228 }
229 out.append(">= " + (1 - negationweight) + "\n");
230 return FAKE_CONSTR;
231 }
232
233
234
235
236
237
238 public String getExplanation() {
239
240 return null;
241 }
242
243
244
245
246
247
248
249
250 public void setListOfVariablesForExplanation(IVecInt listOfVariables) {
251
252
253 }
254
255 public void objectiveFunctionToLP(ObjectiveFunction obj, StringBuffer buffer) {
256 buffer.append("Minimize \n");
257 buffer.append("obj: ");
258 IVecInt variables = obj.getVars();
259 IVec<BigInteger> coeffs = obj.getCoeffs();
260 int n = variables.size();
261 if (n > 0) {
262 buffer.append(coeffs.get(0));
263 buffer.append("x");
264 buffer.append(variables.get(0));
265 buffer.append(" ");
266 }
267 BigInteger coeff;
268 for (int i = 1; i < n; i++) {
269 coeff = coeffs.get(i);
270 if (coeff.signum() > 0) {
271 buffer.append("+ " + coeff);
272 } else {
273 buffer.append("- " + coeff.negate());
274 }
275 buffer.append("x");
276 buffer.append(variables.get(i));
277 buffer.append(" ");
278 }
279
280 }
281
282 @Override
283 public String toString() {
284 StringBuffer out = getOut();
285 if (!this.inserted) {
286 StringBuffer tmp = new StringBuffer();
287
288
289
290
291 if (this.obj != null) {
292 objectiveFunctionToLP(this.obj, tmp);
293 tmp.append("\n");
294 tmp.append("Subject To\n ");
295 }
296
297 out.insert(this.indxConstrObj, tmp.toString());
298 this.inserted = true;
299 }
300
301 out.append("Binary \n");
302
303
304 for (int i = 1; i <= nVars(); i++) {
305 out.append("x" + i + "\n");
306 }
307 out.append("\n");
308 out.append("End");
309 return out.toString();
310 }
311
312 @Override
313 public String toString(String prefix) {
314 return toString();
315 }
316
317 @Override
318 public int newVar(int howmany) {
319 StringBuffer out = getOut();
320 setNbVars(howmany);
321
322 this.indxConstrObj = out.length();
323 out.append("\n");
324 return howmany;
325 }
326
327 @Override
328 public void setExpectedNumberOfClauses(int nb) {
329 }
330
331 public ObjectiveFunction getObjectiveFunction() {
332 return this.obj;
333 }
334
335 @Override
336 public int nConstraints() {
337 return this.nbOfConstraints;
338 }
339
340 public IConstr addAtMost(IVecInt literals, IVecInt coeffs, int degree)
341 throws ContradictionException {
342 StringBuffer out = getOut();
343 assert literals.size() == coeffs.size();
344 this.nbOfConstraints++;
345 int n = literals.size();
346 if (n > 0) {
347 out.append(-coeffs.get(0));
348 out.append("x");
349 out.append(literals.get(0));
350 out.append(" ");
351 }
352 int coeff;
353 for (int i = 1; i < n; i++) {
354 coeff = coeffs.get(i);
355 if (coeff > 0) {
356 out.append("+ " + -coeff);
357 } else {
358 out.append("- " + coeff);
359 }
360 out.append("x");
361 out.append(literals.get(i));
362 out.append(" ");
363 }
364 out.append(">= ");
365 out.append(-degree);
366 out.append(" \n");
367 return FAKE_CONSTR;
368 }
369
370 public IConstr addAtMost(IVecInt literals, IVec<BigInteger> coeffs,
371 BigInteger degree) throws ContradictionException {
372 StringBuffer out = getOut();
373 assert literals.size() == coeffs.size();
374 this.nbOfConstraints++;
375 int n = literals.size();
376 if (n > 0) {
377 out.append(coeffs.get(0).negate());
378 out.append("x");
379 out.append(literals.get(0));
380 out.append(" ");
381 }
382 BigInteger coeff;
383 for (int i = 1; i < n; i++) {
384 coeff = coeffs.get(i);
385 if (coeff.signum() < 0) {
386 out.append("+ " + coeff.negate());
387 } else {
388 out.append("- " + coeff);
389 }
390 out.append("x");
391 out.append(literals.get(i));
392 out.append(" ");
393 }
394 out.append(">= ");
395 out.append(degree.negate());
396 out.append(" \n");
397 return FAKE_CONSTR;
398 }
399
400 public IConstr addAtLeast(IVecInt literals, IVecInt coeffs, int degree)
401 throws ContradictionException {
402 StringBuffer out = getOut();
403 assert literals.size() == coeffs.size();
404 this.nbOfConstraints++;
405 int n = literals.size();
406 if (n > 0) {
407 out.append(coeffs.get(0));
408 out.append("x");
409 out.append(literals.get(0));
410 out.append(" ");
411 }
412 int coeff;
413 for (int i = 1; i < n; i++) {
414 coeff = coeffs.get(i);
415 if (coeff > 0) {
416 out.append("+ " + coeff);
417 } else {
418 out.append("- " + coeff * -1);
419 }
420 out.append("x");
421 out.append(literals.get(i));
422 out.append(" ");
423 }
424 out.append(">= ");
425 out.append(degree);
426 out.append(" \n");
427 return FAKE_CONSTR;
428 }
429
430 public IConstr addAtLeast(IVecInt literals, IVec<BigInteger> coeffs,
431 BigInteger degree) throws ContradictionException {
432 StringBuffer out = getOut();
433 assert literals.size() == coeffs.size();
434 this.nbOfConstraints++;
435 int n = literals.size();
436 if (n > 0) {
437 out.append(coeffs.get(0));
438 out.append("x");
439 out.append(literals.get(0));
440 out.append(" ");
441 }
442 BigInteger coeff;
443 for (int i = 1; i < n; i++) {
444 coeff = coeffs.get(i);
445 if (coeff.signum() > 0) {
446 out.append("+ " + coeff);
447 } else {
448 out.append("- " + coeff.negate());
449 }
450 out.append("x");
451 out.append(literals.get(i));
452 out.append(" ");
453 }
454 out.append(">= ");
455 out.append(degree);
456 out.append(" \n");
457 return FAKE_CONSTR;
458
459 }
460
461 public IConstr addExactly(IVecInt literals, IVecInt coeffs, int weight)
462 throws ContradictionException {
463 StringBuffer out = getOut();
464 assert literals.size() == coeffs.size();
465 this.nbOfConstraints++;
466 int n = literals.size();
467 if (n > 0) {
468 out.append(coeffs.get(0));
469 out.append("x");
470 out.append(literals.get(0));
471 out.append(" ");
472 }
473 int coeff;
474 for (int i = 1; i < n; i++) {
475 coeff = coeffs.get(i);
476 if (coeff > 0) {
477 out.append("+ " + coeff);
478 } else {
479 out.append("- " + coeff * -1);
480 }
481 out.append("x");
482 out.append(literals.get(i));
483 out.append(" ");
484 }
485 out.append("= ");
486 out.append(weight);
487 out.append(" \n");
488 return FAKE_CONSTR;
489 }
490
491 public IConstr addExactly(IVecInt literals, IVec<BigInteger> coeffs,
492 BigInteger weight) throws ContradictionException {
493 StringBuffer out = getOut();
494 assert literals.size() == coeffs.size();
495 this.nbOfConstraints++;
496 int n = literals.size();
497 if (n > 0) {
498 out.append(coeffs.get(0));
499 out.append("x");
500 out.append(literals.get(0));
501 out.append(" ");
502 }
503 BigInteger coeff;
504 for (int i = 1; i < n; i++) {
505 coeff = coeffs.get(i);
506 if (coeff.signum() > 0) {
507 out.append("+ " + coeff);
508 } else {
509 out.append("- " + coeff.negate());
510 }
511 out.append("x");
512 out.append(literals.get(i));
513 out.append(" ");
514 }
515 out.append("= ");
516 out.append(weight);
517 out.append(" \n");
518 return FAKE_CONSTR;
519 }
520
521 }