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.maxsat;
31
32 import java.math.BigInteger;
33
34 import org.sat4j.core.Vec;
35 import org.sat4j.core.VecInt;
36 import org.sat4j.pb.IPBSolver;
37 import org.sat4j.pb.PBSolverDecorator;
38 import org.sat4j.specs.ContradictionException;
39 import org.sat4j.specs.IConstr;
40 import org.sat4j.specs.IOptimizationProblem;
41 import org.sat4j.specs.IVec;
42 import org.sat4j.specs.IVecInt;
43 import org.sat4j.specs.TimeoutException;
44
45
46
47
48
49
50
51
52
53
54 public class MinCostDecorator extends PBSolverDecorator implements
55 IOptimizationProblem {
56
57
58
59
60 private static final long serialVersionUID = 1L;
61
62 private int[] costs;
63
64 private int[] prevmodel;
65
66 private final IVecInt vars = new VecInt();
67
68 private final IVec<BigInteger> coeffs = new Vec<BigInteger>();
69
70 private int objectivevalue;
71
72 private IConstr prevConstr;
73
74 private boolean isSolutionOptimal;
75
76 public MinCostDecorator(IPBSolver solver) {
77 super(solver);
78 }
79
80
81
82
83
84
85 @Override
86 public int newVar() {
87 throw new UnsupportedOperationException();
88 }
89
90
91
92
93
94
95
96
97
98
99 @Override
100 public int newVar(int howmany) {
101 this.costs = new int[howmany + 1];
102
103 this.vars.clear();
104 this.coeffs.clear();
105 for (int i = 1; i <= howmany; i++) {
106 this.vars.push(i);
107 this.coeffs.push(BigInteger.ZERO);
108 }
109
110
111 return super.newVar(howmany);
112 }
113
114
115
116
117
118
119
120
121 public int costOf(int var) {
122 return this.costs[var];
123 }
124
125
126
127
128
129
130
131
132
133 public void setCost(int var, int cost) {
134 this.costs[var] = cost;
135 this.coeffs.set(var - 1, BigInteger.valueOf(cost));
136 }
137
138 public boolean admitABetterSolution() throws TimeoutException {
139 return admitABetterSolution(VecInt.EMPTY);
140 }
141
142 public boolean admitABetterSolution(IVecInt assumps)
143 throws TimeoutException {
144 this.isSolutionOptimal = false;
145 boolean result = super.isSatisfiable(assumps, true);
146 if (result) {
147 this.prevmodel = super.model();
148 calculateObjective();
149 } else {
150 this.isSolutionOptimal = true;
151 }
152 return result;
153 }
154
155 public boolean hasNoObjectiveFunction() {
156 return false;
157 }
158
159 public boolean nonOptimalMeansSatisfiable() {
160 return true;
161 }
162
163 public Number calculateObjective() {
164 this.objectivevalue = calculateDegree(this.prevmodel);
165 return this.objectivevalue;
166 }
167
168 private int calculateDegree(int[] prevmodel2) {
169 int tmpcost = 0;
170 for (int i = 1; i < this.costs.length; i++) {
171 if (prevmodel2[i - 1] > 0) {
172 tmpcost += this.costs[i];
173 }
174 }
175 return tmpcost;
176 }
177
178 public void discardCurrentSolution() throws ContradictionException {
179 if (this.prevConstr != null) {
180 super.removeSubsumedConstr(this.prevConstr);
181 }
182 try {
183 this.prevConstr = super.addPseudoBoolean(this.vars, this.coeffs,
184 false, BigInteger.valueOf(this.objectivevalue - 1));
185 } catch (ContradictionException e) {
186 this.isSolutionOptimal = true;
187 throw e;
188 }
189 }
190
191 @Override
192 public void reset() {
193 this.prevConstr = null;
194 super.reset();
195 }
196
197 @Override
198 public int[] model() {
199
200 return this.prevmodel;
201 }
202
203 public Number getObjectiveValue() {
204 return this.objectivevalue;
205 }
206
207 public void discard() throws ContradictionException {
208 discardCurrentSolution();
209 }
210
211 public void forceObjectiveValueTo(Number forcedValue)
212 throws ContradictionException {
213 super.addPseudoBoolean(this.vars, this.coeffs, false,
214 (BigInteger) forcedValue);
215 }
216
217 public boolean isOptimal() {
218 return this.isSolutionOptimal;
219 }
220
221 public void setTimeoutForFindingBetterSolution(int seconds) {
222
223 throw new UnsupportedOperationException("No implemented yet");
224 }
225 }