1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  package org.sat4j.maxsat;
20  
21  import java.math.BigInteger;
22  
23  import org.sat4j.core.Vec;
24  import org.sat4j.core.VecInt;
25  import org.sat4j.pb.IPBSolver;
26  import org.sat4j.pb.PBSolverDecorator;
27  import org.sat4j.specs.ContradictionException;
28  import org.sat4j.specs.IConstr;
29  import org.sat4j.specs.IOptimizationProblem;
30  import org.sat4j.specs.IVec;
31  import org.sat4j.specs.IVecInt;
32  import org.sat4j.specs.TimeoutException;
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  public class MinCostDecorator extends PBSolverDecorator implements
44  		IOptimizationProblem {
45  
46  	
47  
48  
49  	private static final long serialVersionUID = 1L;
50  
51  	private int[] costs;
52  
53  	private int[] prevmodel;
54  
55  	private final IVecInt vars = new VecInt();
56  
57  	private final IVec<BigInteger> coeffs = new Vec<BigInteger>();
58  
59  	private int objectivevalue;
60  
61  	private IConstr prevConstr;
62  
63  	public MinCostDecorator(IPBSolver solver) {
64  		super(solver);
65  	}
66  
67  	
68  
69  
70  
71  
72  	@Override
73  	public int newVar() {
74  		throw new UnsupportedOperationException();
75  	}
76  
77  	
78  
79  
80  
81  
82  
83  
84  
85  
86  	@Override
87  	public int newVar(int howmany) {
88  		costs = new int[howmany + 1];
89  		
90  		vars.clear();
91  		coeffs.clear();
92  		for (int i = 1; i <= howmany; i++) {
93  			vars.push(i);
94  			coeffs.push(BigInteger.ZERO);
95  		}
96  		
97  		
98  		return super.newVar(howmany);
99  	}
100 
101 	
102 
103 
104 
105 
106 
107 
108 	public int costOf(int var) {
109 		return costs[var];
110 	}
111 
112 	
113 
114 
115 
116 
117 
118 
119 
120 	public void setCost(int var, int cost) {
121 		costs[var] = cost;
122 		coeffs.set(var - 1, BigInteger.valueOf(cost));
123 	}
124 
125 	public boolean admitABetterSolution() throws TimeoutException {
126 		return admitABetterSolution(VecInt.EMPTY);
127 	}
128 
129 	public boolean admitABetterSolution(IVecInt assumps)
130 			throws TimeoutException {
131 		boolean result = super.isSatisfiable(assumps, true);
132 		if (result) {
133 			prevmodel = super.model();
134 			calculateObjective();
135 		}
136 		return result;
137 	}
138 
139 	public boolean hasNoObjectiveFunction() {
140 		return false;
141 	}
142 
143 	public boolean nonOptimalMeansSatisfiable() {
144 		return true;
145 	}
146 
147 	public Number calculateObjective() {
148 		objectivevalue = calculateDegree(prevmodel);
149 		return new Integer(objectivevalue);
150 	}
151 
152 	private int calculateDegree(int[] prevmodel2) {
153 		int tmpcost = 0;
154 		for (int i = 1; i < costs.length; i++) {
155 			if (prevmodel2[i - 1] > 0) {
156 				tmpcost += costs[i];
157 			}
158 		}
159 		return tmpcost;
160 	}
161 
162 	public void discardCurrentSolution() throws ContradictionException {
163 		if (prevConstr!=null) {
164 			super.removeSubsumedConstr(prevConstr);
165 		}
166 		prevConstr = super.addPseudoBoolean(vars, coeffs, false, BigInteger
167 				.valueOf(objectivevalue - 1));
168 	}
169 
170 	@Override
171 	public void reset() {
172 		prevConstr = null;
173 		super.reset();
174 	}
175 
176 	@Override
177 	public int[] model() {
178 		
179 		return prevmodel;
180 	}
181 
182 	public Number getObjectiveValue() {
183 		return objectivevalue;
184 	}
185 
186 	public void discard() throws ContradictionException {
187 		discardCurrentSolution();
188 	}
189 
190 	public void forceObjectiveValueTo(Number forcedValue)
191 			throws ContradictionException {
192 		super.addPseudoBoolean(vars, coeffs, false, (BigInteger)
193 				forcedValue);
194 	}
195 }