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

Simplification of objective manager #949

Merged
merged 3 commits into from
Oct 25, 2022
Merged
Show file tree
Hide file tree
Changes from 2 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 @@ -354,6 +354,7 @@ public List<Model> getModels() {
* @return a list that contained the found solutions.
*/
public Stream<Solution> streamSolutions() {
//noinspection Convert2Diamond
Spliterator<Solution> it = new Spliterator<Solution>() {

@Override
Expand Down Expand Up @@ -388,7 +389,6 @@ public int characteristics() {
/////////////////////////////////////// INTERNAL METHODS //////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

@SuppressWarnings("unchecked")
public void prepare() {
isPrepared = true;
check();
Expand Down Expand Up @@ -417,11 +417,7 @@ private synchronized void updateFromSolution(Model m) {
if (solverVal == bestVal) {
getSolutionFound().set(true);
finder = m;
if (m.getResolutionPolicy() == ResolutionPolicy.MAXIMIZE) {
models.forEach(s1 -> s1.getSolver().getObjectiveManager().updateBestLB(bestVal));
} else {
models.forEach(s1 -> s1.getSolver().getObjectiveManager().updateBestUB(bestVal));
}
models.forEach(s1 -> s1.getSolver().getObjectiveManager().updateBestSolution(bestVal));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,58 +16,142 @@
import org.chocosolver.solver.variables.IntVar;
import org.chocosolver.util.objects.setDataStructures.iterable.IntIterableRangeSet;

import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.IntUnaryOperator;

/**
* @author Jean-Guillaume Fages, Charles Prud'homme, Arnaud Malapert
*
*/
abstract class AbstractIntObjManager extends AbstractObjManager<IntVar> {
public abstract class AbstractIntObjManager implements IObjectiveManager<IntVar> {

private static final long serialVersionUID = 5539060355541720114L;

public AbstractIntObjManager(AbstractIntObjManager objman) {
super(objman);
}
/**
* The variable to optimize
**/
transient protected final IntVar objective;

/**
* Define how should the objective be optimize
*/
protected final ResolutionPolicy policy;

/**
* define the precision to consider a variable as instantiated
**/
protected final int precision;

public AbstractIntObjManager(IntVar objective, ResolutionPolicy policy, Number precision) {
super(objective, policy, precision);
/**
* best lower bound found so far
**/
protected int bestProvedLB;

/**
* best upper bound found so far
**/
protected int bestProvedUB;

/**
* Define how the cut should be updated when posting the cut
**/
transient protected IntUnaryOperator cutComputer = n -> n; // walking cut by default

public AbstractIntObjManager(AbstractIntObjManager objman) {
objective = objman.objective;
policy = objman.policy;
precision = objman.precision;
bestProvedLB = objman.bestProvedLB;
bestProvedUB = objman.bestProvedUB;
cutComputer = objman.cutComputer;
}

public AbstractIntObjManager(IntVar objective, ResolutionPolicy policy, int precision) {
assert Objects.nonNull(objective);
this.objective = objective;
assert Objects.nonNull(policy);
this.policy = policy;
this.precision = precision;
bestProvedLB = objective.getLB() - 1;
bestProvedUB = objective.getUB() + 1;
}


@Override
public final IntVar getObjective() {
return objective;
}

@Override
public final ResolutionPolicy getPolicy() {
return policy;
}

@Override
public final Number getBestLB() {
return bestProvedLB;
}

@Override
public final Number getBestUB() {
return bestProvedUB;
}

@Override
public final void setCutComputer(Function<Number, Number> cutComputer) {
this.cutComputer = operand -> cutComputer.apply(operand).intValue();
}

public final void setCutComputer(IntUnaryOperator cutComputer) {
this.cutComputer = cutComputer;
}

@Override
public void setStrictDynamicCut() {
cutComputer = n -> n + precision;
}

@Override
public synchronized boolean updateBestLB(Number lb) {
if (bestProvedLB.intValue() < lb.intValue()) {
public final void setWalkingDynamicCut() {
cutComputer = n -> n;
}

public synchronized boolean updateBestLB(int lb) {
if (bestProvedLB < lb) {
bestProvedLB = lb;
return true;
}
return false;
}

@Override
public synchronized boolean updateBestUB(Number ub) {
if (bestProvedUB.intValue() > ub.intValue()) {
public synchronized boolean updateBestUB(int ub) {
if (bestProvedUB > ub) {
bestProvedUB = ub;
return true;
}
return false;
}

@Override
public boolean updateBestSolution(Number n) {
return updateBestSolution(n.intValue());
}

/**
* Informs the manager that a new solution has been found
*/
public abstract boolean updateBestSolution(int n);

@Override
public boolean updateBestSolution() {
if(!objective.isInstantiated()) {
if (!objective.isInstantiated()) {
throw new SolverException(
"objective variable (" + objective + ") is not instantiated on solution. Check constraints and/or decision variables.");
"objective variable (" + objective + ") is not instantiated on solution. Check constraints and/or decision variables.");
}
return updateBestSolution(objective.getValue());
}

@Override
public void setStrictDynamicCut() {
cutComputer = (Number n) -> n.intValue() + precision.intValue();
}

@Override
public void resetBestBounds() {
bestProvedLB = objective.getLB() - 1;
Expand Down Expand Up @@ -99,13 +183,13 @@ public MinIntObjManager(IntVar objective) {
}

@Override
public boolean updateBestSolution(Number n) {
public boolean updateBestSolution(int n) {
return updateBestUB(n);
}

@Override
public void postDynamicCut() throws ContradictionException {
objective.updateBounds(bestProvedLB.intValue(), cutComputer.apply(bestProvedUB).intValue(), this);
objective.updateBounds(bestProvedLB, cutComputer.applyAsInt(bestProvedUB), this);
}

@Override
Expand All @@ -115,7 +199,7 @@ public Number getBestSolutionValue() {

@Override
public void explain(int p, ExplanationForSignedClause explanation) {
objective.intersectLit(IntIterableRangeSet.MIN, bestProvedUB.intValue() - 1, explanation);
objective.intersectLit(IntIterableRangeSet.MIN, bestProvedUB - 1, explanation);
}

}
Expand All @@ -134,13 +218,13 @@ public MaxIntObjManager(IntVar objective) {
}

@Override
public boolean updateBestSolution(Number n) {
public boolean updateBestSolution(int n) {
return updateBestLB(n);
}

@Override
public void postDynamicCut() throws ContradictionException {
objective.updateBounds(cutComputer.apply(bestProvedLB).intValue(), bestProvedUB.intValue(), this);
objective.updateBounds(cutComputer.applyAsInt(bestProvedLB), bestProvedUB, this);
}

@Override
Expand All @@ -150,6 +234,6 @@ public Number getBestSolutionValue() {

@Override
public void explain(int p, ExplanationForSignedClause explanation) {
objective.intersectLit(bestProvedLB.intValue() + 1, IntIterableRangeSet.MAX, explanation);
objective.intersectLit(bestProvedLB + 1, IntIterableRangeSet.MAX, explanation);
}
}

This file was deleted.

Loading