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