@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; }
@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(); } }
/** 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); } } }
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); } } } }
/** * 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 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); } }
@Override public void propagate(int evtmask) throws ContradictionException { for (int i = 0; i < n; i++) { IntVar intVar = intVars[i]; RealVar realVar = realVars[i]; realVar.updateBounds( (double) intVar.getLB() - epsilon, (double) intVar.getUB() + epsilon, aCause); intVar.updateLowerBound((int) Math.ceil(realVar.getLB() - epsilon), aCause); intVar.updateUpperBound((int) Math.floor(realVar.getUB() + epsilon), aCause); if (intVar.hasEnumeratedDomain()) { realVar.updateBounds( (double) intVar.getLB() - epsilon, (double) intVar.getUB() + epsilon, aCause); } } }
/** In case of a EQ, due to a modification of the upper bound of v0 */ public void filterOnSup(IntVar v0, IntVar v1) throws ContradictionException { if (v1.hasEnumeratedDomain()) { int initval; if (v0.getUB() - cste > v1.getLB()) { initval = v1.nextValue(v0.getUB() - cste - 1); } else { initval = v1.getLB(); } int val = initval; do { if (!v0.contains(val - cste) && !v0.contains(val + cste)) { v1.removeValue(val, this); } val = v1.nextValue(val); } while (val <= v1.getUB() && val > initval); // todo : pourquoi besoin du deuxieme currentElement ? } else { v1.updateUpperBound(v0.getUB() + cste, this); } }
private void filter() throws ContradictionException { buildSCC(); int j, ub; IntVar v; for (int i = 0; i < n; i++) { v = vars[i]; ub = v.getUB(); for (int k = v.getLB(); k <= ub; k = v.nextValue(k)) { j = map.get(k); if (nodeSCC[i] != nodeSCC[j]) { if (digraph.getPredOf(i).contains(j)) { v.instantiateTo(k, this); } else { v.removeValue(k, this); digraph.removeArc(i, j); } } } if (!v.hasEnumeratedDomain()) { ub = v.getUB(); for (int k = v.getLB(); k <= ub; k = v.nextValue(k)) { j = map.get(k); if (digraph.arcExists(i, j) || digraph.arcExists(j, i)) { break; } else { v.removeValue(k, this); } } int lb = v.getLB(); for (int k = ub; k >= lb; k = v.previousValue(k)) { j = map.get(k); if (digraph.arcExists(i, j) || digraph.arcExists(j, i)) { break; } else { v.removeValue(k, this); } } } } }