Search in sources :

Example 1 with Encoder

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));
            }
        }
    }
}
Also used : SATHandler(org.logicng.handlers.SATHandler) Tristate(org.logicng.datastructures.Tristate) Encoder(org.logicng.solvers.maxsat.encodings.Encoder) LNGBooleanVector(org.logicng.collections.LNGBooleanVector) LNGIntVector(org.logicng.collections.LNGIntVector) LNGVector(org.logicng.collections.LNGVector)

Aggregations

LNGBooleanVector (org.logicng.collections.LNGBooleanVector)1 LNGIntVector (org.logicng.collections.LNGIntVector)1 LNGVector (org.logicng.collections.LNGVector)1 Tristate (org.logicng.datastructures.Tristate)1 SATHandler (org.logicng.handlers.SATHandler)1 Encoder (org.logicng.solvers.maxsat.encodings.Encoder)1