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 PseudoOptDecorator extends PBSolverDecorator implements
48 IOptimizationProblem {
49
50
51
52
53 private static final long serialVersionUID = 1L;
54
55 private BigInteger objectiveValue;
56
57 private int[] prevmodel;
58 private int[] prevmodelwithadditionalvars;
59
60 private boolean[] prevfullmodel;
61
62 private IConstr previousPBConstr;
63
64 private boolean isSolutionOptimal;
65
66 private final boolean nonOptimalMeansSatisfiable;
67
68 private final boolean useAnImplicantForEvaluation;
69
70
71
72
73
74
75
76
77 public PseudoOptDecorator(IPBSolver solver) {
78 this(solver, true);
79 }
80
81
82
83
84
85
86
87
88
89
90
91 public PseudoOptDecorator(IPBSolver solver,
92 boolean nonOptimalMeansSatisfiable) {
93 this(solver, nonOptimalMeansSatisfiable, false);
94 }
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110 public PseudoOptDecorator(IPBSolver solver,
111 boolean nonOptimalMeansSatisfiable,
112 boolean useAnImplicantForEvaluation) {
113 super(solver);
114 this.nonOptimalMeansSatisfiable = nonOptimalMeansSatisfiable;
115 this.useAnImplicantForEvaluation = useAnImplicantForEvaluation;
116 }
117
118 @Override
119 public boolean isSatisfiable() throws TimeoutException {
120 return isSatisfiable(VecInt.EMPTY);
121 }
122
123 @Override
124 public boolean isSatisfiable(boolean global) throws TimeoutException {
125 return isSatisfiable(VecInt.EMPTY, global);
126 }
127
128 @Override
129 public boolean isSatisfiable(IVecInt assumps, boolean global)
130 throws TimeoutException {
131 boolean result = super.isSatisfiable(assumps, true);
132 if (result) {
133 this.prevmodel = super.model();
134 this.prevmodelwithadditionalvars = super
135 .modelWithInternalVariables();
136 this.prevfullmodel = new boolean[nVars()];
137 for (int i = 0; i < nVars(); i++) {
138 this.prevfullmodel[i] = decorated().model(i + 1);
139 }
140 } else {
141 if (this.previousPBConstr != null) {
142 decorated().removeConstr(this.previousPBConstr);
143 this.previousPBConstr = null;
144 }
145 }
146 return result;
147 }
148
149 @Override
150 public boolean isSatisfiable(IVecInt assumps) throws TimeoutException {
151 return isSatisfiable(assumps, true);
152 }
153
154 @Override
155 public void setObjectiveFunction(ObjectiveFunction objf) {
156 decorated().setObjectiveFunction(objf);
157 }
158
159 public boolean admitABetterSolution() throws TimeoutException {
160 return admitABetterSolution(VecInt.EMPTY);
161 }
162
163 public boolean admitABetterSolution(IVecInt assumps)
164 throws TimeoutException {
165 try {
166 this.isSolutionOptimal = false;
167 boolean result = super.isSatisfiable(assumps, true);
168 if (result) {
169 this.prevmodel = super.model();
170 this.prevmodelwithadditionalvars = super
171 .modelWithInternalVariables();
172 this.prevfullmodel = new boolean[nVars()];
173 for (int i = 0; i < nVars(); i++) {
174 this.prevfullmodel[i] = decorated().model(i + 1);
175 }
176 if (decorated().getObjectiveFunction() != null) {
177 calculateObjective();
178 }
179 } else {
180 this.isSolutionOptimal = true;
181 if (this.previousPBConstr != null) {
182 decorated().removeConstr(this.previousPBConstr);
183 this.previousPBConstr = null;
184 }
185 }
186 return result;
187 } catch (TimeoutException te) {
188 if (this.previousPBConstr != null) {
189 decorated().removeConstr(this.previousPBConstr);
190 this.previousPBConstr = null;
191 }
192 throw te;
193 }
194 }
195
196 public boolean hasNoObjectiveFunction() {
197 return decorated().getObjectiveFunction() == null;
198 }
199
200 public boolean nonOptimalMeansSatisfiable() {
201 return nonOptimalMeansSatisfiable;
202 }
203
204 public Number calculateObjective() {
205 if (decorated().getObjectiveFunction() == null) {
206 throw new UnsupportedOperationException(
207 "The problem does not contain an objective function");
208 }
209 if (this.useAnImplicantForEvaluation) {
210 this.objectiveValue = decorated().getObjectiveFunction()
211 .calculateDegreeImplicant(decorated());
212 } else {
213 this.objectiveValue = decorated().getObjectiveFunction()
214 .calculateDegree(decorated());
215 }
216 return getObjectiveValue();
217 }
218
219 public void discardCurrentSolution() throws ContradictionException {
220 if (this.previousPBConstr != null) {
221 super.removeSubsumedConstr(this.previousPBConstr);
222 }
223 if (decorated().getObjectiveFunction() != null
224 && this.objectiveValue != null) {
225 this.previousPBConstr = super.addPseudoBoolean(decorated()
226 .getObjectiveFunction().getVars(), decorated()
227 .getObjectiveFunction().getCoeffs(), false,
228 this.objectiveValue.subtract(BigInteger.ONE));
229 }
230 }
231
232 @Override
233 public void reset() {
234 this.previousPBConstr = null;
235 super.reset();
236 }
237
238 @Override
239 public int[] model() {
240
241 return this.prevmodel;
242 }
243
244 @Override
245 public boolean model(int var) {
246 return this.prevfullmodel[var - 1];
247 }
248
249 @Override
250 public String toString(String prefix) {
251 return prefix + "Pseudo Boolean Optimization by upper bound\n"
252 + super.toString(prefix);
253 }
254
255 public Number getObjectiveValue() {
256 return this.objectiveValue.add(decorated().getObjectiveFunction()
257 .getCorrection());
258 }
259
260 public void discard() throws ContradictionException {
261 discardCurrentSolution();
262 }
263
264 public void forceObjectiveValueTo(Number forcedValue)
265 throws ContradictionException {
266 super.addPseudoBoolean(decorated().getObjectiveFunction().getVars(),
267 decorated().getObjectiveFunction().getCoeffs(), false,
268 (BigInteger) forcedValue);
269 }
270
271 public boolean isOptimal() {
272 return this.isSolutionOptimal;
273 }
274
275 @Override
276 public int[] modelWithInternalVariables() {
277 return this.prevmodelwithadditionalvars;
278 }
279 }