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