use of org.logicng.solvers.maxsat.encodings.Encoder in project LogicNG by logic-ng.
the class WMSU3 method iterativeBmo.
protected MaxSATResult iterativeBmo() {
assert this.isBmo;
this.nbInitialVariables = nVars();
Tristate res;
this.initRelaxation();
this.solver = this.rebuildSolver();
this.encoder.setIncremental(IncrementalStrategy.ITERATIVE);
final LNGIntVector joinObjFunction = new LNGIntVector();
final LNGIntVector encodingAssumptions = new LNGIntVector();
final LNGIntVector joinCoeffs = new LNGIntVector();
this.activeSoft.growTo(nSoft(), false);
for (int i = 0; i < nSoft(); i++) {
this.coreMapping.put(this.softClauses.get(i).assumptionVar(), i);
}
int minWeight = 0;
int posWeight = 0;
int localCost = 0;
final LNGVector<LNGIntVector> functions = new LNGVector<>();
final LNGIntVector weights = new LNGIntVector();
final LNGVector<Encoder> bmoEncodings = new LNGVector<>();
final LNGBooleanVector firstEncoding = new LNGBooleanVector();
functions.push(new LNGIntVector());
weights.push(0);
assert this.objFunction.size() == 0;
Encoder e = new Encoder(CardinalityEncoding.TOTALIZER);
e.setIncremental(IncrementalStrategy.ITERATIVE);
bmoEncodings.push(e);
firstEncoding.push(true);
while (true) {
final SATHandler satHandler = satHandler();
res = searchSATSolver(this.solver, satHandler, this.assumptions);
if (aborted(satHandler)) {
return MaxSATResult.UNDEF;
} else if (res == TRUE) {
this.nbSatisfiable++;
final int newCost = computeCostModel(this.solver.model(), Integer.MAX_VALUE);
if (newCost < this.ubCost || this.nbSatisfiable == 1) {
saveModel(this.solver.model());
if (this.verbosity != Verbosity.NONE) {
this.output.println("o " + newCost);
}
this.ubCost = newCost;
}
if (this.nbSatisfiable == 1) {
if (this.ubCost == 0) {
return MaxSATResult.OPTIMUM;
} else if (!foundUpperBound(this.ubCost, null)) {
return MaxSATResult.UNDEF;
}
assert this.orderWeights.size() > 0;
assert this.orderWeights.get(0) > 1;
minWeight = this.orderWeights.get(this.orderWeights.size() - 1);
this.currentWeight = this.orderWeights.get(0);
for (int i = 0; i < nSoft(); i++) {
if (this.softClauses.get(i).weight() >= this.currentWeight) {
this.assumptions.push(not(this.softClauses.get(i).assumptionVar()));
}
}
} else {
if (this.currentWeight == 1 || this.currentWeight == minWeight) {
return MaxSATResult.OPTIMUM;
} else {
if (!foundUpperBound(this.ubCost, null)) {
return MaxSATResult.UNDEF;
}
this.assumptions.clear();
final int previousWeight = this.currentWeight;
posWeight++;
assert posWeight < this.orderWeights.size();
this.currentWeight = this.orderWeights.get(posWeight);
if (this.objFunction.size() > 0) {
functions.set(functions.size() - 1, new LNGIntVector(this.objFunction));
}
functions.push(new LNGIntVector());
weights.push(0);
localCost = 0;
e = new Encoder(CardinalityEncoding.TOTALIZER);
e.setIncremental(IncrementalStrategy.ITERATIVE);
bmoEncodings.push(e);
firstEncoding.push(true);
for (int i = 0; i < encodingAssumptions.size(); i++) {
this.solver.addClause(encodingAssumptions.get(i), null);
}
encodingAssumptions.clear();
for (int i = 0; i < nSoft(); i++) {
if (!this.activeSoft.get(i) && previousWeight == this.softClauses.get(i).weight()) {
this.solver.addClause(not(this.softClauses.get(i).assumptionVar()), null);
}
if (this.currentWeight == this.softClauses.get(i).weight()) {
this.assumptions.push(not(this.softClauses.get(i).assumptionVar()));
}
if (this.activeSoft.get(i)) {
assert this.softClauses.get(i).weight() == previousWeight;
this.activeSoft.set(i, false);
}
}
}
}
} else {
localCost++;
this.lbCost += this.currentWeight;
this.nbCores++;
if (this.verbosity != Verbosity.NONE) {
this.output.println("c LB : " + this.lbCost);
}
if (this.nbSatisfiable == 0) {
return MaxSATResult.UNSATISFIABLE;
} else if (this.lbCost == this.ubCost) {
assert this.nbSatisfiable > 0;
if (this.verbosity != Verbosity.NONE) {
this.output.println("c LB = UB");
}
return MaxSATResult.OPTIMUM;
} else if (!foundLowerBound(this.lbCost, null)) {
return MaxSATResult.UNDEF;
}
this.sumSizeCores += this.solver.conflict().size();
joinObjFunction.clear();
joinCoeffs.clear();
for (int i = 0; i < this.solver.conflict().size(); i++) {
if (this.coreMapping.containsKey(this.solver.conflict().get(i))) {
if (this.activeSoft.get(this.coreMapping.get(this.solver.conflict().get(i)))) {
continue;
}
assert this.softClauses.get(this.coreMapping.get(this.solver.conflict().get(i))).weight() == this.currentWeight;
this.activeSoft.set(this.coreMapping.get(this.solver.conflict().get(i)), true);
joinObjFunction.push(this.softClauses.get(this.coreMapping.get(this.solver.conflict().get(i))).relaxationVars().get(0));
joinCoeffs.push(this.softClauses.get(this.coreMapping.get(this.solver.conflict().get(i))).weight());
}
}
this.objFunction.clear();
this.coeffs.clear();
this.assumptions.clear();
for (int i = 0; i < nSoft(); i++) {
if (this.activeSoft.get(i)) {
assert this.softClauses.get(i).weight() == this.currentWeight;
this.objFunction.push(this.softClauses.get(i).relaxationVars().get(0));
this.coeffs.push(this.softClauses.get(i).weight());
} else if (this.currentWeight == this.softClauses.get(i).weight()) {
this.assumptions.push(not(this.softClauses.get(i).assumptionVar()));
}
}
if (this.verbosity != Verbosity.NONE) {
this.output.printf("c Relaxed soft clauses %d / %d%n", this.objFunction.size(), nSoft());
}
assert posWeight < functions.size();
functions.set(posWeight, new LNGIntVector(this.objFunction));
weights.set(posWeight, localCost);
if (firstEncoding.get(posWeight)) {
if (weights.get(posWeight) != this.objFunction.size()) {
bmoEncodings.get(posWeight).buildCardinality(this.solver, this.objFunction, weights.get(posWeight));
joinObjFunction.clear();
bmoEncodings.get(posWeight).incUpdateCardinality(this.solver, joinObjFunction, this.objFunction, weights.get(posWeight), encodingAssumptions);
firstEncoding.set(posWeight, false);
}
} else {
bmoEncodings.get(posWeight).incUpdateCardinality(this.solver, joinObjFunction, this.objFunction, weights.get(posWeight), encodingAssumptions);
}
for (int i = 0; i < encodingAssumptions.size(); i++) {
this.assumptions.push(encodingAssumptions.get(i));
}
}
}
}
Aggregations