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 package org.sat4j.tools.encoding;
30
31 import org.sat4j.core.ConstrGroup;
32 import org.sat4j.core.VecInt;
33 import org.sat4j.specs.ContradictionException;
34 import org.sat4j.specs.IConstr;
35 import org.sat4j.specs.ISolver;
36 import org.sat4j.specs.IVecInt;
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52 public class Commander extends EncodingStrategyAdapter {
53
54
55
56
57
58
59 @Override
60 public IConstr addAtMostOne(ISolver solver, IVecInt literals)
61 throws ContradictionException {
62
63 return addAtMostOne(solver, literals, 3);
64 }
65
66 private IConstr addAtMostOne(ISolver solver, IVecInt literals, int groupSize)
67 throws ContradictionException {
68
69 ConstrGroup constrGroup = new ConstrGroup(false);
70
71 IVecInt clause = new VecInt();
72 IVecInt clause1 = new VecInt();
73
74 final int n = literals.size();
75
76 int nbGroup = (int) Math.ceil((double) literals.size()
77 / (double) groupSize);
78
79 if (nbGroup == 1) {
80 for (int i = 0; i < literals.size() - 1; i++) {
81 for (int j = i + 1; j < literals.size(); j++) {
82 clause.push(-literals.get(i));
83 clause.push(-literals.get(j));
84 constrGroup.add(solver.addClause(clause));
85 clause.clear();
86 }
87 }
88 return constrGroup;
89 }
90
91 int[] c = new int[nbGroup];
92
93 for (int i = 0; i < nbGroup; i++) {
94 c[i] = solver.nextFreeVarId(true);
95 }
96
97 int nbVarLastGroup = n - (nbGroup - 1) * groupSize;
98
99
100 for (int i = 0; i < nbGroup; i++) {
101 int size = 0;
102 if (i == (nbGroup - 1)) {
103 size = nbVarLastGroup;
104 } else {
105 size = groupSize;
106 }
107
108 for (int j = 0; j < size - 1; j++) {
109 for (int k = j + 1; k < size; k++) {
110 clause.push(-literals.get(i * groupSize + j));
111 clause.push(-literals.get(i * groupSize + k));
112 constrGroup.add(solver.addClause(clause));
113 clause.clear();
114 }
115 }
116
117
118
119
120
121 clause1.push(-c[i]);
122 for (int j = 0; j < size; j++) {
123 clause1.push(literals.get(i * groupSize + j));
124 clause.push(c[i]);
125 clause.push(-literals.get(i * groupSize + j));
126 constrGroup.add(solver.addClause(clause));
127 clause.clear();
128 }
129 constrGroup.add(solver.addClause(clause1));
130 clause1.clear();
131 }
132
133
134
135 constrGroup.add(addAtMostOne(solver, new VecInt(c), groupSize));
136 return constrGroup;
137 }
138
139 @Override
140 public IConstr addAtMost(ISolver solver, IVecInt literals, int degree)
141 throws ContradictionException {
142 return super.addAtMost(solver, literals, degree);
143
144 }
145
146 private IConstr addAtMost(ISolver solver, IVecInt literals, int k,
147 int groupSize) throws ContradictionException {
148 ConstrGroup constrGroup = new ConstrGroup(false);
149
150 IVecInt clause = new VecInt();
151
152 final int n = literals.size();
153
154 int nbGroup = (int) Math.ceil((double) n / (double) groupSize);
155
156 if (nbGroup == 1) {
157 for (IVecInt vec : literals.subset(k + 1)) {
158 for (int i = 0; i < vec.size(); i++) {
159 clause.push(-vec.get(i));
160 }
161 constrGroup.add(solver.addClause(clause));
162 clause.clear();
163 }
164 return constrGroup;
165 }
166
167 int[][] c = new int[nbGroup][k];
168 VecInt vecC = new VecInt();
169
170 for (int i = 0; i < nbGroup - 1; i++) {
171 for (int j = 0; j < k; j++) {
172 c[i][j] = solver.nextFreeVarId(true);
173 vecC.push(c[i][j]);
174 }
175 }
176
177 int nbVarLastGroup = n - (nbGroup - 1) * groupSize;
178 int nbCForLastGroup;
179
180 nbCForLastGroup = k;
181
182 for (int j = 0; j < nbCForLastGroup; j++) {
183 c[nbGroup - 1][j] = solver.nextFreeVarId(true);
184 vecC.push(c[nbGroup - 1][j]);
185 }
186
187 VecInt[] groupTab = new VecInt[nbGroup];
188
189
190
191
192 for (int i = 0; i < nbGroup - 1; i++) {
193 groupTab[i] = new VecInt();
194
195 int size = 0;
196 if (i == (nbGroup - 1)) {
197 size = nbVarLastGroup;
198 } else {
199 size = groupSize;
200 }
201
202 for (int j = 0; j < size; j++) {
203 groupTab[i].push(literals.get(i * groupSize + j));
204 }
205 for (int j = 0; j < k; j++) {
206 groupTab[i].push(-c[i][j]);
207 }
208 }
209
210 int size = nbVarLastGroup;
211 groupTab[nbGroup - 1] = new VecInt();
212 for (int j = 0; j < size; j++) {
213 groupTab[nbGroup - 1].push(literals.get((nbGroup - 1) * groupSize
214 + j));
215 }
216 for (int j = 0; j < nbCForLastGroup; j++) {
217 groupTab[nbGroup - 1].push(-c[nbGroup - 1][j]);
218 }
219
220 Binomial bin = new Binomial();
221
222
223
224 for (int i = 0; i < nbGroup; i++) {
225 constrGroup.add(bin.addAtMost(solver, groupTab[i], k));
226 System.out.println(constrGroup.getConstr(i).size());
227 }
228
229
230
231 for (int i = 0; i < nbGroup; i++) {
232 constrGroup.add(bin.addAtLeast(solver, groupTab[i], k));
233 System.out.println(constrGroup.getConstr(i + nbGroup).size());
234 }
235
236 for (int i = 0; i < nbGroup; i++) {
237 for (int j = 0; j < k - 1; j++) {
238 clause.push(-c[i][j]);
239 clause.push(c[i][j + 1]);
240 constrGroup.add(solver.addClause(clause));
241 clause.clear();
242 }
243 }
244
245 constrGroup.add(addAtMost(solver, vecC, k));
246
247 return constrGroup;
248 }
249 }