/**
*
*/
package vroom.common.heuristics;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import vroom.common.utilities.optimization.IConstraint;
import vroom.common.utilities.optimization.IMove;
/**
* <code>ConstraintHandler</code> is a utility class for the handling of a set of constraints.
* <p>
* It implements {@link IConstraint} in order to be transparently used as a simple constraint.
* <p>
* Creation date: Jun 22, 2010 - 9:08:40 AM
*
* @author Victor Pillac, <a href="http://uniandes.edu.co">Universidad de Los Andes</a>-<a
* href="http://copa.uniandes.edu.co">Copa</a> <a href="http://www.emn.fr">Ecole des Mines de Nantes</a>-<a
* href="http://www.irccyn.ec-nantes.fr/irccyn/d/en/equipes/Slp">SLP</a>
* @version 1.0
*/
public class ConstraintHandler<S> implements IConstraint<S>, Iterable<IConstraint<S>> {
private final List<IConstraint<S>> mConstraints;
/**
* Creates a new <code>ConstraintHandler</code> with an initial set of constraints
* <p>
* Please note that constraints will be checked in the same order they were added
* </p>
*
* @param constraints
* the constraints to be added to the new handler
*/
public ConstraintHandler(IConstraint<S>... constraints) {
mConstraints = new ArrayList<IConstraint<S>>(constraints.length);
for (IConstraint<S> c : constraints)
mConstraints.add(c);
}
/**
* Creates a new <code>ConstraintHandler</code>
*/
public ConstraintHandler() {
mConstraints = new ArrayList<IConstraint<S>>();
}
/**
* Returns the number of constraints registered in this handler
*
* @return the number of constraints registered in this handler
*/
public int size() {
return mConstraints.size();
}
/**
* Add a constraint to this handler.
* <p>
* Please note that constraints will be checked in the same order they were added
* </p>
*
* @param constraint
* the constraint to be added
* @return <code>true</code> if the constraint was not already registered
*/
public boolean addConstraint(IConstraint<S> constraint) {
return mConstraints.add(constraint);
}
/**
* Add a constraint to this handler.
* <p>
* Please note that constraints will be checked in the same order they were added
* </p>
*
* @param idx
* the index at which the constraint should be added
* @param constraint
* the constraint to be added
* @return <code>true</code> if the constraint was not already registered
* @see List#add(int, Object)
*/
public void addConstraint(int idx, IConstraint<S> constraint) {
mConstraints.add(idx, constraint);
}
/**
* Remove a constraint from this handler.
* <p>
* Please note that if a constraint was added more than once only the first occurrence will be removed
* </p>
*
* @param constraint
* the constraint to be removed
* @return <code>true</code> if the constraint was registered
*/
public boolean removeConstraint(IConstraint<S> constraint) {
return mConstraints.remove(constraint);
}
/*
* (non-Javadoc)
*
* @see
* vroom.common.heuristics.IConstraint#checkIMove(vroom.common.heuristics
* .ISolution, vroom.common.heuristics.IMove)
*/
@Override
public boolean isFeasible(S solution, IMove move) {
for (IConstraint<S> c : this) {
if (!c.isFeasible(solution, move)) {
return false;
}
}
return true;
}
/*
* (non-Javadoc)
*
* @see
* vroom.common.heuristics.IConstraint#checkSolution(vroom.common.heuristics
* .ISolution)
*/
@Override
public boolean isFeasible(S solution) {
for (IConstraint<S> c : this) {
if (!c.isFeasible(solution)) {
return false;
}
}
return true;
}
/**
* Check the violated constraints
*
* @param mSolution
* the mSolution to be checked
* @return a collection containing the violated constraints
*/
public Collection<IConstraint<S>> getViolatedConstraints(S solution) {
LinkedList<IConstraint<S>> ctr = new LinkedList<IConstraint<S>>();
for (IConstraint<S> c : mConstraints) {
if (!c.isFeasible(solution)) {
ctr.add(c);
}
}
return ctr;
}
/*
* (non-Javadoc)
*
* @see
* vroom.common.heuristics.IConstraint#getInfeasibilityExplanation(java.
* lang.Object)
*/
@Override
public String getInfeasibilityExplanation(S solution) {
StringBuilder sb = new StringBuilder();
for (IConstraint<S> c : mConstraints) {
String infeas = c.getInfeasibilityExplanation(solution);
if (infeas != null) {
if (sb.length() > 0) {
sb.append(", ");
}
sb.append('[');
sb.append(infeas);
sb.append(']');
}
}
return sb.length() > 0 ? sb.toString() : null;
}
/*
* (non-Javadoc)
*
* @see
* vroom.common.heuristics.IConstraint#getInfeasibilityExplanation(java.
* lang.Object, vroom.common.heuristics.IMove)
*/
@Override
public String getInfeasibilityExplanation(S solution, IMove move) {
StringBuilder sb = new StringBuilder();
for (IConstraint<S> c : mConstraints) {
String infeas = c.getInfeasibilityExplanation(solution, move);
if (infeas != null) {
if (sb.length() > 0) {
sb.append(", ");
}
sb.append('[');
sb.append(infeas);
sb.append(']');
}
}
return sb.length() > 0 ? sb.toString() : null;
}
@Override
public ListIterator<IConstraint<S>> iterator() {
return mConstraints.listIterator();
}
@Override
public String toString() {
StringBuilder s = new StringBuilder();
s.append("[");
for (IConstraint<S> c : mConstraints) {
if (s.length() > 1)
s.append(",");
s.append(c.getClass().getSimpleName());
}
s.append("]");
return s.toString();
}
}