    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    }