View Javadoc

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 pseudo boolean algorithms described in:
20   * A fast pseudo-Boolean constraint solver Chai, D.; Kuehlmann, A.
21   * Computer-Aided Design of Integrated Circuits and Systems, IEEE Transactions on
22   * Volume 24, Issue 3, March 2005 Page(s): 305 - 317
23   * 
24   * and 
25   * Heidi E. Dixon, 2004. Automating Pseudo-Boolean Inference within a DPLL 
26   * Framework. Ph.D. Dissertation, University of Oregon.
27   *******************************************************************************/
28  package org.sat4j.pb;
29  
30  import java.math.BigInteger;
31  
32  import org.sat4j.core.VecInt;
33  import org.sat4j.specs.ContradictionException;
34  import org.sat4j.specs.IConstr;
35  import org.sat4j.specs.IOptimizationProblem;
36  import org.sat4j.specs.IVecInt;
37  import org.sat4j.specs.TimeoutException;
38  
39  /**
40   * A decorator that computes minimal pseudo boolean models.
41   * 
42   * @author daniel
43   * 
44   */
45  public class PseudoOptDecorator extends PBSolverDecorator implements
46  		IOptimizationProblem {
47  
48  	/**
49       * 
50       */
51  	private static final long serialVersionUID = 1L;
52  
53  	private ObjectiveFunction objfct;
54  
55  	private BigInteger objectiveValue;
56  
57  	private int[] prevmodel;
58  	private boolean[] prevfullmodel;
59  
60  	private IConstr previousPBConstr;
61  
62  	public PseudoOptDecorator(IPBSolver solver) {
63  		super(solver);
64  	}
65  
66  	@Override
67  	public boolean isSatisfiable() throws TimeoutException {
68  		return isSatisfiable(VecInt.EMPTY);
69  	}
70  
71  	@Override
72  	public boolean isSatisfiable(boolean global) throws TimeoutException {
73  		return isSatisfiable(VecInt.EMPTY, global);
74  	}
75  
76  	@Override
77  	public boolean isSatisfiable(IVecInt assumps, boolean global)
78  			throws TimeoutException {
79  		boolean result = super.isSatisfiable(assumps, true);
80  		if (result) {
81  			prevmodel = super.model();
82  			prevfullmodel = new boolean[nVars()];
83  			for (int i = 0; i < nVars(); i++) {
84  				prevfullmodel[i] = decorated().model(i + 1);
85  			}
86  		} else {
87  			if (previousPBConstr != null) {
88  				decorated().removeConstr(previousPBConstr);
89  				previousPBConstr = null;
90  			}
91  		}
92  		return result;
93  	}
94  
95  	@Override
96  	public boolean isSatisfiable(IVecInt assumps) throws TimeoutException {
97  		return isSatisfiable(assumps, true);
98  	}
99  
100 	@Override
101 	public void setObjectiveFunction(ObjectiveFunction objf) {
102 		objfct = objf;
103 		decorated().setObjectiveFunction(objf);
104 	}
105 
106 	public boolean admitABetterSolution() throws TimeoutException {
107 		return admitABetterSolution(VecInt.EMPTY);
108 	}
109 
110 	public boolean admitABetterSolution(IVecInt assumps)
111 			throws TimeoutException {
112 		try {
113 			boolean result = super.isSatisfiable(assumps, true);
114 			if (result) {
115 				prevmodel = super.model();
116 				prevfullmodel = new boolean[nVars()];
117 				for (int i = 0; i < nVars(); i++) {
118 					prevfullmodel[i] = decorated().model(i + 1);
119 				}
120 				if (objfct != null) {
121 					calculateObjective();
122 				}
123 			} else {
124 				if (previousPBConstr != null) {
125 					decorated().removeConstr(previousPBConstr);
126 					previousPBConstr = null;
127 				}
128 			}
129 			return result;
130 		} catch (TimeoutException te) {
131 			if (previousPBConstr != null) {
132 				decorated().removeConstr(previousPBConstr);
133 				previousPBConstr = null;
134 			}
135 			throw te;
136 		}
137 	}
138 
139 	public boolean hasNoObjectiveFunction() {
140 		return objfct == null;
141 	}
142 
143 	public boolean nonOptimalMeansSatisfiable() {
144 		return true;
145 	}
146 
147 	public Number calculateObjective() {
148 		if (objfct == null) {
149 			throw new UnsupportedOperationException(
150 					"The problem does not contain an objective function");
151 		}
152 		objectiveValue = objfct.calculateDegree(prevmodel);
153 		return objectiveValue;
154 	}
155 
156 	public void discardCurrentSolution() throws ContradictionException {
157 		if (previousPBConstr != null) {
158 			super.removeSubsumedConstr(previousPBConstr);
159 		}
160 		if (objfct != null && objectiveValue != null) {
161 			previousPBConstr = super.addPseudoBoolean(objfct.getVars(), objfct
162 					.getCoeffs(), false, objectiveValue
163 					.subtract(BigInteger.ONE));
164 		}
165 	}
166 
167 	@Override
168 	public void reset() {
169 		previousPBConstr = null;
170 		super.reset();
171 	}
172 
173 	@Override
174 	public int[] model() {
175 		// DLB findbugs ok
176 		return prevmodel;
177 	}
178 
179 	@Override
180 	public boolean model(int var) {
181 		return prevfullmodel[var - 1];
182 	}
183 
184 	@Override
185 	public String toString(String prefix) {
186 		return prefix + "Pseudo Boolean Optimization\n"
187 				+ super.toString(prefix);
188 	}
189 
190 	public Number getObjectiveValue() {
191 		return objectiveValue;
192 	}
193 
194 	public void discard() throws ContradictionException {
195 		discardCurrentSolution();
196 	}
197 
198 	public void forceObjectiveValueTo(Number forcedValue)
199 			throws ContradictionException {
200 		super.addPseudoBoolean(objfct.getVars(), objfct.getCoeffs(), false,
201 				(BigInteger) forcedValue);
202 	}
203 }