Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add frequency + fallback value selector #1057

Merged
merged 7 commits into from
Aug 23, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.chocosolver.solver.variables.IntVar;

import java.util.function.BiPredicate;
import java.util.function.Function;

/**
* Value selector for optimization problems:
Expand All @@ -43,6 +44,10 @@ public final class IntDomainBest implements IntValueSelector {
*/
private final BiPredicate<IntVar, Integer> condition;

private final IntValueSelector fallbackValueSelector;

private final Function<IntVar, Boolean> trigger;

/**
* Create a value selector that returns the best value wrt to the objective to optimize.
* When an enumerated variable domain exceeds {@link #maxdom}, only bounds are considered.
Expand All @@ -54,14 +59,40 @@ public final class IntDomainBest implements IntValueSelector {
* is kept.
* </p>
*
* @param maxdom a maximum domain size to satisfy to use this value selector.
* @param dop the decision operator used to make the decision
* @param condition predicate to break ties
* @param maxdom a maximum domain size to satisfy to use this value selector
* @param intValueSelector fallback value selector
* @param trigger the function that indicates when the best value selector is applied.
* When it returns true, the best value selector is applied.
* Otherwise, the fallback value selector is applied.
* @param dop the decision operator used to make the decision
* @param condition predicate to break ties
*/
public IntDomainBest(int maxdom, DecisionOperator<IntVar> dop, BiPredicate<IntVar, Integer> condition) {
public IntDomainBest(int maxdom, IntValueSelector intValueSelector, Function<IntVar, Boolean> trigger, DecisionOperator<IntVar> dop, BiPredicate<IntVar, Integer> condition) {
this.maxdom = maxdom;
this.dop = dop;
this.condition = condition;
this.fallbackValueSelector = intValueSelector;
this.trigger = trigger;
}

/**
* Create a value selector that returns the best value wrt to the objective to optimize.
* When an enumerated variable domain exceeds {@link #maxdom}, only bounds are considered.
*
* <p>
* {@code condition} is called when the evaluated {@code value} returns a score
* equals to the current best one. In that case, if {@code condition} returns {@code true}
* then {@code value} is retained as the new best candidate, otherwise the previous one
* is kept.
* </p>
*
* @param intValueSelector fallback value selector
* @param trigger the function that indicates when the best value selector is applied.
* When it returns true, the best value selector is applied.
* Otherwise, the fallback value selector is applied.
*/
public IntDomainBest(IntValueSelector intValueSelector, Function<IntVar, Boolean> trigger) {
this(100, intValueSelector, trigger, DecisionOperatorFactory.makeIntEq(), (k, v) -> false);
}

/**
Expand All @@ -76,26 +107,51 @@ public IntDomainBest(int maxdom, DecisionOperator<IntVar> dop, BiPredicate<IntVa
* </p>
*
* @param condition predicate to break ties
* @apiNote The default values are:
* <ul>
* <li>maxdom is set to 100</li>
* <li>the trigger is set to restart count % 16 == 0</li>
* <li>the decision operator is set to '='</li>
* </ul>
*/
public IntDomainBest(BiPredicate<IntVar, Integer> condition) {
this(100, DecisionOperatorFactory.makeIntEq(), condition);
this(100,
new IntDomainMin(),
v -> true,
DecisionOperatorFactory.makeIntEq(),
condition);
}


/**
* Create a value selector for assignments that returns the best value wrt to the objective to
* optimize. When an enumerated variable domain exceeds 100, only bounds are considered.
* Always-false condition is set by default.
*
* @apiNote The default values are:
* <ul>
* <li>maxdom is set to 100</li>
* <li>the trigger is set to restart count % 16 == 0</li>
* <li>the decision operator is set to '='</li>
* <li>the predicate to break ties is lexico</li>
* </ul>
*/
public IntDomainBest() {
this(100, DecisionOperatorFactory.makeIntEq(), (k, v) -> false);
this(100,
new IntDomainMin(),
v -> true,
DecisionOperatorFactory.makeIntEq(),
(k, v) -> false);
}

/**
* {@inheritDoc}
*/
@Override
public int selectValue(IntVar var) {
if (!trigger.apply(var)) {
return fallbackValueSelector.selectValue(var);
}
assert var.getModel().getObjective() != null;
if (var.hasEnumeratedDomain() && var.getDomainSize() < maxdom) {
int bestCost = Integer.MAX_VALUE;
Expand Down
Loading