1 /******************************************************************************* 2 * SAT4J: a SATisfiability library for Java Copyright (C) 2004-2008 Daniel Le Berre 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 *******************************************************************************/ 28 package org.sat4j.specs; 29 30 /** 31 * Represents an optimization problem. The SAT solver will find suboptimal 32 * solutions of the problem until no more solutions are available. The latest 33 * solution found will be the optimal one. 34 * 35 * Such kind of problem is supposed to be handled: 36 * 37 * <pre> 38 * boolean isSatisfiable = false; 39 * 40 * IOptimizationProblem optproblem = (IOptimizationProblem) problem; 41 * 42 * try { 43 * while (optproblem.admitABetterSolution()) { 44 * if (!isSatisfiable) { 45 * if (optproblem.nonOptimalMeansSatisfiable()) { 46 * setExitCode(ExitCode.SATISFIABLE); 47 * if (optproblem.hasNoObjectiveFunction()) { 48 * return; 49 * } 50 * log("SATISFIABLE"); //$NON-NLS-1$ 51 * } 52 * isSatisfiable = true; 53 * log("OPTIMIZING..."); //$NON-NLS-1$ 54 * } 55 * log("Got one! Elapsed wall clock time (in seconds):" //$NON-NLS-1$ 56 * + (System.currentTimeMillis() - getBeginTime()) / 1000.0); 57 * getLogWriter().println( 58 * CURRENT_OPTIMUM_VALUE_PREFIX + optproblem.getObjectiveValue()); 59 * optproblem.discardCurrentSolution(); 60 * } 61 * if (isSatisfiable) { 62 * setExitCode(ExitCode.OPTIMUM_FOUND); 63 * } else { 64 * setExitCode(ExitCode.UNSATISFIABLE); 65 * } 66 * } catch (ContradictionException ex) { 67 * assert isSatisfiable; 68 * setExitCode(ExitCode.OPTIMUM_FOUND); 69 * } 70 * </pre> 71 * 72 * @author leberre 73 * 74 */ 75 public interface IOptimizationProblem extends IProblem { 76 77 /** 78 * Look for a solution of the optimization problem. 79 * 80 * @return true if a better solution than current one can be found. 81 * @throws TimeoutException 82 * if the solver cannot answer in reasonable time. 83 * @see ISolver#setTimeout(int) 84 */ 85 boolean admitABetterSolution() throws TimeoutException; 86 87 /** 88 * Look for a solution of the optimization problem when some literals are 89 * satisfied. 90 * 91 * @param assumps 92 * a set of literals in Dimacs format. 93 * @return true if a better solution than current one can be found. 94 * @throws TimeoutException 95 * if the solver cannot answer in reasonable time. 96 * @see ISolver#setTimeout(int) 97 * @since 2.1 98 */ 99 boolean admitABetterSolution(IVecInt assumps) throws TimeoutException; 100 101 /** 102 * If the optimization problem has no objective function, then it is a 103 * simple decision problem. 104 * 105 * @return true if the problem is a decision problem, false if the problem 106 * is an optimization problem. 107 */ 108 boolean hasNoObjectiveFunction(); 109 110 /** 111 * A suboptimal solution has different meaning depending of the optimization 112 * problem considered. 113 * 114 * For instance, in the case of MAXSAT, a suboptimal solution does not mean 115 * that the problem is satisfiable, while in pseudo boolean optimization, it 116 * is true. 117 * 118 * @return true if founding a suboptimal solution means that the problem is 119 * satisfiable. 120 */ 121 boolean nonOptimalMeansSatisfiable(); 122 123 /** 124 * Compute the value of the objective function for the current solution. A 125 * call to that method only makes sense if hasNoObjectiveFunction()==false. 126 * 127 * DO NOT CALL THAT METHOD THAT WILL BE CALLED AUTOMATICALLY. USE 128 * getObjectiveValue() instead! 129 * 130 * @return the value of the objective function. 131 * @see #getObjectiveValue() 132 */ 133 @Deprecated 134 Number calculateObjective(); 135 136 /** 137 * Read only access to the value of the objective function for the current 138 * solution. 139 * 140 * @return the value of the objective function for the current solution. 141 * @since 2.1 142 */ 143 Number getObjectiveValue(); 144 145 /** 146 * Force the value of the objective function. 147 * 148 * This is especially useful to iterate over optimal solutions. 149 * 150 * @throws ContradictionException 151 * @since 2.1 152 */ 153 void forceObjectiveValueTo(Number forcedValue) 154 throws ContradictionException; 155 156 /** 157 * Discard the current solution in the optimization problem. 158 * 159 * THE NAME WAS NOT NICE. STILL AVAILABLE TO AVOID BREAKING THE API. PLEASE 160 * USE THE LONGER discardCurrentSolution() instead. 161 * 162 * @throws ContradictionException 163 * if a trivial inconsistency is detected. 164 * @see #discardCurrentSolution() 165 */ 166 @Deprecated 167 void discard() throws ContradictionException; 168 169 /** 170 * Discard the current solution in the optimization problem. 171 * 172 * @throws ContradictionException 173 * if a trivial inconsistency is detected. 174 * @since 2.1 175 */ 176 void discardCurrentSolution() throws ContradictionException; 177 178 /** 179 * Allows to check afterwards if the solution provided by the solver is 180 * optimal or not. 181 * 182 * @return 183 */ 184 boolean isOptimal(); 185 }