35 #include "algorithms/Alg_OLL.h" 62 if (encoding != _CARD_TOTALIZER_) {
64 "Error: Currently algorithm MSU3 with iterative encoding only " 65 "supports the totalizer encoding.\n");
66 printf(
"s UNKNOWN\n");
70 if (maxsat_formula->getProblemType() == _WEIGHTED_) {
72 return Utils::convertVecDataToVector<lbool>(model, model.size());
74 printf(
"Error: Use the solver in 'weighted' mode only!\n");
91 solver = rebuildSolver();
94 vec<Lit> joinObjFunction;
95 vec<Lit> currentObjFunction;
96 vec<Lit> encodingAssumptions;
97 encoder.setIncremental(_INCREMENTAL_ITERATIVE_);
99 activeSoft.growTo(maxsat_formula->nSoft(),
false);
100 for (
int i = 0; i < maxsat_formula->nSoft(); i++)
101 coreMapping[maxsat_formula->getSoftClause(i).assumption_var] = i;
103 std::set<Lit> cardinality_assumptions;
104 vec<Encoder *> soft_cardinality;
106 min_weight = maxsat_formula->getMaximumWeight();
110 res = searchSATSolver(solver, assumptions);
113 uint64_t newCost = computeCostModel(solver->model);
114 if (newCost < ubCost || nbSatisfiable == 1) {
115 saveModel(solver->model);
116 if (maxsat_formula->getFormat() == _FORMAT_PB_) {
118 if (maxsat_formula->getObjFunction() != NULL) {
126 if (nbSatisfiable == 1) {
128 findNextWeightDiversity(min_weight, cardinality_assumptions);
131 for (
int i = 0; i < maxsat_formula->nSoft(); i++)
132 if (maxsat_formula->getSoftClause(i).weight >= min_weight)
133 assumptions.push(~maxsat_formula->getSoftClause(i).assumption_var);
136 int not_considered = 0;
137 for (
int i = 0; i < maxsat_formula->nSoft(); i++) {
138 if (maxsat_formula->getSoftClause(i).weight < min_weight)
144 for (std::set<Lit>::iterator it = cardinality_assumptions.begin();
145 it != cardinality_assumptions.end(); ++it) {
146 assert(boundMapping.find(*it) != boundMapping.end());
147 std::pair<std::pair<int, uint64_t>, uint64_t> soft_id =
149 if (soft_id.second < min_weight) not_considered++;
152 if (not_considered != 0) {
154 findNextWeightDiversity(min_weight, cardinality_assumptions);
161 for (
int i = 0; i < maxsat_formula->nSoft(); i++) {
162 if (!activeSoft[i] &&
163 maxsat_formula->getSoftClause(i).weight >= min_weight) {
165 ~maxsat_formula->getSoftClause(i).assumption_var);
173 for (std::set<Lit>::iterator it = cardinality_assumptions.begin();
174 it != cardinality_assumptions.end(); ++it) {
175 assert(boundMapping.find(*it) != boundMapping.end());
176 std::pair<std::pair<int, uint64_t>, uint64_t> soft_id =
178 if (soft_id.second >= min_weight) assumptions.push(~(*it));
183 assert(lbCost == newCost);
189 if (res == l_False) {
191 uint64_t min_core = UINT64_MAX;
192 for (
int i = 0; i < solver->conflict.size(); i++) {
193 Lit p = solver->conflict[i];
194 if (coreMapping.find(p) != coreMapping.end()) {
195 assert(!activeSoft[coreMapping[p]]);
196 if (maxsat_formula->getSoftClause(coreMapping[solver->conflict[i]])
199 maxsat_formula->getSoftClause(coreMapping[solver->conflict[i]])
203 if (boundMapping.find(p) != boundMapping.end()) {
204 std::pair<std::pair<int, uint64_t>, uint64_t> soft_id =
205 boundMapping[solver->conflict[i]];
206 if (soft_id.second < min_core) min_core = soft_id.second;
217 if (nbSatisfiable == 0) {
221 if (lbCost == ubCost) {
222 assert(nbSatisfiable > 0);
228 sumSizeCores += solver->conflict.size();
231 vec<Lit> cardinality_relax;
233 for (
int i = 0; i < solver->conflict.size(); i++) {
234 Lit p = solver->conflict[i];
235 if (coreMapping.find(p) != coreMapping.end()) {
236 if (maxsat_formula->getSoftClause(coreMapping[p]).weight > min_core) {
238 assert(!activeSoft[coreMapping[p]]);
240 int indexSoft = coreMapping[p];
241 assert(maxsat_formula->getSoftClause(indexSoft).weight - min_core >
245 maxsat_formula->getSoftClause(indexSoft).weight -= min_core;
250 maxsat_formula->getSoftClause(indexSoft).clause.copyTo(clause);
253 while (maxsat_formula->nVars() < solver->nVars())
254 maxsat_formula->newLiteral();
256 Lit l = maxsat_formula->newLiteral();
262 maxsat_formula->addSoftClause(min_core, clause, vars);
263 activeSoft.push(
true);
266 newSATVariable(solver);
268 solver->addClause(clause);
270 assert(clause.size() - 1 ==
271 maxsat_formula->getSoftClause(indexSoft).clause.size());
272 assert(maxsat_formula->getSoftClause(maxsat_formula->nSoft() - 1)
273 .relaxation_vars.size() == 1);
277 maxsat_formula->getSoftClause(maxsat_formula->nSoft() - 1)
279 assert(maxsat_formula->getSoftClause(maxsat_formula->nSoft() - 1)
281 maxsat_formula->getSoftClause(maxsat_formula->nSoft() - 1)
282 .relaxation_vars[0]);
284 maxsat_formula->nSoft() - 1;
288 assert(maxsat_formula->getSoftClause(coreMapping[l]).weight ==
290 assert(activeSoft.size() == maxsat_formula->nSoft());
295 maxsat_formula->getSoftClause(coreMapping[solver->conflict[i]])
296 .weight == min_core);
299 assert(!activeSoft[coreMapping[p]]);
300 activeSoft[coreMapping[p]] =
true;
304 if (boundMapping.find(p) != boundMapping.end()) {
307 std::set<Lit>::iterator it;
308 it = cardinality_assumptions.find(p);
309 assert(it != cardinality_assumptions.end());
312 std::pair<std::pair<int, uint64_t>, uint64_t> soft_id =
313 boundMapping[solver->conflict[i]];
315 assert(soft_id.first.first < soft_cardinality.size());
316 assert(soft_cardinality[soft_id.first.first]->hasCardEncoding());
318 if (soft_id.second == min_core) {
319 cardinality_assumptions.erase(it);
320 cardinality_relax.push(p);
322 joinObjFunction.clear();
323 encodingAssumptions.clear();
324 soft_cardinality[soft_id.first.first]->incUpdateCardinality(
325 solver, joinObjFunction,
326 soft_cardinality[soft_id.first.first]->lits(),
327 soft_id.first.second + 1, encodingAssumptions);
331 if (soft_id.first.second + 1 <
332 (
unsigned)soft_cardinality[soft_id.first.first]
335 assert((
unsigned)soft_cardinality[soft_id.first.first]
337 .size() > soft_id.first.second + 1);
338 Lit out = soft_cardinality[soft_id.first.first]
339 ->outputs()[soft_id.first.second + 1];
340 boundMapping[out] = std::make_pair(
341 std::make_pair(soft_id.first.first, soft_id.first.second + 1),
343 cardinality_assumptions.insert(out);
349 Encoder *e =
new Encoder();
350 e->setIncremental(_INCREMENTAL_ITERATIVE_);
351 e->buildCardinality(solver,
352 soft_cardinality[soft_id.first.first]->lits(),
353 soft_id.first.second);
355 assert((
unsigned)e->outputs().size() > soft_id.first.second);
356 Lit out = e->outputs()[soft_id.first.second];
357 soft_cardinality.push(e);
360 std::make_pair(std::make_pair(soft_cardinality.size() - 1,
361 soft_id.first.second),
363 cardinality_relax.push(out);
366 assert(soft_id.second - min_core > 0);
367 boundMapping[p] = std::make_pair(
368 std::make_pair(soft_id.first.first, soft_id.first.second),
369 soft_id.second - min_core);
373 std::pair<std::pair<int, int>,
int> soft_core_id =
376 joinObjFunction.clear();
377 encodingAssumptions.clear();
378 soft_cardinality[soft_core_id.first.first]->incUpdateCardinality(
379 solver, joinObjFunction,
380 soft_cardinality[soft_core_id.first.first]->lits(),
381 soft_core_id.first.second + 1, encodingAssumptions);
385 if (soft_core_id.first.second + 1 <
386 soft_cardinality[soft_core_id.first.first]->outputs().size()) {
388 soft_cardinality[soft_core_id.first.first]->outputs().size() >
389 soft_core_id.first.second + 1);
390 Lit out = soft_cardinality[soft_core_id.first.first]
391 ->outputs()[soft_core_id.first.second + 1];
393 std::make_pair(std::make_pair(soft_core_id.first.first,
394 soft_core_id.first.second + 1),
396 cardinality_assumptions.insert(out);
403 while (nVars() < solver->nVars()) newLiteral();
405 Lit l = newLiteral();
408 newSATVariable(solver);
412 solver->addClause(clause);
417 solver->addClause(clause);
419 boundMapping[l] = std::make_pair(
420 std::make_pair(soft_id.first.first, soft_id.first.second),
422 cardinality_relax.push(l);
426 std::pair<std::pair<int, int>,
int> soft_core_id = boundMapping[p];
428 joinObjFunction.clear();
429 encodingAssumptions.clear();
430 soft_cardinality[soft_core_id.first.first]->incUpdateCardinality(
431 solver, joinObjFunction,
432 soft_cardinality[soft_core_id.first.first]->lits(),
433 soft_core_id.first.second + 1, encodingAssumptions);
437 if (soft_core_id.first.second + 1 <
438 soft_cardinality[soft_core_id.first.first]->outputs().size()) {
440 soft_cardinality[soft_core_id.first.first]->outputs().size() >
441 soft_core_id.first.second + 1);
442 Lit out = soft_cardinality[soft_core_id.first.first]
443 ->outputs()[soft_core_id.first.second + 1];
445 std::make_pair(std::make_pair(soft_core_id.first.first,
446 soft_core_id.first.second + 1),
448 cardinality_assumptions.insert(out);
452 assert(soft_id.second - min_core > 0);
453 boundMapping[p] = std::make_pair(
454 std::make_pair(soft_id.first.first, soft_id.first.second),
455 soft_id.second - min_core);
462 assert(soft_relax.size() + cardinality_relax.size() > 0);
464 if (soft_relax.size() == 1 && cardinality_relax.size() == 0) {
467 solver->addClause(soft_relax[0]);
472 if (soft_relax.size() + cardinality_relax.size() > 1) {
473 vec<Lit> relax_harden;
474 soft_relax.copyTo(relax_harden);
475 for (
int i = 0; i < cardinality_relax.size(); i++)
476 relax_harden.push(cardinality_relax[i]);
492 Encoder *e =
new Encoder();
493 e->setIncremental(_INCREMENTAL_ITERATIVE_);
494 e->buildCardinality(solver, relax_harden, 1);
495 soft_cardinality.push(e);
496 assert(e->outputs().size() > 1);
499 Lit out = e->outputs()[1];
500 boundMapping[out] = std::make_pair(
501 std::make_pair(soft_cardinality.size() - 1, 1), min_core);
502 cardinality_assumptions.insert(out);
508 for (
int i = 0; i < maxsat_formula->nSoft(); i++) {
509 if (!activeSoft[i] &&
510 maxsat_formula->getSoftClause(i).weight >= min_weight) {
511 assumptions.push(~maxsat_formula->getSoftClause(i).assumption_var);
519 for (std::set<Lit>::iterator it = cardinality_assumptions.begin();
520 it != cardinality_assumptions.end(); ++it) {
521 assert(boundMapping.find(*it) != boundMapping.end());
522 std::pair<std::pair<int, uint64_t>, uint64_t> soft_id =
524 if (soft_id.second >= min_weight) assumptions.push(~(*it));
std::vector< lbool > tSearch()
Solves the MaxSAT problem by calling the solver.
void tWeighted()
Solves a weighted MaxSAT problem.
TSolver(int verb=_VERBOSITY_MINIMAL_, int enc=_CARD_TOTALIZER_)
Constructs the TSolver object.