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 package org.sat4j.pb;
29
30 import java.math.BigInteger;
31
32 import org.sat4j.core.VecInt;
33 import org.sat4j.specs.ContradictionException;
34 import org.sat4j.specs.IConstr;
35 import org.sat4j.specs.IOptimizationProblem;
36 import org.sat4j.specs.IVecInt;
37 import org.sat4j.specs.TimeoutException;
38
39
40
41
42
43
44
45 public class PseudoOptDecorator extends PBSolverDecorator implements
46 IOptimizationProblem {
47
48
49
50
51 private static final long serialVersionUID = 1L;
52
53 private BigInteger objectiveValue;
54
55 private int[] prevmodel;
56 private int[] prevmodelwithadditionalvars;
57
58 private boolean[] prevfullmodel;
59
60 private IConstr previousPBConstr;
61
62 private boolean isSolutionOptimal;
63
64 public PseudoOptDecorator(IPBSolver solver) {
65 super(solver);
66 }
67
68 @Override
69 public boolean isSatisfiable() throws TimeoutException {
70 return isSatisfiable(VecInt.EMPTY);
71 }
72
73 @Override
74 public boolean isSatisfiable(boolean global) throws TimeoutException {
75 return isSatisfiable(VecInt.EMPTY, global);
76 }
77
78 @Override
79 public boolean isSatisfiable(IVecInt assumps, boolean global)
80 throws TimeoutException {
81 boolean result = super.isSatisfiable(assumps, true);
82 if (result) {
83 prevmodel = super.model();
84 prevmodelwithadditionalvars = super.modelWithInternalVariables();
85 prevfullmodel = new boolean[nVars()];
86 for (int i = 0; i < nVars(); i++) {
87 prevfullmodel[i] = decorated().model(i + 1);
88 }
89 } else {
90 if (previousPBConstr != null) {
91 decorated().removeConstr(previousPBConstr);
92 previousPBConstr = null;
93 }
94 }
95 return result;
96 }
97
98 @Override
99 public boolean isSatisfiable(IVecInt assumps) throws TimeoutException {
100 return isSatisfiable(assumps, true);
101 }
102
103 @Override
104 public void setObjectiveFunction(ObjectiveFunction objf) {
105 decorated().setObjectiveFunction(objf);
106 }
107
108 public boolean admitABetterSolution() throws TimeoutException {
109 return admitABetterSolution(VecInt.EMPTY);
110 }
111
112 public boolean admitABetterSolution(IVecInt assumps)
113 throws TimeoutException {
114 try {
115 isSolutionOptimal = false;
116 boolean result = super.isSatisfiable(assumps, true);
117 if (result) {
118 prevmodel = super.model();
119 prevmodelwithadditionalvars = super
120 .modelWithInternalVariables();
121 prevfullmodel = new boolean[nVars()];
122 for (int i = 0; i < nVars(); i++) {
123 prevfullmodel[i] = decorated().model(i + 1);
124 }
125 if (decorated().getObjectiveFunction() != null) {
126 calculateObjective();
127 }
128 } else {
129 isSolutionOptimal = true;
130 if (previousPBConstr != null) {
131 decorated().removeConstr(previousPBConstr);
132 previousPBConstr = null;
133 }
134 }
135 return result;
136 } catch (TimeoutException te) {
137 if (previousPBConstr != null) {
138 decorated().removeConstr(previousPBConstr);
139 previousPBConstr = null;
140 }
141 throw te;
142 }
143 }
144
145 public boolean hasNoObjectiveFunction() {
146 return decorated().getObjectiveFunction() == null;
147 }
148
149 public boolean nonOptimalMeansSatisfiable() {
150 return true;
151 }
152
153 public Number calculateObjective() {
154 if (decorated().getObjectiveFunction() == null) {
155 throw new UnsupportedOperationException(
156 "The problem does not contain an objective function");
157 }
158 objectiveValue = decorated().getObjectiveFunction().calculateDegree(
159 decorated());
160 return getObjectiveValue();
161 }
162
163 public void discardCurrentSolution() throws ContradictionException {
164 if (previousPBConstr != null) {
165 super.removeSubsumedConstr(previousPBConstr);
166 }
167 if (decorated().getObjectiveFunction() != null
168 && objectiveValue != null) {
169 previousPBConstr = super.addPseudoBoolean(decorated()
170 .getObjectiveFunction().getVars(), decorated()
171 .getObjectiveFunction().getCoeffs(), false, objectiveValue
172 .subtract(BigInteger.ONE));
173 }
174 }
175
176 @Override
177 public void reset() {
178 previousPBConstr = null;
179 super.reset();
180 }
181
182 @Override
183 public int[] model() {
184
185 return prevmodel;
186 }
187
188 @Override
189 public boolean model(int var) {
190 return prevfullmodel[var - 1];
191 }
192
193 @Override
194 public String toString(String prefix) {
195 return prefix + "Pseudo Boolean Optimization by upper bound\n"
196 + super.toString(prefix);
197 }
198
199 public Number getObjectiveValue() {
200 return objectiveValue.add(decorated().getObjectiveFunction()
201 .getCorrection());
202 }
203
204 public void discard() throws ContradictionException {
205 discardCurrentSolution();
206 }
207
208 public void forceObjectiveValueTo(Number forcedValue)
209 throws ContradictionException {
210 super.addPseudoBoolean(decorated().getObjectiveFunction().getVars(),
211 decorated().getObjectiveFunction().getCoeffs(), false,
212 (BigInteger) forcedValue);
213 }
214
215 public boolean isOptimal() {
216 return isSolutionOptimal;
217 }
218
219 @Override
220 public int[] modelWithInternalVariables() {
221 return prevmodelwithadditionalvars;
222 }
223 }