001 package ifs.extension;
002
003 import ifs.model.*;
004 import ifs.solver.*;
005 import ifs.util.*;
006
007 import java.util.*;
008
009 /**
010 * Computation of violated initial values (minimal perturbation problem).
011 * <br><br>
012 * It is using {@link Constraint#isConsistent(Value, Value)} to find out what
013 * initial values (of different variables) cannot be assigned when an arbitrary value is
014 * assigned to a variable. This information is computed in advance, before the solver is
015 * executed. It is used for better estimation of perturbation penalty (see
016 * {@link ifs.perturbations.PerturbationsCounter}) when a value is to be assigned to a variable.
017 *
018 * @author <a href="mailto:muller@ktiml.mff.cuni.cz">Tomáš Müller</a>
019 * @version 1.0
020 */
021 public class ViolatedInitials extends Extension {
022 private static org.apache.log4j.Logger sLogger = org.apache.log4j.Logger.getLogger(ViolatedInitials.class);
023 private Hashtable iViolatedInitials = new Hashtable();
024
025 public ViolatedInitials(Solver solver, DataProperties properties) {
026 super(solver, properties);
027 }
028
029 /** Compute the violations between any value and all other initial values */
030 public boolean init() {
031 sLogger.info("Computation of violated initials enabled.");
032 for (Enumeration i = getModel().variables().elements(); i.hasMoreElements();) {
033 Variable variable = (Variable)i.nextElement();
034 if (variable.getInitialAssignment() == null) continue;
035 for (Enumeration i1 = variable.constraints().elements(); i1.hasMoreElements();) {
036 Constraint constraint = (Constraint)i1.nextElement();
037 Vector conflicts = conflictValues(constraint, variable.getInitialAssignment());
038 for (Enumeration i2 = conflicts.elements(); i2.hasMoreElements(); ) {
039 Value value = (Value)i2.nextElement();
040 addViolatedInitial(value, variable.getInitialAssignment());
041 }
042 }
043 }
044 return true;
045 }
046
047 /** Initial values that cannot be assigned when the given value is assigned */
048 public Set getViolatedInitials(Value value) {
049 return (Set)iViolatedInitials.get(value);
050 }
051
052 private void addViolatedInitial(Value value, Value anotherValue) {
053 Set violations = (Set)iViolatedInitials.get(value);
054 if (violations == null) {
055 violations = new HashSet();
056 iViolatedInitials.put(value, violations);
057 }
058 violations.add(anotherValue);
059 }
060
061 private Vector conflictValues(Constraint constraint, Value aValue) {
062 Vector ret = new FastVector();
063 for (Enumeration i1 = constraint.variables().elements();i1.hasMoreElements();) {
064 Variable variable = (Variable)i1.nextElement();
065 if (variable.equals(aValue.variable())) continue;
066 if (variable.getAssignment() != null) continue;
067 for (Enumeration i2 = variable.values().elements(); i2.hasMoreElements(); ) {
068 Value value = (Value)i2.nextElement();
069 if (!constraint.isConsistent(aValue, value))
070 ret.addElement(value);
071 }
072 }
073 return ret;
074 }
075 }