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.core.VecInt;
35 import org.sat4j.specs.ContradictionException;
36 import org.sat4j.specs.IConstr;
37 import org.sat4j.specs.IOptimizationProblem;
38 import org.sat4j.specs.IVecInt;
39 import org.sat4j.specs.TimeoutException;
40
41
42
43
44
45
46
47 public class ConstraintRelaxingPseudoOptDecorator extends PBSolverDecorator
48 implements IOptimizationProblem {
49
50 private static final long serialVersionUID = 1L;
51 private int[] bestModel;
52 private boolean[] bestFullModel;
53 private IConstr previousPBConstr;
54 private IConstr addedConstr = null;
55 private int maxValue = 0;
56 private Number objectiveValue;
57 private boolean optimumFound = false;
58
59 public ConstraintRelaxingPseudoOptDecorator(IPBSolver solver) {
60 super(solver);
61 }
62
63 @Override
64 public boolean isSatisfiable() throws TimeoutException {
65 return isSatisfiable(VecInt.EMPTY);
66 }
67
68 @Override
69 public boolean isSatisfiable(boolean global) throws TimeoutException {
70 return isSatisfiable(VecInt.EMPTY, global);
71 }
72
73 @Override
74 public boolean isSatisfiable(IVecInt assumps, boolean global)
75 throws TimeoutException {
76 boolean result = super.isSatisfiable(assumps, true);
77 if (result) {
78 this.bestModel = super.model();
79 this.bestFullModel = new boolean[nVars()];
80 for (int i = 0; i < nVars(); i++) {
81 this.bestFullModel[i] = decorated().model(i + 1);
82 }
83 calculateObjective();
84 } else {
85 if (this.previousPBConstr != null) {
86 decorated().removeConstr(this.previousPBConstr);
87 this.previousPBConstr = null;
88 }
89 }
90 return result;
91 }
92
93 @Override
94 public boolean isSatisfiable(IVecInt assumps) throws TimeoutException {
95 return isSatisfiable(assumps, true);
96 }
97
98 public boolean admitABetterSolution() throws TimeoutException {
99 return admitABetterSolution(VecInt.EMPTY);
100 }
101
102 public boolean admitABetterSolution(IVecInt assumps)
103 throws TimeoutException {
104 boolean isSatisfiable;
105
106 if (this.optimumFound) {
107 return false;
108 }
109 this.maxValue = getObjectiveFunction().minValue().intValue();
110 while (true) {
111 if (this.addedConstr != null) {
112 this.decorated().removeConstr(this.addedConstr);
113 }
114 try {
115 forceObjectiveValueTo(this.maxValue++);
116 } catch (ContradictionException e) {
117 if (isVerbose()) {
118 System.out.println(decorated().getLogPrefix()
119 + "no solution for objective value "
120 + (this.maxValue - 1));
121 }
122 continue;
123 }
124 isSatisfiable = super.isSatisfiable(assumps, true);
125 if (isSatisfiable) {
126 this.optimumFound = true;
127 this.bestModel = super.model();
128 this.bestFullModel = new boolean[nVars()];
129 for (int i = 0; i < nVars(); i++) {
130 this.bestFullModel[i] = decorated().model(i + 1);
131 }
132 if (getObjectiveFunction() != null) {
133 calculateObjective();
134 }
135 this.decorated().removeConstr(this.addedConstr);
136 return true;
137 }
138 if (isVerbose()) {
139 System.out.println(decorated().getLogPrefix()
140 + "no solution for objective value "
141 + (this.maxValue - 1));
142 }
143 }
144 }
145
146 public boolean hasNoObjectiveFunction() {
147 return getObjectiveFunction() == null;
148 }
149
150 public boolean nonOptimalMeansSatisfiable() {
151 return false;
152 }
153
154 @Deprecated
155 public Number calculateObjective() {
156 if (getObjectiveFunction() == null) {
157 throw new UnsupportedOperationException(
158 "The problem does not contain an objective function");
159 }
160 this.objectiveValue = getObjectiveFunction().calculateDegree(this);
161 return this.objectiveValue;
162 }
163
164 public Number getObjectiveValue() {
165 return this.objectiveValue;
166 }
167
168 public void forceObjectiveValueTo(Number forcedValue)
169 throws ContradictionException {
170 this.addedConstr = super.addPseudoBoolean(getObjectiveFunction()
171 .getVars(), getObjectiveFunction().getCoeffs(), false,
172 BigInteger.valueOf(forcedValue.longValue()));
173 }
174
175 @Deprecated
176 public void discard() {
177 discardCurrentSolution();
178 }
179
180 public void discardCurrentSolution() {
181
182 }
183
184 public boolean isOptimal() {
185 return this.optimumFound;
186 }
187
188 @Override
189 public String toString(String prefix) {
190 return prefix + "Pseudo Boolean Optimization by lower bound\n"
191 + super.toString(prefix);
192 }
193
194 }