View Javadoc

1   /*******************************************************************************
2    * SAT4J: a SATisfiability library for Java Copyright (C) 2004, 2012 Artois University and CNRS
3    *
4    * All rights reserved. This program and the accompanying materials
5    * are made available under the terms of the Eclipse Public License v1.0
6    * which accompanies this distribution, and is available at
7    *  http://www.eclipse.org/legal/epl-v10.html
8    *
9    * Alternatively, the contents of this file may be used under the terms of
10   * either the GNU Lesser General Public License Version 2.1 or later (the
11   * "LGPL"), in which case the provisions of the LGPL are applicable instead
12   * of those above. If you wish to allow use of your version of this file only
13   * under the terms of the LGPL, and not to allow others to use your version of
14   * this file under the terms of the EPL, indicate your decision by deleting
15   * the provisions above and replace them with the notice and other provisions
16   * required by the LGPL. If you do not delete the provisions above, a recipient
17   * may use your version of this file under the terms of the EPL or the LGPL.
18   *
19   * Based on the original MiniSat specification from:
20   *
21   * An extensible SAT solver. Niklas Een and Niklas Sorensson. Proceedings of the
22   * Sixth International Conference on Theory and Applications of Satisfiability
23   * Testing, LNCS 2919, pp 502-518, 2003.
24   *
25   * See www.minisat.se for the original solver in C++.
26   *
27   * Contributors:
28   *   CRIL - initial API and implementation
29   *******************************************************************************/
30  package org.sat4j.pb;
31  
32  import java.math.BigInteger;
33  
34  import org.sat4j.core.VecInt;
35  import org.sat4j.specs.ContradictionException;
36  import org.sat4j.specs.IConstr;
37  import org.sat4j.specs.IOptimizationProblem;
38  import org.sat4j.specs.IVecInt;
39  import org.sat4j.specs.TimeoutException;
40  
41  /**
42   * 
43   * @author lonca
44   * 
45   */
46  
47  public class ConstraintRelaxingPseudoOptDecorator extends PBSolverDecorator
48          implements IOptimizationProblem {
49  
50      private static final long serialVersionUID = 1L;
51      private int[] bestModel;
52      private boolean[] bestFullModel;
53      private IConstr previousPBConstr;
54      private IConstr addedConstr = null;
55      private int maxValue = 0;
56      private Number objectiveValue;
57      private boolean optimumFound = false;
58  
59      public ConstraintRelaxingPseudoOptDecorator(IPBSolver solver) {
60          super(solver);
61      }
62  
63      @Override
64      public boolean isSatisfiable() throws TimeoutException {
65          return isSatisfiable(VecInt.EMPTY);
66      }
67  
68      @Override
69      public boolean isSatisfiable(boolean global) throws TimeoutException {
70          return isSatisfiable(VecInt.EMPTY, global);
71      }
72  
73      @Override
74      public boolean isSatisfiable(IVecInt assumps, boolean global)
75              throws TimeoutException {
76          boolean result = super.isSatisfiable(assumps, true);
77          if (result) {
78              this.bestModel = super.model();
79              this.bestFullModel = new boolean[nVars()];
80              for (int i = 0; i < nVars(); i++) {
81                  this.bestFullModel[i] = decorated().model(i + 1);
82              }
83              calculateObjective();
84          } else {
85              if (this.previousPBConstr != null) {
86                  decorated().removeConstr(this.previousPBConstr);
87                  this.previousPBConstr = null;
88              }
89          }
90          return result;
91      }
92  
93      @Override
94      public boolean isSatisfiable(IVecInt assumps) throws TimeoutException {
95          return isSatisfiable(assumps, true);
96      }
97  
98      public boolean admitABetterSolution() throws TimeoutException {
99          return admitABetterSolution(VecInt.EMPTY);
100     }
101 
102     public boolean admitABetterSolution(IVecInt assumps)
103             throws TimeoutException {
104         boolean isSatisfiable;
105 
106         if (this.optimumFound) {
107             return false;
108         }
109         this.maxValue = getObjectiveFunction().minValue().intValue();
110         while (true) {
111             if (this.addedConstr != null) {
112                 this.decorated().removeConstr(this.addedConstr);
113             }
114             try {
115                 forceObjectiveValueTo(this.maxValue++);
116             } catch (ContradictionException e) {
117                 if (isVerbose()) {
118                     System.out.println(decorated().getLogPrefix()
119                             + "no solution for objective value "
120                             + (this.maxValue - 1));
121                 }
122                 continue;
123             }
124             isSatisfiable = super.isSatisfiable(assumps, true);
125             if (isSatisfiable) {
126                 this.optimumFound = true;
127                 this.bestModel = super.model();
128                 this.bestFullModel = new boolean[nVars()];
129                 for (int i = 0; i < nVars(); i++) {
130                     this.bestFullModel[i] = decorated().model(i + 1);
131                 }
132                 if (getObjectiveFunction() != null) {
133                     calculateObjective();
134                 }
135                 this.decorated().removeConstr(this.addedConstr);
136                 return true;
137             }
138             if (isVerbose()) {
139                 System.out.println(decorated().getLogPrefix()
140                         + "no solution for objective value "
141                         + (this.maxValue - 1));
142             }
143         }
144     }
145 
146     public boolean hasNoObjectiveFunction() {
147         return getObjectiveFunction() == null;
148     }
149 
150     public boolean nonOptimalMeansSatisfiable() {
151         return false;
152     }
153 
154     @Deprecated
155     public Number calculateObjective() {
156         if (getObjectiveFunction() == null) {
157             throw new UnsupportedOperationException(
158                     "The problem does not contain an objective function");
159         }
160         this.objectiveValue = getObjectiveFunction().calculateDegree(this);
161         return this.objectiveValue;
162     }
163 
164     public Number getObjectiveValue() {
165         return this.objectiveValue;
166     }
167 
168     public void forceObjectiveValueTo(Number forcedValue)
169             throws ContradictionException {
170         this.addedConstr = super.addPseudoBoolean(getObjectiveFunction()
171                 .getVars(), getObjectiveFunction().getCoeffs(), false,
172                 BigInteger.valueOf(forcedValue.longValue()));
173     }
174 
175     @Deprecated
176     public void discard() {
177         discardCurrentSolution();
178     }
179 
180     public void discardCurrentSolution() {
181         // nothing to do here
182     }
183 
184     public boolean isOptimal() {
185         return this.optimumFound;
186     }
187 
188     @Override
189     public String toString(String prefix) {
190         return prefix + "Pseudo Boolean Optimization by lower bound\n"
191                 + super.toString(prefix);
192     }
193 
194 }