Skip to content

Commit

Permalink
Simple Search: max idle iterations during construction
Browse files Browse the repository at this point in the history
- when CBS is enabled, only stop the construction/IFS heuristic when all unassigned variables have been unassigned more times than the given max number of idle iterations
- when Search.MaxIdleIterations is set to zero, the construction/IFS heuristics gets switched off (HC and GD/SA are used from the start)
  • Loading branch information
tomas-muller committed Oct 18, 2024
1 parent 7bb8c8e commit db4b876
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 8 deletions.
11 changes: 8 additions & 3 deletions src/org/cpsolver/ifs/extension/ConflictStatistics.java
Original file line number Diff line number Diff line change
Expand Up @@ -333,16 +333,21 @@ public long countPotentialConflicts(Assignment<V, T> assignment, long iteration,
}
}

private int countAssignments(V variable) {
/**
* Count the number of past assignments of a variable
* @param variable
* @return total number of past assignments
*/
public long countAssignments(V variable) {
iLock.readLock().lock();
try {
List<AssignedValue<T>> assignments = iUnassignedVariables.get(variable);
if (assignments == null || assignments.isEmpty()) return 0;
int ret = 0;
double ret = 0;
for (AssignedValue<T> assignment: assignments) {
ret += assignment.getCounter(0);
}
return ret;
return Math.round(ret);
} finally {
iLock.readLock().unlock();
}
Expand Down
51 changes: 46 additions & 5 deletions src/org/cpsolver/ifs/heuristics/MaxIdleNeighbourSelection.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import org.cpsolver.ifs.assignment.Assignment;
import org.cpsolver.ifs.assignment.context.AssignmentContext;
import org.cpsolver.ifs.assignment.context.NeighbourSelectionWithContext;
import org.cpsolver.ifs.extension.ConflictStatistics;
import org.cpsolver.ifs.extension.Extension;
import org.cpsolver.ifs.model.Neighbour;
import org.cpsolver.ifs.model.Value;
import org.cpsolver.ifs.model.Variable;
Expand Down Expand Up @@ -49,6 +51,7 @@ public class MaxIdleNeighbourSelection<V extends Variable<V, T>, T extends Value
protected NeighbourSelection<V, T> iParent = null;
protected int iMaxIdle = 1000;
protected int iBestAssigned = 0;
protected ConflictStatistics<V, T> iStat = null;

public MaxIdleNeighbourSelection(DataProperties properties, NeighbourSelection<V, T> parent, int maxIdle) {
iParent = parent;
Expand All @@ -60,6 +63,9 @@ public void init(Solver<V, T> solver) {
super.init(solver);
iParent.init(solver);
solver.currentSolution().addSolutionListener(this);
for (Extension<V, T> ext: solver.getExtensions())
if (ext instanceof ConflictStatistics)
iStat = (ConflictStatistics<V, T>)ext;
}


Expand All @@ -77,12 +83,22 @@ public void getInfo(Solution<V, T> solution, Map<String, String> info, Collectio

@Override
public void bestCleared(Solution<V, T> solution) {
iBestAssigned = 0;
getContext(solution.getAssignment()).clear();
}

@Override
public void bestSaved(Solution<V, T> solution) {
if (solution.getAssignment().nrAssignedVariables() > iBestAssigned)
getContext(solution.getAssignment()).reset();
if (solution.getAssignment().nrAssignedVariables() > iBestAssigned) {
long max = 0;
if (iStat != null) {
for (V v: solution.getAssignment().unassignedVariables(solution.getModel())) {
long count = iStat.countAssignments(v);
if (count > max) max = count;
}
}
getContext(solution.getAssignment()).reset((int)max);
}
iBestAssigned = solution.getAssignment().nrAssignedVariables();
}

Expand All @@ -92,9 +108,21 @@ public void bestRestored(Solution<V, T> solution) {

@Override
public Neighbour<V, T> selectNeighbour(Solution<V, T> solution) {
if (iMaxIdle < 0) return iParent.selectNeighbour(solution);
if (iMaxIdle == 0) return null;
MaxIdleContext context = getContext(solution.getAssignment());
if (context.inc() >= iMaxIdle)
return null;
if (context.inc() >= iMaxIdle) {
if (iStat != null) {
Collection<V> unassigned = solution.getAssignment().unassignedVariables(solution.getModel());
for (V v: unassigned) {
if (iStat.countAssignments(v) < context.getLimit())
return iParent.selectNeighbour(solution);
}
return null;
} else {
return null;
}
}
return iParent.selectNeighbour(solution);
}

Expand All @@ -105,12 +133,25 @@ public MaxIdleContext createAssignmentContext(Assignment<V, T> assignment) {

public class MaxIdleContext implements AssignmentContext {
private int iCounter = 0;
private int iLimit = 0;

public MaxIdleContext(Assignment<V, T> assignment) {
}

public int getLimit() {
if (iLimit <= 0) iLimit = iMaxIdle;
return iLimit;
}

public int inc() { return iCounter++; }
public void reset() { iCounter = 0; }
public void reset(int max) {
iCounter = 0;
iLimit = max + iMaxIdle;
}
public void clear() {
iCounter = 0;
iLimit = iMaxIdle;
}

}
}

0 comments on commit db4b876

Please sign in to comment.