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.IOptimizationProblem;
29 import org.sat4j.specs.IVec;
30 import org.sat4j.specs.IVecInt;
31 import org.sat4j.specs.TimeoutException;
32
33
34
35
36
37
38
39
40
41 public class MinCostDecorator extends PBSolverDecorator implements
42 IOptimizationProblem {
43
44
45
46
47 private static final long serialVersionUID = 1L;
48
49 private int[] costs;
50
51 private int[] prevmodel;
52
53 private final IVecInt vars = new VecInt();
54
55 private final IVec<BigInteger> coeffs = new Vec<BigInteger>();
56
57 public MinCostDecorator(IPBSolver solver) {
58 super(solver);
59 }
60
61
62
63
64
65
66 @Override
67 public int newVar() {
68 throw new UnsupportedOperationException();
69 }
70
71
72
73
74
75
76
77
78
79
80 @Override
81 public int newVar(int howmany) {
82 costs = new int[howmany + 1];
83
84 vars.clear();
85 coeffs.clear();
86 for (int i = 1; i <= howmany; i++) {
87 vars.push(i);
88 coeffs.push(BigInteger.ZERO);
89 }
90
91
92 return super.newVar(howmany);
93 }
94
95
96
97
98
99
100
101
102 public int costOf(int var) {
103 return costs[var];
104 }
105
106
107
108
109
110
111
112
113
114 public void setCost(int var, int cost) {
115 costs[var] = cost;
116 coeffs.set(var - 1, BigInteger.valueOf(cost));
117 }
118
119 public boolean admitABetterSolution() throws TimeoutException {
120 boolean result = super.isSatisfiable(true);
121 if (result)
122 prevmodel = super.model();
123 return result;
124 }
125
126 public boolean hasNoObjectiveFunction() {
127 return false;
128 }
129
130 public boolean nonOptimalMeansSatisfiable() {
131 return true;
132 }
133
134 public Number calculateObjective() {
135 return new Integer(calculateDegree(prevmodel));
136 }
137
138 private int calculateDegree(int[] prevmodel2) {
139 int tmpcost = 0;
140 for (int i = 1; i < costs.length; i++) {
141 if (prevmodel2[i - 1] > 0) {
142 tmpcost += costs[i];
143 }
144 }
145 return tmpcost;
146 }
147
148 public void discard() throws ContradictionException {
149 super.addPseudoBoolean(vars, coeffs, false, BigInteger
150 .valueOf(calculateDegree(prevmodel) - 1));
151 }
152
153 @Override
154 public int[] model() {
155
156 return prevmodel;
157 }
158
159 }