From 7ef941158cd04aaed3101fb38dd2f35367e6585c Mon Sep 17 00:00:00 2001 From: cprudhom Date: Mon, 28 Nov 2022 11:36:02 +0100 Subject: [PATCH 1/3] Adapt iteration over ISet to use `nextInt()` method --- .../nary/cumulative/PropGraphCumulative.java | 36 ++++++++++--------- .../nary/cumulative/TimeCumulFilter.java | 4 ++- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/solver/src/main/java/org/chocosolver/solver/constraints/nary/cumulative/PropGraphCumulative.java b/solver/src/main/java/org/chocosolver/solver/constraints/nary/cumulative/PropGraphCumulative.java index 1d5e1a31b6..216b80024d 100644 --- a/solver/src/main/java/org/chocosolver/solver/constraints/nary/cumulative/PropGraphCumulative.java +++ b/solver/src/main/java/org/chocosolver/solver/constraints/nary/cumulative/PropGraphCumulative.java @@ -57,7 +57,7 @@ public class PropGraphCumulative extends PropCumulative { * @param e end variables * @param h height variables * @param capa capacity variable - * @param fast reduces the number of propagation (less filtering) + * @param fast reduces the number of propagation (less filtering) * @param filters filtering algorithm to use */ public PropGraphCumulative(IntVar[] s, IntVar[] d, IntVar[] e, IntVar[] h, IntVar capa, boolean fast, @@ -66,7 +66,7 @@ public PropGraphCumulative(IntVar[] s, IntVar[] d, IntVar[] e, IntVar[] h, IntVa this.g = new UndirectedGraph(model, n, SetType.BITSET, true); this.tasks = SetFactory.makeBipartiteSet(0); this.toCompute = SetFactory.makeBipartiteSet(0); - this.fast = fast; + this.fast = fast; } //*********************************************************************************** @@ -79,26 +79,28 @@ public void propagate(int evtmask) throws ContradictionException { super.propagate(evtmask); graphComputation(); } else { - if(full){ + if (full) { filter(allTasks); - }else { + } else { int count = 0; ISetIterator tcIt = toCompute.iterator(); - while (tcIt.hasNext()){ + while (tcIt.hasNext()) { int i = tcIt.nextInt(); - for (int j : g.getNeighborsOf(i)) { + ISetIterator it = g.getNeighborsOf(i).iterator(); + while (it.hasNext()) { + int j = it.nextInt(); if (disjoint(i, j)) { g.removeEdge(i, j); } } count += g.getNeighborsOf(i).size(); - if(count >= 2*n)break; + if (count >= 2 * n) break; } - if (count >= 2*n) { + if (count >= 2 * n) { filter(allTasks); } else { ISetIterator iter = toCompute.iterator(); - while (iter.hasNext()){ + while (iter.hasNext()) { filterAround(iter.nextInt()); } } @@ -117,20 +119,20 @@ public void propagate(int varIdx, int mask) throws ContradictionException { } if (varIdx < 4 * n) { int v = varIdx % n; - if(h[v].getUB()==0 || d[v].getUB()==0){ + if (h[v].getUB() == 0 || d[v].getUB() == 0) { allTasks.remove(v); ISetIterator gIt = g.getNeighborsOf(v).iterator(); - while (gIt.hasNext()){ - g.removeEdge(v,gIt.nextInt()); + while (gIt.hasNext()) { + g.removeEdge(v, gIt.nextInt()); } - }else if(s[v].getUB()0 && d[event.index].getUB()>0; - if(eok) { + boolean eok = h[event.index].getUB() > 0 && d[event.index].getUB() > 0; + if (eok) { for (int i = tprune.nextSetBit(0); i >= 0; i = tprune.nextSetBit(i + 1)) { - if(h[i].getUB()>0 && d[i].getUB()>0) { + if (h[i].getUB() > 0 && d[i].getUB() > 0) { g.addEdge(i, event.index); } } diff --git a/solver/src/main/java/org/chocosolver/solver/constraints/nary/cumulative/TimeCumulFilter.java b/solver/src/main/java/org/chocosolver/solver/constraints/nary/cumulative/TimeCumulFilter.java index c0d7aadc5a..1d0710a79b 100644 --- a/solver/src/main/java/org/chocosolver/solver/constraints/nary/cumulative/TimeCumulFilter.java +++ b/solver/src/main/java/org/chocosolver/solver/constraints/nary/cumulative/TimeCumulFilter.java @@ -91,7 +91,9 @@ public void filter(IntVar[] s, IntVar[] d, IntVar[] e, IntVar[] h, IntVar capa, h[i].updateUpperBound(minH,aCause); } } - for (int i : tasks) { + tIter = tasks.iterator(); + while (tIter.hasNext()){ + int i = tIter.nextInt(); if (h[i].getLB() > 0) { // filters if (s[i].getLB() + d[i].getLB() > min) { From 40403852ba50132e7071ce0e209e4b92a92288d0 Mon Sep 17 00:00:00 2001 From: cprudhom Date: Mon, 28 Nov 2022 11:36:26 +0100 Subject: [PATCH 2/3] Use resetQuick instead of clear in PropDiffN --- .../org/chocosolver/solver/constraints/nary/PropDiffN.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/solver/src/main/java/org/chocosolver/solver/constraints/nary/PropDiffN.java b/solver/src/main/java/org/chocosolver/solver/constraints/nary/PropDiffN.java index a4af171250..82ddf9d390 100644 --- a/solver/src/main/java/org/chocosolver/solver/constraints/nary/PropDiffN.java +++ b/solver/src/main/java/org/chocosolver/solver/constraints/nary/PropDiffN.java @@ -110,13 +110,13 @@ public void propagate(int evtmask) throws ContradictionException { } } } - pruneList.clear(); + pruneList.resetQuick(); for(int k = 0; k Date: Wed, 7 Dec 2022 11:38:57 +0100 Subject: [PATCH 3/3] Reduce objet creation for AbstractCriterionBasedVariableSelector --- ...bstractCriterionBasedVariableSelector.java | 60 ++++++++++--------- .../solver/variables/Variable.java | 8 +++ .../variables/impl/AbstractVariable.java | 25 +++++++- 3 files changed, 63 insertions(+), 30 deletions(-) diff --git a/solver/src/main/java/org/chocosolver/solver/search/strategy/selectors/variables/AbstractCriterionBasedVariableSelector.java b/solver/src/main/java/org/chocosolver/solver/search/strategy/selectors/variables/AbstractCriterionBasedVariableSelector.java index 454933587f..81555217bb 100644 --- a/solver/src/main/java/org/chocosolver/solver/search/strategy/selectors/variables/AbstractCriterionBasedVariableSelector.java +++ b/solver/src/main/java/org/chocosolver/solver/search/strategy/selectors/variables/AbstractCriterionBasedVariableSelector.java @@ -27,6 +27,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.function.BiConsumer; import java.util.function.BiFunction; import java.util.stream.Collectors; @@ -53,21 +54,6 @@ public Element(int count, int w0, int w1) { } } - private final BiFunction, double[], double[]> remapWeights = - (p, w) -> { - if (w == null) { - // if absent - w = new double[p.getNbVars()]; - } else if (w.length < p.getNbVars()) { - // may happen propagators (like PropSat) with dynamic variable addition - w = new double[p.getNbVars()]; - double[] nw = new double[p.getNbVars()]; - System.arraycopy(w, 0, nw, 0, w.length); - w = nw; - } - return w; - }; - protected static final int FLUSH_TOPS = 20; protected static final double FLUSH_RATIO = .9 * FLUSH_TOPS; protected int flushThs; @@ -118,6 +104,35 @@ public Element(int count, int w0, int w1) { final HashMap, double[]> refinedWeights = new HashMap<>(); static final double[] rw = {0.}; + private final BiFunction, double[], double[]> remapWeights = + (p, w) -> { + if (w == null) { + // if absent + w = new double[p.getNbVars()]; + } else if (w.length < p.getNbVars()) { + // may happen propagators (like PropSat) with dynamic variable addition + w = new double[p.getNbVars()]; + double[] nw = new double[p.getNbVars()]; + System.arraycopy(w, 0, nw, 0, w.length); + w = nw; + } + return w; + }; + + private final BiConsumer> updater = (v, p) -> { + Element elt = failCount.get(p); + if (elt != null) { + if (p.getVar(elt.ws[0]) == v) { + updateFutvars(p, elt, 0); + } else if (p.getVar(elt.ws[1]) == v) { + updateFutvars(p, elt, 1); + } + } + }; + + private final BiFunction incr = (v, c) -> c + 1; + private final BiFunction decr = (v, c) -> c - 1; + public AbstractCriterionBasedVariableSelector(V[] vars, long seed, int flush) { this.random = new java.util.Random(seed); this.solver = vars[0].getModel().getSolver(); @@ -264,13 +279,13 @@ final void plug(Variable var) { observed.put(var, 1); var.addMonitor(this); } else { - observed.computeIfPresent(var, (v, c) -> c + 1); + observed.computeIfPresent(var, incr); } } private void unplug(Variable var) { assert observed.containsKey(var); - Integer obs = observed.computeIfPresent(var, (v, c) -> c - 1); + Integer obs = observed.computeIfPresent(var, decr); if (obs != null && obs == 0) { var.removeMonitor(this); observed.remove(var); @@ -290,16 +305,7 @@ private int next(Propagator pro, int w0, int w1) { @Override public final void onUpdate(Variable var, IEventType evt) { if (var.isInstantiated()) { - var.streamPropagators().forEach(p -> { - Element elt = failCount.get(p); - if (elt != null) { - if (p.getVar(elt.ws[0]) == var) { - updateFutvars(p, elt, 0); - } else if (p.getVar(elt.ws[1]) == var) { - updateFutvars(p, elt, 1); - } - } - }); + var.forEachPropagator(updater); } } diff --git a/solver/src/main/java/org/chocosolver/solver/variables/Variable.java b/solver/src/main/java/org/chocosolver/solver/variables/Variable.java index a31446a538..02a26e8c17 100755 --- a/solver/src/main/java/org/chocosolver/solver/variables/Variable.java +++ b/solver/src/main/java/org/chocosolver/solver/variables/Variable.java @@ -21,6 +21,7 @@ import org.chocosolver.solver.variables.view.IView; import org.chocosolver.util.iterators.EvtScheduler; +import java.util.function.BiConsumer; import java.util.stream.Stream; /** @@ -137,6 +138,13 @@ public interface Variable extends Identity, Comparable { */ Stream> streamPropagators(); + /** + * Performs an action for each propagator of this variable. + * + * @param action action to perform on the elements + */ + void forEachPropagator(BiConsumer> action); + /** * Return the number of propagators * diff --git a/solver/src/main/java/org/chocosolver/solver/variables/impl/AbstractVariable.java b/solver/src/main/java/org/chocosolver/solver/variables/impl/AbstractVariable.java index 778204f209..ffcf62b17f 100644 --- a/solver/src/main/java/org/chocosolver/solver/variables/impl/AbstractVariable.java +++ b/solver/src/main/java/org/chocosolver/solver/variables/impl/AbstractVariable.java @@ -24,6 +24,7 @@ import java.util.Arrays; import java.util.Spliterator; +import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.stream.Stream; import java.util.stream.StreamSupport; @@ -237,6 +238,7 @@ public void swapOnPassivate(Propagator propagator, int idxInProp) { @Override public Stream> streamPropagators() { + //noinspection Convert2Diamond Spliterator> it = new Spliterator>() { int c = 0; @@ -278,6 +280,22 @@ public int characteristics() { return StreamSupport.stream(it, false); } + @Override + public void forEachPropagator(BiConsumer> action) { + int c = 0; + int i = propagators[c].first; + do { + if (i < propagators[c].last) { + action.accept(this, propagators[c].propagators[i++]); + } else { + c++; + if (c < propagators.length) { + i = propagators[c].first; + } + } + } while (c < propagators.length); + } + @Override public final int getNbProps() { return nbPropagators; @@ -541,9 +559,9 @@ public int add(Propagator propagator, int idxInVar) { /** * Remove the propagator p from {@link #propagators}. * - * @param propagator - * @param idxInProp - * @param var + * @param propagator the propagator to remove + * @param idxInProp the index of the variable in the propagator + * @param var the variable (for assertions only) */ public void remove(Propagator propagator, int idxInProp, final AbstractVariable var) { int p = propagator.getVIndice(idxInProp); @@ -640,6 +658,7 @@ Stream> stream() { shiftTail(); } } + //noinspection Convert2Diamond Spliterator> it = new Spliterator>() { int i = s; @Override