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 		boolean result = super.isSatisfiable(assumps, true);
113 		if (result) {
114 			prevmodel = super.model();
115 			prevfullmodel = new boolean[nVars()];
116 			for (int i = 0; i < nVars(); i++) {
117 				prevfullmodel[i] = decorated().model(i + 1);
118 			}
119 			if (objfct != null) {
120 				calculateObjective();
121 			}
122 		} else {
123 			if (previousPBConstr != null) {
124 				decorated().removeConstr(previousPBConstr);
125 				previousPBConstr = null;
126 			}
127 		}
128 		return result;
129 	}
130 
131 	public boolean hasNoObjectiveFunction() {
132 		return objfct == null;
133 	}
134 
135 	public boolean nonOptimalMeansSatisfiable() {
136 		return true;
137 	}
138 
139 	public Number calculateObjective() {
140 		objectiveValue = objfct.calculateDegree(prevmodel);
141 		return objectiveValue;
142 	}
143 
144 	public void discardCurrentSolution() throws ContradictionException {
145 		if (previousPBConstr != null) {
146 			super.removeSubsumedConstr(previousPBConstr);
147 		}
148 		previousPBConstr = super.addPseudoBoolean(objfct.getVars(), objfct
149 				.getCoeffs(), false, objectiveValue.subtract(BigInteger.ONE));
150 	}
151 
152 	@Override
153 	public void reset() {
154 		previousPBConstr = null;
155 		super.reset();
156 	}
157 
158 	@Override
159 	public int[] model() {
160 		// DLB findbugs ok
161 		return prevmodel;
162 	}
163 
164 	@Override
165 	public boolean model(int var) {
166 		return prevfullmodel[var - 1];
167 	}
168 
169 	@Override
170 	public String toString(String prefix) {
171 		return prefix + "Pseudo Boolean Optimization\n"
172 				+ super.toString(prefix);
173 	}
174 
175 	public Number getObjectiveValue() {
176 		return objectiveValue;
177 	}
178 
179 	public void discard() throws ContradictionException {
180 		discardCurrentSolution();
181 	}
182 
183 	public void forceObjectiveValueTo(Number forcedValue)
184 			throws ContradictionException {
185 		super.addPseudoBoolean(objfct.getVars(), objfct.getCoeffs(), false,
186 				(BigInteger) forcedValue);
187 	}
188 }