From 50a9038b368b1bbd3e0a9862931b308e5dbff983 Mon Sep 17 00:00:00 2001 From: Augustin Delecluse Date: Fri, 12 Apr 2024 13:53:58 +0200 Subject: [PATCH] XP for additional value selectors --- .../run_xp_jobshop_with_attribution_small.sh | 17 +++++++++++------ scripts/run_xp_qap_with_attribution.sh | 17 +++++++++++------ scripts/run_xp_tsp_with_attribution.sh | 17 +++++++++++------ scripts/run_xp_with_attribution.sh | 8 ++++++++ scripts/run_xp_xcsp_with_attribution.sh | 15 ++++++++++----- .../solver/search/strategy/SearchParams.java | 11 ++++++++++- .../selectors/values/IntDomainBestPruning.java | 16 ++++++++-------- .../selectors/values/IntDomainBestSubset.java | 5 ++--- 8 files changed, 71 insertions(+), 35 deletions(-) create mode 100755 scripts/run_xp_with_attribution.sh diff --git a/scripts/run_xp_jobshop_with_attribution_small.sh b/scripts/run_xp_jobshop_with_attribution_small.sh index e93ad4890..53bd56f58 100755 --- a/scripts/run_xp_jobshop_with_attribution_small.sh +++ b/scripts/run_xp_jobshop_with_attribution_small.sh @@ -8,12 +8,17 @@ commitId=$(git rev-parse HEAD) outFileOpt="results/jobshop/jobshop-opt-${commitId}-${currentDate}.csv" # filename of the results (with the date at the end of the file) #valSel,Best,freqBest,PhaseSaving -declare -a valueSelection=("GREEDY,None,1,false" -"MIN,None,1,false" -"MIN,Best,1,false" -"MIN,BestSubset,1,false" -"MIN,ReverseBest,1,false" -"MIN,ReverseBestSubset,1,false") # each value selection to try +#declare -a valueSelection=("GREEDY,None,1,false" +#"MIN,None,1,false" +#"MIN,Best,1,false" +#"MIN,BestSubset,1,false" +#"MIN,ReverseBest,1,false" +#"MIN,ReverseBestSubset,1,false") # each value selection to try +declare -a valueSelection=("MAX,None,1,false" +"MED,None,1,false" +"RAND,None,1,false" +"MIN,BestSubsetInf,1,false" +"MIN,BestInf,1,false") # each value selection to try timeout="00h30m00s" # timeout in seconds iter=1 # number of iterations to account for randomness diff --git a/scripts/run_xp_qap_with_attribution.sh b/scripts/run_xp_qap_with_attribution.sh index f80f15dba..09b2be824 100755 --- a/scripts/run_xp_qap_with_attribution.sh +++ b/scripts/run_xp_qap_with_attribution.sh @@ -8,12 +8,17 @@ commitId=$(git rev-parse HEAD) outFileOpt="results/qap/qap-opt-${commitId}-${currentDate}.csv" # filename of the results (with the date at the end of the file) #valSel,Best,freqBest,PhaseSaving -declare -a valueSelection=("GREEDY,None,1,false" -"MIN,None,1,false" -"MIN,Best,1,false" -"MIN,BestSubset,1,false" -"MIN,ReverseBest,1,false" -"MIN,ReverseBestSubset,1,false") # each value selection to try +#declare -a valueSelection=("GREEDY,None,1,false" +#"MIN,None,1,false" +#"MIN,Best,1,false" +#"MIN,BestSubset,1,false" +#"MIN,ReverseBest,1,false" +#"MIN,ReverseBestSubset,1,false") # each value selection to try +declare -a valueSelection=("MAX,None,1,false" +"MED,None,1,false" +"RAND,None,1,false" +"MIN,BestSubsetInf,1,false" +"MIN,BestInf,1,false") # each value selection to try timeout="00h30m00s" # timeout in seconds iter=1 # number of iterations to account for randomness diff --git a/scripts/run_xp_tsp_with_attribution.sh b/scripts/run_xp_tsp_with_attribution.sh index 0a694b13f..f2fa8f682 100755 --- a/scripts/run_xp_tsp_with_attribution.sh +++ b/scripts/run_xp_tsp_with_attribution.sh @@ -8,12 +8,17 @@ commitId=$(git rev-parse HEAD) outFileOpt="results/tsp/tsp-opt-${commitId}-${currentDate}.csv" # filename of the results (with the date at the end of the file) #valSel,Best,freqBest,PhaseSaving -declare -a valueSelection=("GREEDY,None,1,false" -"MIN,None,1,false" -"MIN,Best,1,false" -"MIN,BestSubset,1,false" -"MIN,ReverseBest,1,false" -"MIN,ReverseBestSubset,1,false") # each value selection to try +#declare -a valueSelection=("GREEDY,None,1,false" +#"MIN,None,1,false" +#"MIN,Best,1,false" +#"MIN,BestSubset,1,false" +#"MIN,ReverseBest,1,false" +#"MIN,ReverseBestSubset,1,false") # each value selection to try +declare -a valueSelection=("MAX,None,1,false" +"MED,None,1,false" +"RAND,None,1,false" +"MIN,BestSubsetInf,1,false" +"MIN,BestInf,1,false") # each value selection to try timeout="00h30m00s" # timeout in seconds iter=1 # number of iterations to account for randomness diff --git a/scripts/run_xp_with_attribution.sh b/scripts/run_xp_with_attribution.sh new file mode 100755 index 000000000..acb87efdd --- /dev/null +++ b/scripts/run_xp_with_attribution.sh @@ -0,0 +1,8 @@ +echo "running jobshop" +scripts/run_xp_jobshop_with_attribution_small.sh +echo "running qap" +scripts/run_xp_qap_with_attribution.sh +echo "running tsp" +scripts/run_xp_tsp_with_attribution.sh +echo "running xcsp" +scripts/run_xp_xcsp_with_attribution.sh diff --git a/scripts/run_xp_xcsp_with_attribution.sh b/scripts/run_xp_xcsp_with_attribution.sh index 0f5b715b3..34153d514 100755 --- a/scripts/run_xp_xcsp_with_attribution.sh +++ b/scripts/run_xp_xcsp_with_attribution.sh @@ -8,11 +8,16 @@ commitId=$(git rev-parse HEAD) outFileOpt="results/xcsp/xcsp-opt-${commitId}-${currentDate}.csv" # filename of the results (with the date at the end of the file) #valSel,Best,freqBest,PhaseSaving -declare -a valueSelection=("MIN,None,1,false" -"MIN,Best,1,false" -"MIN,BestSubset,1,false" -"MIN,ReverseBest,1,false" -"MIN,ReverseBestSubset,1,false") # each value selection to try +#declare -a valueSelection=("MIN,None,1,false" +#"MIN,Best,1,false" +#"MIN,BestSubset,1,false" +#"MIN,ReverseBest,1,false" +#"MIN,ReverseBestSubset,1,false") # each value selection to try +declare -a valueSelection=("MAX,None,1,false" +"MED,None,1,false" +"RAND,None,1,false" +"MIN,BestSubsetInf,1,false" +"MIN,BestInf,1,false") # each value selection to try timeout="00h30m00s" # timeout in seconds iter=1 # number of iterations to account for randomness diff --git a/solver/src/main/java/org/chocosolver/solver/search/strategy/SearchParams.java b/solver/src/main/java/org/chocosolver/solver/search/strategy/SearchParams.java index f15a52319..aa08594e8 100644 --- a/solver/src/main/java/org/chocosolver/solver/search/strategy/SearchParams.java +++ b/solver/src/main/java/org/chocosolver/solver/search/strategy/SearchParams.java @@ -12,6 +12,7 @@ import org.chocosolver.solver.Model; import org.chocosolver.solver.Solver; import org.chocosolver.solver.search.restart.*; +import org.chocosolver.solver.search.strategy.assignments.DecisionOperatorFactory; import org.chocosolver.solver.search.strategy.selectors.values.*; import org.chocosolver.solver.search.strategy.selectors.variables.*; import org.chocosolver.solver.search.strategy.strategy.AbstractStrategy; @@ -100,7 +101,9 @@ enum BestSelection { REVERSEBEST, REVERSEBESTSUBSET, REVERSEBESTMANUAL, - NONE + NONE, + BESTINF, + BESTSUBSETINF } /** @@ -420,6 +423,12 @@ public Function make() { case NONE: fn1 = fn0; break; + case BESTINF: + fn1 = m -> new IntDomainBest(Integer.MAX_VALUE, fn0.apply(m), v -> m.getSolver().getRestartCount() % bestFreq == 0, DecisionOperatorFactory.makeIntEq(), (k, v) -> false); + break; + case BESTSUBSETINF: + fn1 = m -> new IntDomainBestSubset(Integer.MAX_VALUE, fn0.apply(m), v -> m.getSolver().getRestartCount() % bestFreq == 0, DecisionOperatorFactory.makeIntEq(), (k, v) -> false, true); + break; } final Function fn2; if (last) { diff --git a/solver/src/main/java/org/chocosolver/solver/search/strategy/selectors/values/IntDomainBestPruning.java b/solver/src/main/java/org/chocosolver/solver/search/strategy/selectors/values/IntDomainBestPruning.java index ab3b08e9d..83b1010dc 100644 --- a/solver/src/main/java/org/chocosolver/solver/search/strategy/selectors/values/IntDomainBestPruning.java +++ b/solver/src/main/java/org/chocosolver/solver/search/strategy/selectors/values/IntDomainBestPruning.java @@ -17,6 +17,8 @@ import org.chocosolver.solver.search.strategy.assignments.DecisionOperatorFactory; import org.chocosolver.solver.variables.IntVar; +import java.util.ArrayList; +import java.util.List; import java.util.function.BiPredicate; import java.util.function.Function; @@ -44,8 +46,7 @@ public class IntDomainBestPruning implements IntValueSelector { private final Function trigger; protected boolean pruning; // TODO pruning activation seems to prevent the triggering of some constraints - protected final int[] invalidValuesRemoved; - protected int nInvalidValuesRemoved = 0; + protected final List invalidValuesRemoved; /** * Create a value selector that returns the best value wrt to the objective to optimize. @@ -75,7 +76,7 @@ public IntDomainBestPruning(int maxdom, IntValueSelector intValueSelector, Funct this.fallbackValueSelector = intValueSelector; this.trigger = trigger; this.pruning = pruning; - invalidValuesRemoved = new int[maxdom]; + invalidValuesRemoved = new ArrayList<>(); } /** @@ -160,7 +161,7 @@ public int selectValue(IntVar var) throws ContradictionException { return fallbackValueSelector.selectValue(var); } assert var.getModel().getObjective() != null; - nInvalidValuesRemoved = 0; + invalidValuesRemoved.clear(); int bestV; if (var.getModel().getResolutionPolicy() != ResolutionPolicy.SATISFACTION) { @@ -191,9 +192,8 @@ public int selectValue(IntVar var) throws ContradictionException { bestV = lbB < ubB ? var.getLB() : var.getUB(); } } - if (pruning && nInvalidValuesRemoved > 0) { - for (int i = 0 ; i < nInvalidValuesRemoved ; i++) { - int val = invalidValuesRemoved[i]; + if (pruning && !invalidValuesRemoved.isEmpty()) { + for (int val: invalidValuesRemoved) { dop.unapply(var, val, Cause.Null); } // the left branch will be x = v and the right branch x != v @@ -226,7 +226,7 @@ protected int bound(IntVar var, int val, boolean removeIfInvalid) throws Contrad if (pruning && !valid && removeIfInvalid) { // removes the value if the operation failed //dop.unapply(var, val, Cause.Null); - invalidValuesRemoved[nInvalidValuesRemoved++] = val; + invalidValuesRemoved.add(val); } return cost; } diff --git a/solver/src/main/java/org/chocosolver/solver/search/strategy/selectors/values/IntDomainBestSubset.java b/solver/src/main/java/org/chocosolver/solver/search/strategy/selectors/values/IntDomainBestSubset.java index 118ce23a2..edb13c3a2 100644 --- a/solver/src/main/java/org/chocosolver/solver/search/strategy/selectors/values/IntDomainBestSubset.java +++ b/solver/src/main/java/org/chocosolver/solver/search/strategy/selectors/values/IntDomainBestSubset.java @@ -68,7 +68,7 @@ public int selectValue(IntVar var) throws ContradictionException { if (objectiveReached) { value = super.selectValue(var); } else { - nInvalidValuesRemoved = 0; + invalidValuesRemoved.clear(); value = var.getLB(); // the objective will not change by modifying this variable } } catch (ContradictionException cex) { @@ -79,8 +79,7 @@ public int selectValue(IntVar var) throws ContradictionException { // reactivate the propagators model.getEnvironment().worldPop(); // removes the values that were detected as invalid - for (int idx = 0 ; idx < nInvalidValuesRemoved ; idx++) { - int val = invalidValuesRemoved[idx]; + for (int val: invalidValuesRemoved) { dop.unapply(var, val, Cause.Null); } if (var.getDomainSize() <= 2) {