@Override public void propagate(int evtmask) throws ContradictionException { int remainingCapacity = capacity.getUB(); int maxPower = 0; for (int i = 0; i < n; i++) { remainingCapacity -= weigth[i] * vars[i].getLB(); maxPower += energy[i] * vars[i].getLB(); } power.updateLowerBound(maxPower, this); if (remainingCapacity < 0) { fails(); } else { int idx; for (int i = 0; i < n; i++) { assert remainingCapacity >= 0; idx = order[i]; if (vars[idx].getUB() - vars[idx].getLB() > 0) { int delta = weigth[idx] * (vars[idx].getUB() - vars[idx].getLB()); if (delta <= remainingCapacity) { maxPower += energy[idx] * (vars[idx].getUB() - vars[idx].getLB()); remainingCapacity -= delta; if (remainingCapacity == 0) { power.updateUpperBound(maxPower, this); return; } } else { int deltaPow = (int) Math.ceil((double) remainingCapacity * ratio[idx]); power.updateUpperBound(maxPower + deltaPow, this); return; } } } } }
@Override public ESat isEntailed() { if (set.getEnvelopeSize() == 0) { if (notEmpty) { return ESat.FALSE; } else { return ESat.TRUE; } } int lb = min.getLB(); int ub = min.getUB(); for (int j = set.getKernelFirst(); j != SetVar.END; j = set.getKernelNext()) { if (get(j) < lb) { return ESat.FALSE; } } int minVal = Integer.MAX_VALUE; for (int j = set.getEnvelopeFirst(); j != SetVar.END; j = set.getEnvelopeNext()) { if (minVal > get(j)) { minVal = get(j); } } if (minVal > ub && (notEmpty || set.getKernelSize() > 0)) { return ESat.FALSE; } if (isCompletelyInstantiated()) { return ESat.TRUE; } return ESat.UNDEFINED; }
/** * Set all variables to their respective value in the solution Throws an exception is this empties * a domain (i.e. this domain does not contain the solution value) * * <p>BEWARE: A restart might be required so that domains contain the solution values */ public void restore(Solver solver) throws ContradictionException { if (empty) { throw new UnsupportedOperationException("Empty solution. No solution found"); } Variable[] vars = solver.getVars(); for (int i = 0; i < vars.length; i++) { if ((vars[i].getTypeAndKind() & Variable.TYPE) != Variable.CSTE) { int kind = vars[i].getTypeAndKind() & Variable.KIND; switch (kind) { case Variable.INT: case Variable.BOOL: IntVar v = (IntVar) vars[i]; int value = intmap.get(v.getId()); if (value != NO_ENTRY) { v.instantiateTo(value, this); } // otherwise, this is not a decision variable break; case Variable.REAL: RealVar r = (RealVar) vars[i]; double[] bounds = realmap.get(r.getId()); if (bounds != null) { r.updateBounds(bounds[0], bounds[1], this); } // otherwise, this is not a decision variable break; case Variable.SET: SetVar s = (SetVar) vars[i]; int[] values = setmap.get(s.getId()); if (values != null) { s.instantiateTo(values, Cause.Null); } // otherwise, this is not a decision variable break; } } } }
public String toString(Solver solver) { Variable[] vars = solver.getVars(); StringBuilder st = new StringBuilder("Solution: "); for (int i = 0; i < vars.length; i++) { if ((vars[i].getTypeAndKind() & Variable.TYPE) != Variable.CSTE) { int kind = vars[i].getTypeAndKind() & Variable.KIND; switch (kind) { case Variable.INT: case Variable.BOOL: IntVar v = (IntVar) vars[i]; st.append(v.getName()).append("=").append(intmap.get(v.getId())).append(", "); break; case Variable.REAL: RealVar r = (RealVar) vars[i]; double[] bounds = realmap.get(r.getId()); st.append(r.getName()) .append("=[") .append(bounds[0]) .append(",") .append(bounds[1]) .append("], "); break; case Variable.SET: SetVar s = (SetVar) vars[i]; st.append(s.getName()) .append("=") .append(Arrays.toString(setmap.get(s.getId()))) .append(", "); break; } } } return st.toString(); }
private PropTestDM1(IntVar i, IntVar j) { super(new IntVar[] {i, j}, PropagatorPriority.UNARY, true); this.i = i; this.j = j; iD = i.monitorDelta(this); jD = j.monitorDelta(this); }
@Override public void propagate(int evtmask) throws ContradictionException { int min = 0; int max = 0; ISet nodes = g.getPotentialNodes(); for (int i = nodes.getFirstElement(); i >= 0; i = nodes.getNextElement()) { if (g.getMandSuccOrNeighOf(i).contain(i)) { min++; max++; } else if (g.getPotSuccOrNeighOf(i).contain(i)) { max++; } } k.updateLowerBound(min, aCause); k.updateUpperBound(max, aCause); if (min == max) { setPassive(); } else if (k.isInstantiated()) { if (k.getValue() == max) { for (int i = nodes.getFirstElement(); i >= 0; i = nodes.getNextElement()) { if (g.getPotSuccOrNeighOf(i).contain(i)) { g.enforceArc(i, i, aCause); } } setPassive(); } else if (k.getValue() == min) { for (int i = nodes.getFirstElement(); i >= 0; i = nodes.getNextElement()) { if (!g.getMandSuccOrNeighOf(i).contain(i)) { g.removeArc(i, i, aCause); } } setPassive(); } } }
/** * AtLeastNValues Propagator (similar to SoftAllDiff) The number of distinct values in vars is at * least nValues Performs Generalized Arc Consistency based on Maximum Bipartite Matching The * worst case time complexity is O(nm) but this is very pessimistic In practice it is more like * O(m) where m is the number of variable-value pairs * * @param variables array of integer variables * @param nValues integer variable */ public PropAtLeastNValues_AC(IntVar[] variables, IntVar nValues) { super(ArrayUtils.append(variables, new IntVar[] {nValues}), PropagatorPriority.QUADRATIC, true); this.idms = new IIntDeltaMonitor[this.vars.length]; for (int i = 0; i < this.vars.length; i++) { idms[i] = this.vars[i].monitorDelta(this); } n = variables.length; map = new TIntIntHashMap(); IntVar v; int ub; int idx = n; for (int i = 0; i < n; i++) { v = vars[i]; ub = v.getUB(); for (int j = v.getLB(); j <= ub; j = v.nextValue(j)) { if (!map.containsKey(j)) { map.put(j, idx); idx++; } } } n2 = idx; fifo = new int[n2]; digraph = new DirectedGraph(model, n2 + 2, SetType.LINKED_LIST, false); free = new BitSet(n2); remProc = new DirectedRemProc(); father = new int[n2]; in = new BitSet(n2); SCCfinder = new StrongConnectivityFinder(digraph); }
private static String prettyMethod(IntVar method) { if (method.isInstantiatedTo(0)) { return "migration"; } else if (method.isInstantiatedTo(1)) { return "re-instantiation"; } return "(migration || re-instantiation)"; }
private boolean match() { int lb = x.getLB(); int ub = x.getUB(); for (; lb <= ub; lb = x.nextValue(lb)) { if (y.contains(lb - cste)) return true; } return false; }
@Override public ESat isEntailed() { if ((x.getUB() < y.getLB() + cste) || (x.getLB() > y.getUB() + cste) || x.hasEnumeratedDomain() && y.hasEnumeratedDomain() && !match()) return ESat.FALSE; else if (x.isInstantiated() && y.isInstantiated() && (x.getValue() == y.getValue() + cste)) return ESat.TRUE; else return ESat.UNDEFINED; }
/** * Randomly selects a variable and assigns it to a value randomly taken in the domain. This is * dedicated to enumerated domains. In case some variables have bounded domains, please use * random_valueOrBound instead * * @param VARS list of variables * @param SEED a seed for random * @return assignment strategy */ public static IntStrategy random_value(IntVar[] VARS, long SEED) { for (IntVar v : VARS) { if (!v.hasEnumeratedDomain()) { throw new UnsupportedOperationException( "Some variables have bounded domains, " + "please use random heuristic instead"); } } return custom(random_var_selector(SEED), random_value_selector(SEED), VARS); }
/** In case of a GT, due to a modification on v0 domain */ public void filterGTonVar(IntVar v0, IntVar v1) throws ContradictionException { if (cste >= 0) { int lbv0 = v0.getUB() - cste; int ubv0 = v0.getLB() + cste; // remove interval [lbv0, ubv0] from domain of vars[0] v1.removeInterval(lbv0, ubv0, this); } else { this.setPassive(); } }
private void backPropRemPoss() throws ContradictionException { ISetIterator iter = poss.iterator(); while (iter.hasNext()) { int i = iter.nextInt(); IntVar v = vars[i]; if (v.hasEnumeratedDomain()) { for (int value : values) { v.removeValue(value, this); } poss.remove(i); } else { int newLB = v.getLB(); int newUB = v.getUB(); for (int val = v.getLB(); val <= newUB; val = v.nextValue(val)) { if (setValues.contains(val)) { newLB = val + 1; } else { break; } } for (int val = newUB; val >= newLB; val = v.previousValue(val)) { if (setValues.contains(val)) { newUB = val - 1; } else { break; } } v.updateBounds(newLB, newUB, this); if (newLB > values[values.length - 1] || newUB < values[0]) { poss.remove(i); } } } }
@Test(groups = "1s", timeOut = 60000) public void testNominal() { Model model = new Model(); IntVar var = model.intVar(10); SetVar setVar = model.setVar(new int[] {}, new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}); model.member(var, setVar).post(); assertEquals(model.getSolver().isSatisfied(), ESat.UNDEFINED); checkSolutions(model, setVar, var.getValue()); }
/** In case of a EQ, due to the instantion to one variable to val */ public void filterOnInst(IntVar v, int val) throws ContradictionException { if (!v.contains(val + cste)) { v.instantiateTo(val - cste, this); } else if (!v.contains(val - cste)) { v.instantiateTo(val + cste, this); } else { if (v.hasEnumeratedDomain()) { DisposableRangeIterator rit = v.getRangeIterator(true); try { while (rit.hasNext()) { int from = rit.min(); int to = rit.max(); for (int value = from; value <= to; value++) { if (value != (val - cste) && value != (val + cste)) { v.removeValue(value, this); } } rit.next(); } } finally { rit.dispose(); } } else { v.updateBounds(val - cste, val + cste, this); } } }
@SuppressWarnings({"unchecked"}) public PropEqualX_YC(IntVar[] vars, int c) { super(vars, PropagatorPriority.BINARY, true); this.x = vars[0]; this.y = vars[1]; this.cste = c; if (x.hasEnumeratedDomain() && y.hasEnumeratedDomain()) { bothEnumerated = true; idms = new IIntDeltaMonitor[2]; idms[0] = vars[0].monitorDelta(this); idms[1] = vars[1].monitorDelta(this); rem_proc = new RemProc(); } }
@SuppressWarnings("StatementWithEmptyBody") private void updateBounds() throws ContradictionException { while (x.updateLowerBound(y.getLB() + cste, aCause) | y.updateLowerBound(x.getLB() - cste, aCause)) ; while (x.updateUpperBound(y.getUB() + cste, aCause) | y.updateUpperBound(x.getUB() - cste, aCause)) ; }
/** * Get the value of variable v in this solution * * @param v IntVar (or BoolVar) * @return the value of variable v in this solution, or null if the variable is not instantiated * in the solution */ public Integer getIntVal(IntVar v) { if (empty) { throw new UnsupportedOperationException("Empty solution. No solution found"); } if (intmap.containsKey(v.getId())) { return intmap.get(v.getId()); } else { if ((v.getTypeAndKind() & Variable.TYPE) == Variable.CSTE) { return v.getValue(); } else { return null; } } }
/** In case of a EQ, due to a modification of the lower bound of v0 */ public void filterOnInf(IntVar v0, IntVar v1) throws ContradictionException { if (v1.hasEnumeratedDomain()) { int end = v0.getLB() + cste; for (int val = v0.getLB(); val <= end; val = v1.nextValue(val)) { if (!v0.contains(val - cste) && !v0.contains(val + cste)) { v1.removeValue(val, this); } } } else { v1.updateLowerBound(v0.getLB() - cste, this); } }
@Test(groups = "1s") public void testEq() throws ContradictionException { Solver solver = new Solver(); IntVar x = VariableFactory.enumerated("X", 1, 6, solver); IntVar y = VariableFactory.enumerated("Y", 1, 6, solver); solver.post(IntConstraintFactory.arithm(x, "=", y)); solver.propagate(); x.removeValue(4, Cause.Null); solver.propagate(); Assert.assertFalse(y.contains(4)); }
/** * Initial propagation in case of EQ and enumerated domains * * @throws ContradictionException */ public void filterFromVarToVar(IntVar var1, IntVar var2) throws ContradictionException { DisposableRangeIterator it = var1.getRangeIterator(true); try { while (it.hasNext()) { int from = it.min(); int to = it.max(); for (int value = from; value <= to; value++) if (!var2.contains(value - cste) && !var2.contains(value + cste)) { var1.removeValue(value, this); } it.next(); } } finally { it.dispose(); } }
@Override public ESat isEntailed() { IntVar union = vars[0]; int instCount = 0; for (int i = 1; i < vars.length; i++) { if (vars[i].isInstantiated()) { instCount++; if (!union.contains(vars[i].getValue())) { return ESat.FALSE; } } } if (instCount == vars.length - 1) { return ESat.TRUE; } return ESat.UNDEFINED; }
@Override public ESat isEntailed() { assert intVars.length == realVars.length; boolean allInst = true; for (int i = 0; i < n; i++) { IntVar intVar = intVars[i]; RealVar realVar = realVars[i]; if ((realVar.getLB() < (double) intVar.getLB() - epsilon) || (realVar.getUB() > (double) intVar.getUB() + epsilon)) { return ESat.FALSE; } if (!(intVar.isInstantiated() && realVar.isInstantiated())) { allInst = false; } } return allInst ? ESat.TRUE : ESat.UNDEFINED; }
/** * Records the current solution of the solver clears all previous recordings * * @param solver a solver */ public void record(Solver solver) { if (empty) { Variable[] _dvars = solver.getStrategy().getVariables(); for (int i = 0; i < _dvars.length; i++) { dvars.add(_dvars[i].getId()); } empty = false; } boolean warn = false; intmap.clear(); realmap.clear(); setmap.clear(); Variable[] vars = solver.getVars(); for (int i = 0; i < vars.length; i++) { if ((vars[i].getTypeAndKind() & Variable.TYPE) != Variable.CSTE) { int kind = vars[i].getTypeAndKind() & Variable.KIND; if (!vars[i].isInstantiated()) { if (dvars.contains(vars[i].getId())) { throw new SolverException(vars[i] + " is not instantiated when recording a solution."); } else { warn = true; } } else { switch (kind) { case Variable.INT: case Variable.BOOL: IntVar v = (IntVar) vars[i]; intmap.put(v.getId(), v.getValue()); break; case Variable.REAL: RealVar r = (RealVar) vars[i]; realmap.put(r.getId(), new double[] {r.getLB(), r.getUB()}); break; case Variable.SET: SetVar s = (SetVar) vars[i]; setmap.put(s.getId(), s.getValues()); break; } } } } if (warn && solver.getSettings().warnUser()) { Chatterbox.err.printf( "Some non decision variables are not instantiated in the current solution."); } }
@Override public ESat isEntailed() { double camax = capacity.getUB(); double pomin = 0; for (int i = 0; i < n; i++) { camax -= weigth[i] * vars[i].getLB(); pomin += energy[i] * vars[i].getLB(); } if (camax < 0 || pomin > power.getUB()) { return ESat.FALSE; } if (isCompletelyInstantiated()) { if (pomin == power.getValue()) { return ESat.TRUE; } } return ESat.UNDEFINED; }
@Override public void propagate(int varIdx, int mask) throws ContradictionException { updateBounds(); if (x.isInstantiated()) { assert (y.isInstantiated()); setPassive(); } else if (bothEnumerated) { if (varIdx == 0) { indexToFilter = 1; offSet = -cste; } else { indexToFilter = 0; offSet = cste; } idms[varIdx].freeze(); idms[varIdx].forEachRemVal(rem_proc); idms[varIdx].unfreeze(); } }
public void pruningPhase() throws ContradictionException { for (int i = futureVars.nextSetBit(0); i > -1; i = futureVars.nextSetBit(i + 1)) { IntVar v = vars[i]; DisposableValueIterator it3 = v.getValueIterator(true); vrms.clear(); try { while (it3.hasNext()) { int val = it3.next(); if (!gacValues[i].get(val - offsets[i])) { vrms.add(val); // v.removeVal(val, this, false); } } v.removeValues(vrms, this); } finally { it3.dispose(); } } }
private void buildDigraph() { for (int i = 0; i < n2; i++) { digraph.getSuccOf(i).clear(); digraph.getPredOf(i).clear(); } free.set(0, n2); int j, k, ub; IntVar v; for (int i = 0; i < n2 + 2; i++) { digraph.removeNode(i); } for (int i = 0; i < n; i++) { v = vars[i]; ub = v.getUB(); for (k = v.getLB(); k <= ub; k = v.nextValue(k)) { j = map.get(k); digraph.addArc(i, j); } } }
@Override public ESat isEntailed() { int min = 0; int max = 0; ISet env = g.getPotentialNodes(); for (int i = env.getFirstElement(); i >= 0; i = env.getNextElement()) { if (g.getMandSuccOrNeighOf(i).contain(i)) { min++; max++; } else if (g.getPotSuccOrNeighOf(i).contain(i)) { max++; } } if (k.getLB() > max || k.getUB() < min) { return ESat.FALSE; } if (min == max) { return ESat.TRUE; } return ESat.UNDEFINED; }
@Override public void propagate(int evtmask) throws ContradictionException { for (int j = set.getKernelFirst(); j != SetVar.END; j = set.getKernelNext()) { min.updateUpperBound(get(j), this); } int minVal = Integer.MAX_VALUE; int lb = min.getLB(); for (int j = set.getEnvelopeFirst(); j != SetVar.END; j = set.getEnvelopeNext()) { int k = get(j); if (k < lb) { set.removeFromEnvelope(j, this); } else { if (minVal > k) { minVal = k; } } } if (notEmpty || set.getKernelSize() > 0) { min.updateLowerBound(minVal, this); } }