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 IConstr previousPBConstr;
52      private IConstr addedConstr = null;
53      private Number objectiveValue;
54      private boolean optimumFound = false;
55  
56      public ConstraintRelaxingPseudoOptDecorator(IPBSolver solver) {
57          super(solver);
58      }
59  
60      @Override
61      public boolean isSatisfiable() throws TimeoutException {
62          return isSatisfiable(VecInt.EMPTY);
63      }
64  
65      @Override
66      public boolean isSatisfiable(boolean global) throws TimeoutException {
67          return isSatisfiable(VecInt.EMPTY, global);
68      }
69  
70      @Override
71      public boolean isSatisfiable(IVecInt assumps, boolean global)
72              throws TimeoutException {
73          boolean result = super.isSatisfiable(assumps, true);
74          if (result) {
75              calculateObjective();
76          } else {
77              if (this.previousPBConstr != null) {
78                  decorated().removeConstr(this.previousPBConstr);
79                  this.previousPBConstr = null;
80              }
81          }
82          return result;
83      }
84  
85      @Override
86      public boolean isSatisfiable(IVecInt assumps) throws TimeoutException {
87          return isSatisfiable(assumps, true);
88      }
89  
90      public boolean admitABetterSolution() throws TimeoutException {
91          return admitABetterSolution(VecInt.EMPTY);
92      }
93  
94      public boolean admitABetterSolution(IVecInt assumps)
95              throws TimeoutException {
96          boolean isSatisfiable;
97  
98          if (this.optimumFound) {
99              return false;
100         }
101         int maxValue = getObjectiveFunction().minValue().intValue();
102         while (true) {
103             if (this.addedConstr != null) {
104                 this.decorated().removeConstr(this.addedConstr);
105             }
106             try {
107                 forceObjectiveValueTo(maxValue++);
108             } catch (ContradictionException e) {
109                 if (isVerbose()) {
110                     System.out.println(decorated().getLogPrefix()
111                             + "no solution for objective value "
112                             + (maxValue - 1));
113                 }
114                 continue;
115             }
116             isSatisfiable = super.isSatisfiable(assumps, true);
117             if (isSatisfiable) {
118                 this.optimumFound = true;
119                 if (getObjectiveFunction() != null) {
120                     calculateObjective();
121                 }
122                 this.decorated().removeConstr(this.addedConstr);
123                 return true;
124             }
125             if (isVerbose()) {
126                 System.out.println(decorated().getLogPrefix()
127                         + "no solution for objective value " + (maxValue - 1));
128             }
129         }
130     }
131 
132     public boolean hasNoObjectiveFunction() {
133         return getObjectiveFunction() == null;
134     }
135 
136     public boolean nonOptimalMeansSatisfiable() {
137         return false;
138     }
139 
140     @Deprecated
141     public Number calculateObjective() {
142         if (getObjectiveFunction() == null) {
143             throw new UnsupportedOperationException(
144                     "The problem does not contain an objective function");
145         }
146         this.objectiveValue = getObjectiveFunction().calculateDegree(this);
147         return this.objectiveValue;
148     }
149 
150     public Number getObjectiveValue() {
151         return this.objectiveValue;
152     }
153 
154     public void forceObjectiveValueTo(Number forcedValue)
155             throws ContradictionException {
156         this.addedConstr = super.addPseudoBoolean(getObjectiveFunction()
157                 .getVars(), getObjectiveFunction().getCoeffs(), false,
158                 BigInteger.valueOf(forcedValue.longValue()));
159     }
160 
161     @Deprecated
162     public void discard() {
163         discardCurrentSolution();
164     }
165 
166     public void discardCurrentSolution() {
167         // nothing to do here
168     }
169 
170     public boolean isOptimal() {
171         return this.optimumFound;
172     }
173 
174     @Override
175     public String toString(String prefix) {
176         return prefix + "Pseudo Boolean Optimization by lower bound\n"
177                 + super.toString(prefix);
178     }
179 
180     public void setTimeoutForFindingBetterSolution(int seconds) {
181         throw new UnsupportedOperationException("Does not make sense here");
182     }
183 
184 }