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 ObjectiveFunction objfct;
54
55 private BigInteger objectiveValue;
56
57 private int[] prevmodel;
58 private boolean[] prevfullmodel;
59
60 private IConstr previousPBConstr;
61
62 public PseudoOptDecorator(IPBSolver solver) {
63 super(solver);
64 }
65
66 @Override
67 public boolean isSatisfiable() throws TimeoutException {
68 return isSatisfiable(VecInt.EMPTY);
69 }
70
71 @Override
72 public boolean isSatisfiable(boolean global) throws TimeoutException {
73 return isSatisfiable(VecInt.EMPTY, global);
74 }
75
76 @Override
77 public boolean isSatisfiable(IVecInt assumps, boolean global)
78 throws TimeoutException {
79 boolean result = super.isSatisfiable(assumps, true);
80 if (result) {
81 prevmodel = super.model();
82 prevfullmodel = new boolean[nVars()];
83 for (int i = 0; i < nVars(); i++) {
84 prevfullmodel[i] = decorated().model(i + 1);
85 }
86 } else {
87 if (previousPBConstr != null) {
88 decorated().removeConstr(previousPBConstr);
89 previousPBConstr = null;
90 }
91 }
92 return result;
93 }
94
95 @Override
96 public boolean isSatisfiable(IVecInt assumps) throws TimeoutException {
97 return isSatisfiable(assumps, true);
98 }
99
100 @Override
101 public void setObjectiveFunction(ObjectiveFunction objf) {
102 objfct = objf;
103 decorated().setObjectiveFunction(objf);
104 }
105
106 public boolean admitABetterSolution() throws TimeoutException {
107 return admitABetterSolution(VecInt.EMPTY);
108 }
109
110 public boolean admitABetterSolution(IVecInt assumps)
111 throws TimeoutException {
112 try {
113 boolean result = super.isSatisfiable(assumps, true);
114 if (result) {
115 prevmodel = super.model();
116 prevfullmodel = new boolean[nVars()];
117 for (int i = 0; i < nVars(); i++) {
118 prevfullmodel[i] = decorated().model(i + 1);
119 }
120 if (objfct != null) {
121 calculateObjective();
122 }
123 } else {
124 if (previousPBConstr != null) {
125 decorated().removeConstr(previousPBConstr);
126 previousPBConstr = null;
127 }
128 }
129 return result;
130 } catch (TimeoutException te) {
131 if (previousPBConstr != null) {
132 decorated().removeConstr(previousPBConstr);
133 previousPBConstr = null;
134 }
135 throw te;
136 }
137 }
138
139 public boolean hasNoObjectiveFunction() {
140 return objfct == null;
141 }
142
143 public boolean nonOptimalMeansSatisfiable() {
144 return true;
145 }
146
147 public Number calculateObjective() {
148 if (objfct == null) {
149 throw new UnsupportedOperationException(
150 "The problem does not contain an objective function");
151 }
152 objectiveValue = objfct.calculateDegree(prevmodel);
153 return objectiveValue;
154 }
155
156 public void discardCurrentSolution() throws ContradictionException {
157 if (previousPBConstr != null) {
158 super.removeSubsumedConstr(previousPBConstr);
159 }
160 if (objfct != null && objectiveValue != null) {
161 previousPBConstr = super.addPseudoBoolean(objfct.getVars(), objfct
162 .getCoeffs(), false, objectiveValue
163 .subtract(BigInteger.ONE));
164 }
165 }
166
167 @Override
168 public void reset() {
169 previousPBConstr = null;
170 super.reset();
171 }
172
173 @Override
174 public int[] model() {
175
176 return prevmodel;
177 }
178
179 @Override
180 public boolean model(int var) {
181 return prevfullmodel[var - 1];
182 }
183
184 @Override
185 public String toString(String prefix) {
186 return prefix + "Pseudo Boolean Optimization\n"
187 + super.toString(prefix);
188 }
189
190 public Number getObjectiveValue() {
191 return objectiveValue;
192 }
193
194 public void discard() throws ContradictionException {
195 discardCurrentSolution();
196 }
197
198 public void forceObjectiveValueTo(Number forcedValue)
199 throws ContradictionException {
200 super.addPseudoBoolean(objfct.getVars(), objfct.getCoeffs(), false,
201 (BigInteger) forcedValue);
202 }
203 }