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 public MinCostDecorator(IPBSolver solver) {
64 super(solver);
65 }
66
67
68
69
70
71
72 @Override
73 public int newVar() {
74 throw new UnsupportedOperationException();
75 }
76
77
78
79
80
81
82
83
84
85
86 @Override
87 public int newVar(int howmany) {
88 costs = new int[howmany + 1];
89
90 vars.clear();
91 coeffs.clear();
92 for (int i = 1; i <= howmany; i++) {
93 vars.push(i);
94 coeffs.push(BigInteger.ZERO);
95 }
96
97
98 return super.newVar(howmany);
99 }
100
101
102
103
104
105
106
107
108 public int costOf(int var) {
109 return costs[var];
110 }
111
112
113
114
115
116
117
118
119
120 public void setCost(int var, int cost) {
121 costs[var] = cost;
122 coeffs.set(var - 1, BigInteger.valueOf(cost));
123 }
124
125 public boolean admitABetterSolution() throws TimeoutException {
126 return admitABetterSolution(VecInt.EMPTY);
127 }
128
129 public boolean admitABetterSolution(IVecInt assumps)
130 throws TimeoutException {
131 boolean result = super.isSatisfiable(assumps, true);
132 if (result) {
133 prevmodel = super.model();
134 calculateObjective();
135 }
136 return result;
137 }
138
139 public boolean hasNoObjectiveFunction() {
140 return false;
141 }
142
143 public boolean nonOptimalMeansSatisfiable() {
144 return true;
145 }
146
147 public Number calculateObjective() {
148 objectivevalue = calculateDegree(prevmodel);
149 return new Integer(objectivevalue);
150 }
151
152 private int calculateDegree(int[] prevmodel2) {
153 int tmpcost = 0;
154 for (int i = 1; i < costs.length; i++) {
155 if (prevmodel2[i - 1] > 0) {
156 tmpcost += costs[i];
157 }
158 }
159 return tmpcost;
160 }
161
162 public void discardCurrentSolution() throws ContradictionException {
163 if (prevConstr!=null) {
164 super.removeSubsumedConstr(prevConstr);
165 }
166 prevConstr = super.addPseudoBoolean(vars, coeffs, false, BigInteger
167 .valueOf(objectivevalue - 1));
168 }
169
170 @Override
171 public void reset() {
172 prevConstr = null;
173 super.reset();
174 }
175
176 @Override
177 public int[] model() {
178
179 return prevmodel;
180 }
181
182 public Number getObjectiveValue() {
183 return objectivevalue;
184 }
185
186 public void discard() throws ContradictionException {
187 discardCurrentSolution();
188 }
189
190 public void forceObjectiveValueTo(Number forcedValue)
191 throws ContradictionException {
192 super.addPseudoBoolean(vars, coeffs, false, (BigInteger)
193 forcedValue);
194 }
195 }