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