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.ConstrGroup;
33 import org.sat4j.core.VecInt;
34 import org.sat4j.specs.ContradictionException;
35 import org.sat4j.specs.IConstr;
36 import org.sat4j.specs.ISolver;
37 import org.sat4j.specs.IVecInt;
38 import org.sat4j.specs.TimeoutException;
39
40
41
42
43
44
45
46 public final class MaxSatDecorator extends AbstractSelectorVariablesDecorator {
47
48
49
50
51 private static final long serialVersionUID = 1L;
52
53 private final boolean equivalence;
54
55 public MaxSatDecorator(ISolver solver) {
56 this(solver, false);
57 }
58
59 public MaxSatDecorator(ISolver solver, boolean equivalence) {
60 super(solver);
61 this.equivalence = equivalence;
62 }
63
64 @Override
65 public void setExpectedNumberOfClauses(int nb) {
66 super.setExpectedNumberOfClauses(nb);
67 this.lits.ensure(nb);
68 }
69
70 @Override
71 public IConstr addClause(IVecInt literals) throws ContradictionException {
72 int newvar = nextFreeVarId(true);
73 this.lits.push(newvar);
74 literals.push(newvar);
75 if (this.equivalence) {
76 ConstrGroup constrs = new ConstrGroup();
77 constrs.add(super.addClause(literals));
78 IVecInt clause = new VecInt(2);
79 clause.push(-newvar);
80 for (int i = 0; i < literals.size() - 1; i++) {
81 clause.push(-literals.get(i));
82 constrs.add(super.addClause(clause));
83 }
84 clause.pop();
85 return constrs;
86 }
87 return super.addClause(literals);
88 }
89
90 @Override
91 public void reset() {
92 this.lits.clear();
93 super.reset();
94 this.prevConstr = null;
95 }
96
97 public boolean hasNoObjectiveFunction() {
98 return false;
99 }
100
101 public boolean nonOptimalMeansSatisfiable() {
102 return false;
103 }
104
105 public Number calculateObjective() {
106 calculateObjectiveValue();
107 return this.counter;
108 }
109
110 private final IVecInt lits = new VecInt();
111
112 private int counter;
113
114 private IConstr prevConstr;
115
116
117
118
119 public void discardCurrentSolution() throws ContradictionException {
120 if (this.prevConstr != null) {
121 super.removeSubsumedConstr(this.prevConstr);
122 }
123 try {
124 this.prevConstr = super.addAtMost(this.lits, this.counter - 1);
125 } catch (ContradictionException ce) {
126 this.isSolutionOptimal = true;
127 throw ce;
128 }
129 }
130
131 @Override
132 public boolean admitABetterSolution(IVecInt assumps)
133 throws TimeoutException {
134
135 boolean result = super.admitABetterSolution(assumps);
136 if (!result) {
137 if (this.prevConstr != null) {
138 super.removeConstr(this.prevConstr);
139 this.prevConstr = null;
140 }
141 }
142 return result;
143 }
144
145 public void discard() throws ContradictionException {
146 discardCurrentSolution();
147 }
148
149
150
151
152 public Number getObjectiveValue() {
153 return this.counter;
154 }
155
156 @Override
157 void calculateObjectiveValue() {
158 this.counter = 0;
159 for (int q : this.prevfullmodel) {
160 if (q > nVars()) {
161 this.counter++;
162 }
163 }
164 }
165
166
167
168
169 public void forceObjectiveValueTo(Number forcedValue)
170 throws ContradictionException {
171 super.addAtMost(this.lits, forcedValue.intValue());
172 }
173
174 }