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 package org.sat4j.pb;
29
30 import java.math.BigInteger;
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.IVecInt;
37 import org.sat4j.specs.TimeoutException;
38
39
40
41
42
43
44
45 public class ConstraintRelaxingPseudoOptDecorator extends PBSolverDecorator
46 implements IOptimizationProblem {
47
48 private static final long serialVersionUID = 1L;
49 private int[] bestModel;
50 private boolean[] bestFullModel;
51 private IConstr previousPBConstr;
52 private IConstr addedConstr = null;
53 private int maxValue = 0;
54 private Number objectiveValue;
55 private boolean optimumFound = false;
56
57 public ConstraintRelaxingPseudoOptDecorator(IPBSolver solver) {
58 super(solver);
59 }
60
61 @Override
62 public boolean isSatisfiable() throws TimeoutException {
63 return isSatisfiable(VecInt.EMPTY);
64 }
65
66 @Override
67 public boolean isSatisfiable(boolean global) throws TimeoutException {
68 return isSatisfiable(VecInt.EMPTY, global);
69 }
70
71 @Override
72 public boolean isSatisfiable(IVecInt assumps, boolean global)
73 throws TimeoutException {
74 boolean result = super.isSatisfiable(assumps, true);
75 if (result) {
76 bestModel = super.model();
77 bestFullModel = new boolean[nVars()];
78 for (int i = 0; i < nVars(); i++) {
79 bestFullModel[i] = decorated().model(i + 1);
80 }
81 calculateObjective();
82 } else {
83 if (previousPBConstr != null) {
84 decorated().removeConstr(previousPBConstr);
85 previousPBConstr = null;
86 }
87 }
88 return result;
89 }
90
91 @Override
92 public boolean isSatisfiable(IVecInt assumps) throws TimeoutException {
93 return isSatisfiable(assumps, true);
94 }
95
96 public boolean admitABetterSolution() throws TimeoutException {
97 return admitABetterSolution(VecInt.EMPTY);
98 }
99
100 public boolean admitABetterSolution(IVecInt assumps)
101 throws TimeoutException {
102 boolean isSatisfiable;
103
104 if (this.optimumFound) {
105 return false;
106 }
107 maxValue = getObjectiveFunction().minValue().intValue();
108 while (true) {
109 if (addedConstr != null) {
110 this.decorated().removeConstr(addedConstr);
111 }
112 try {
113 forceObjectiveValueTo(this.maxValue++);
114 } catch (ContradictionException e) {
115 if (isVerbose()) {
116 System.out.println(decorated().getLogPrefix()
117 + "no solution for objective value "
118 + (this.maxValue - 1));
119 }
120 continue;
121 }
122 isSatisfiable = super.isSatisfiable(assumps, true);
123 if (isSatisfiable) {
124 optimumFound = true;
125 bestModel = super.model();
126 bestFullModel = new boolean[nVars()];
127 for (int i = 0; i < nVars(); i++) {
128 bestFullModel[i] = decorated().model(i + 1);
129 }
130 if (getObjectiveFunction() != null) {
131 calculateObjective();
132 }
133 this.decorated().removeConstr(addedConstr);
134 return true;
135 }
136 if (isVerbose()) {
137 System.out.println(decorated().getLogPrefix()
138 + "no solution for objective value "
139 + (this.maxValue - 1));
140 }
141 }
142 }
143
144 public boolean hasNoObjectiveFunction() {
145 return getObjectiveFunction() == null;
146 }
147
148 public boolean nonOptimalMeansSatisfiable() {
149 return false;
150 }
151
152 @Deprecated
153 public Number calculateObjective() {
154 if (getObjectiveFunction() == null) {
155 throw new UnsupportedOperationException(
156 "The problem does not contain an objective function");
157 }
158 objectiveValue = getObjectiveFunction().calculateDegree(this);
159 return objectiveValue;
160 }
161
162 public Number getObjectiveValue() {
163 return objectiveValue;
164 }
165
166 public void forceObjectiveValueTo(Number forcedValue)
167 throws ContradictionException {
168 addedConstr = super.addPseudoBoolean(getObjectiveFunction().getVars(),
169 getObjectiveFunction().getCoeffs(), false,
170 BigInteger.valueOf(forcedValue.longValue()));
171 }
172
173 @Deprecated
174 public void discard() {
175 discardCurrentSolution();
176 }
177
178 public void discardCurrentSolution() {
179
180 }
181
182 public boolean isOptimal() {
183 return this.optimumFound;
184 }
185
186 @Override
187 public String toString(String prefix) {
188 return prefix + "Pseudo Boolean Optimization by lower bound\n"
189 + super.toString(prefix);
190 }
191
192 }