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.opt;
31
32 import org.sat4j.core.VecInt;
33 import org.sat4j.specs.ContradictionException;
34 import org.sat4j.specs.IConstr;
35 import org.sat4j.specs.IOptimizationProblem;
36 import org.sat4j.specs.ISolver;
37 import org.sat4j.specs.IVecInt;
38 import org.sat4j.specs.TimeoutException;
39 import org.sat4j.tools.SolverDecorator;
40
41
42
43
44
45
46
47
48 public final class MinOneDecorator extends SolverDecorator<ISolver> implements
49 IOptimizationProblem {
50
51
52
53
54 private static final long serialVersionUID = 1L;
55
56 private int[] prevmodel;
57 private int[] prevmodelWithInternalVariables;
58
59 private boolean isSolutionOptimal;
60
61 public MinOneDecorator(ISolver solver) {
62 super(solver);
63 }
64
65 public boolean admitABetterSolution() throws TimeoutException {
66 return admitABetterSolution(VecInt.EMPTY);
67 }
68
69
70
71
72 public boolean admitABetterSolution(IVecInt assumps)
73 throws TimeoutException {
74 this.isSolutionOptimal = false;
75 boolean result = isSatisfiable(assumps, true);
76 if (result) {
77 this.prevmodel = super.model();
78 this.prevmodelWithInternalVariables = super
79 .modelWithInternalVariables();
80 calculateObjectiveValue();
81 } else {
82 this.isSolutionOptimal = true;
83 }
84 return result;
85 }
86
87 public boolean hasNoObjectiveFunction() {
88 return false;
89 }
90
91 public boolean nonOptimalMeansSatisfiable() {
92 return true;
93 }
94
95 private int counter;
96
97 public Number calculateObjective() {
98 calculateObjectiveValue();
99 return this.counter;
100 }
101
102 private void calculateObjectiveValue() {
103 this.counter = 0;
104 for (int p : this.prevmodel) {
105 if (p > 0) {
106 this.counter++;
107 }
108 }
109 }
110
111 private final IVecInt literals = new VecInt();
112
113 private IConstr previousConstr;
114
115
116
117
118 public void discardCurrentSolution() throws ContradictionException {
119 if (this.literals.isEmpty()) {
120 for (int i = 1; i <= nVars(); i++) {
121 this.literals.push(i);
122 }
123 }
124 if (this.previousConstr != null) {
125 super.removeConstr(this.previousConstr);
126 }
127 this.previousConstr = addAtMost(this.literals, this.counter - 1);
128 }
129
130 @Override
131 public int[] model() {
132
133 return this.prevmodel;
134 }
135
136 @Override
137 public int[] modelWithInternalVariables() {
138 return this.prevmodelWithInternalVariables;
139 }
140
141 @Override
142 public void reset() {
143 this.literals.clear();
144 this.previousConstr = null;
145 super.reset();
146 }
147
148
149
150
151 public Number getObjectiveValue() {
152 return this.counter;
153 }
154
155 public void discard() throws ContradictionException {
156 discardCurrentSolution();
157 }
158
159
160
161
162 public void forceObjectiveValueTo(Number forcedValue)
163 throws ContradictionException {
164 try {
165 addAtMost(this.literals, forcedValue.intValue());
166 } catch (ContradictionException ce) {
167 this.isSolutionOptimal = true;
168 throw ce;
169 }
170
171 }
172
173 public boolean isOptimal() {
174 return this.isSolutionOptimal;
175 }
176
177 public void setTimeoutForFindingBetterSolution(int seconds) {
178
179 throw new UnsupportedOperationException("No implemented yet");
180 }
181 }