// maintain the list by checking only the variable that has changed when // * checking if a tuple is valid. // * // * @param idx : the variable changed public void maintainList(/*int idx*/ ) { int cidx = 0; int nLast = last.get(); while (cidx <= nLast) { int idxt = listuples[cidx++]; int[] tuple = relation.getTuple(idxt); if (valcheck.isValid(tuple /*,idx*/)) { // extract the supports for (int i = futureVars.nextSetBit(0); i > -1; i = futureVars.nextSetBit(i + 1)) { if (!gacValues[i].get(tuple[i] - offsets[i])) { gacValues[i].set(tuple[i] - offsets[i]); nbGacValues[i]++; if (nbGacValues[i] == vars[i].getDomainSize()) { futureVars.clear(i); } } } } else { // remove the tuple from the current list cidx--; final int temp = listuples[nLast]; listuples[nLast] = listuples[cidx]; listuples[cidx] = temp; last.add(-1); nLast--; } } }
/** * Main propagation loop. It maintains the list of valid tuples through the search * * @throws ContradictionException */ public void gacstr() throws ContradictionException { initializeData(); maintainList(); pruningPhase(); if (getCartesianProduct() <= last.get() + 1) { setPassive(); } }
private void filter() throws ContradictionException { int lb = nbSure.get(); int ub = poss.size() + lb; vars[nb_vars].updateBounds(lb, ub, this); if (vars[nb_vars].isInstantiated() && lb < ub) { if (vars[nb_vars].getValue() == lb) { backPropRemPoss(); } else if (vars[nb_vars].getValue() == ub) { backPropForcePoss(); } } }
@Override public void propagate(int vidx, int evtmask) throws ContradictionException { if (vidx != nb_vars && poss.contains(vidx)) { IntVar var = vars[vidx]; int nb = 0; for (int j : values) { if (var.contains(j)) { nb++; } } if (nb == var.getDomainSize()) { nbSure.add(1); poss.remove(vidx); vars[nb_vars].updateLowerBound(nbSure.get(), this); } else if (nb == 0) { poss.remove(vidx); vars[nb_vars].updateUpperBound(poss.size() + nbSure.get(), this); } } forcePropagate(PropagatorEventType.CUSTOM_PROPAGATION); }
private void backPropForcePoss() throws ContradictionException { ISetIterator iter = poss.iterator(); while (iter.hasNext()) { int i = iter.nextInt(); IntVar v = vars[i]; if (v.hasEnumeratedDomain()) { for (int val = v.getLB(); val <= v.getUB(); val = v.nextValue(val)) { if (!setValues.contains(val)) { v.removeValue(val, this); } } poss.remove(i); nbSure.add(1); } else { v.updateBounds(values[0], values[values.length - 1], this); 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 (v.isInstantiated()) { poss.remove(i); nbSure.add(1); } } } }
@Override public void propagate(int v, int mask) throws ContradictionException { if (vars[v].getEnvelopeSize() == 0) { if (emptySetIndex.get() != -1) { contradiction(vars[v], ""); } else { emptySetIndex.set(v); for (int i = 0; i < vars.length; i++) { int s = vars[i].getEnvelopeSize(); if (i != v && s != vars[i].getKernelSize()) { if (s == 0) { contradiction(vars[i], ""); } else if (s == 1) { vars[i].addToKernel(vars[i].getEnvelopeFirst(), this); } } } } } if (vars[v].getEnvelopeSize() == 1 && emptySetIndex.get() != -1) { vars[v].addToKernel(vars[v].getEnvelopeFirst(), this); } }
@Override public void propagate(int evtmask) throws ContradictionException { if (PropagatorEventType.isFullPropagation(evtmask)) { poss.clear(); int nbMandForSure = 0; for (int i = 0; i < nb_vars; i++) { IntVar var = vars[i]; int nb = 0; for (int j : values) { if (var.contains(j)) { nb++; } } if (nb == var.getDomainSize()) { nbMandForSure++; } else if (nb > 0) { poss.add(i); } } nbSure.set(nbMandForSure); } filter(); }