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;
31  
32  import java.io.PrintWriter;
33  
34  import org.sat4j.specs.ContradictionException;
35  import org.sat4j.specs.IOptimizationProblem;
36  import org.sat4j.specs.IProblem;
37  import org.sat4j.specs.TimeoutException;
38  
39  /**
40   * This class is intended to be used by launchers to solve optimization
41   * problems, i.e. problems for which a loop is needed to find the optimal
42   * solution.
43   * 
44   * @author leberre
45   * 
46   */
47  public abstract class AbstractOptimizationLauncher extends AbstractLauncher {
48  
49      /**
50  	 * 
51  	 */
52      private static final long serialVersionUID = 1L;
53  
54      private static final String CURRENT_OPTIMUM_VALUE_PREFIX = "o "; //$NON-NLS-1$
55  
56      private boolean incomplete = false;
57  
58      private boolean displaySolutionLine = true;
59  
60      protected void setIncomplete(boolean value) {
61          this.incomplete = value;
62      }
63  
64      protected void setDisplaySolutionLine(boolean value) {
65          this.displaySolutionLine = value;
66      }
67  
68      @Override
69      protected void displayResult() {
70          displayAnswer();
71  
72          log("Total wall clock time (in seconds): " //$NON-NLS-1$
73                  + (System.currentTimeMillis() - getBeginTime()) / 1000.0);
74      }
75  
76      protected void displayAnswer() {
77          if (this.solver == null) {
78              return;
79          }
80          System.out.flush();
81          PrintWriter out = getLogWriter();
82          out.flush();
83          this.solver.printStat(out, COMMENT_PREFIX);
84          this.solver.printInfos(out, COMMENT_PREFIX);
85          ExitCode exitCode = getExitCode();
86          out.println(ANSWER_PREFIX + exitCode);
87          if (exitCode == ExitCode.SATISFIABLE
88                  || exitCode == ExitCode.OPTIMUM_FOUND || this.incomplete
89                  && exitCode == ExitCode.UPPER_BOUND) {
90              if (this.displaySolutionLine) {
91                  out.print(SOLUTION_PREFIX);
92                  getReader().decode(this.solver.model(), out);
93                  out.println();
94              }
95              IOptimizationProblem optproblem = (IOptimizationProblem) this.solver;
96              if (!optproblem.hasNoObjectiveFunction()) {
97                  log("objective function=" + optproblem.getObjectiveValue()); //$NON-NLS-1$
98              }
99          }
100     }
101 
102     @Override
103     protected void solve(IProblem problem) throws TimeoutException {
104         boolean isSatisfiable = false;
105 
106         IOptimizationProblem optproblem = (IOptimizationProblem) problem;
107 
108         try {
109             while (optproblem.admitABetterSolution()) {
110                 if (!isSatisfiable) {
111                     if (optproblem.nonOptimalMeansSatisfiable()) {
112                         setExitCode(ExitCode.SATISFIABLE);
113                         if (optproblem.hasNoObjectiveFunction()) {
114                             return;
115                         }
116                         log("SATISFIABLE"); //$NON-NLS-1$
117                     } else if (this.incomplete) {
118                         setExitCode(ExitCode.UPPER_BOUND);
119                     }
120                     isSatisfiable = true;
121                     log("OPTIMIZING..."); //$NON-NLS-1$
122                 }
123                 log("Got one! Elapsed wall clock time (in seconds):" //$NON-NLS-1$
124                         + (System.currentTimeMillis() - getBeginTime())
125                         / 1000.0);
126                 getLogWriter().println(
127                         CURRENT_OPTIMUM_VALUE_PREFIX
128                                 + optproblem.getObjectiveValue());
129                 optproblem.discardCurrentSolution();
130             }
131             if (isSatisfiable) {
132                 setExitCode(ExitCode.OPTIMUM_FOUND);
133             } else {
134                 setExitCode(ExitCode.UNSATISFIABLE);
135             }
136         } catch (ContradictionException ex) {
137             assert isSatisfiable;
138             setExitCode(ExitCode.OPTIMUM_FOUND);
139         }
140     }
141 
142 }