001    package ifs.model;
002    
003    import ifs.util.*;
004    import java.util.*;
005    
006    /**
007     * Generic value.
008     * <br><br>
009     * Every value has a notion about the variable it belongs to. It has also a unique id.
010     * By default, every Value has an integer value which is used in general heuristics,
011     * the task is than to minimimize the total value of assigned values in the solution.
012     *
013     * @see Variable
014     * @see Model
015     * @see ifs.solver.Solver
016     *
017     * @author <a href="mailto:muller@ktiml.mff.cuni.cz">Tomáš Müller</a>
018     * @version 1.0
019     */
020    public class Value implements Comparable {
021        private static org.apache.log4j.Logger sLogger = org.apache.log4j.Logger.getLogger(Value.class);
022        private static IdGenerator sIdGenerator = new IdGenerator();
023        
024        private long iId;
025        private Variable iVariable = null;
026        
027        private long iAssignmentCounter = 0;
028        private long iLastAssignmentIteration = -1;
029        private long iLastUnassignmentIteration = -1;
030        
031        /** Integer value */
032        protected int iValue = 0;
033        /** Extra information which can be used by an IFS extension (see {@link ifs.extension.Extension})*/
034        private Object iExtra = null;
035        
036        /** Constructor
037         * @param variable variable which the value belongs to
038         */
039        public Value(Variable variable) {
040            iId = sIdGenerator.newId();
041            iVariable = variable;
042        }
043    
044        /** Constructor
045         * @param variable variable which the value belongs to
046         * @param value integer value
047         */
048        public Value(Variable variable, int value) {
049            iId = sIdGenerator.newId();
050            iVariable = variable;
051            iValue = value;
052        }
053        
054        /** Returns the variable which this value belongs to */
055        public Variable variable() { return iVariable; }
056        /** Sets the variable which this value belongs to */
057        public void setVariable(Variable variable) { iVariable = variable; }
058        
059        /** Notification (called by variable) that this value is assigned
060         * @param iteration current iteration
061         */
062        public void assigned(long iteration) {
063            iAssignmentCounter++; iLastAssignmentIteration = iteration;
064        }
065        
066        /** Notification (called by variable) that this value is unassigned
067         * @param iteration current iteration
068         */
069        public void unassigned(long iteration) { iLastUnassignmentIteration = iteration; }
070        
071        /** Returns the iteration when the value was assigned at last (-1 if never).*/
072        public long lastAssignmentIteration() { return iLastAssignmentIteration; }
073        /** Returns the iteration when the value was unassigned at last (-1 if never).*/
074        public long lastUnassignmentIteration() { return iLastUnassignmentIteration; }
075        /** Returns the number of assignments of this value to its variable.*/
076        public long countAssignments() { return iAssignmentCounter; }
077        
078        /** Unique id */
079        public long getId() { return iId;}
080        
081        /** Values name -- for printing purposes (E.g., Monday 7:30)*/
082        public String getName() { return String.valueOf(iId); }
083        
084        /** Values description -- for printing purposes*/
085        public String getDescription() { return null; }
086        
087        /** Integer representaion. This allows us to have generic optimization criteria. The task
088         * is than to minimize total value of assigned variables of a solution.
089         */
090        public int toInt() { return iValue; }
091        
092        public String toString() { return getName(); }
093        
094        public int hashCode() { return (int)iId; }
095        
096        /** Comparison of two values which is based only on the value (not appropriate variable etc.). toInt() is compared by default. */
097        public boolean valueEquals(Value value) {
098            if (value==null) return false;
099            return toInt()==value.toInt();
100        }
101        
102        public int compareTo(Object o) {
103            if (o==null || !(o instanceof Value)) return -1;
104            return toInt() - ((Value)o).toInt();
105        }
106        
107        /** By default, comparison is made on unique ids */
108        public boolean equals(Object o) {
109            try {
110                return getId()==((Value)o).getId();
111            } catch (Exception e) { return false; }
112        }
113        
114        /** Extra information to which can be used by an extension (see {@link ifs.extension.Extension}). */
115        public Object getExtra() { return iExtra; }
116        /** Extra information to which can be used by an extension (see {@link ifs.extension.Extension}). */
117        public void setExtra(Object object) { iExtra = object; }
118    
119        /** Returns a set of conflicting values with this value. When empty, the value is consistent with the existing assignment. */
120        public java.util.Set conflicts() {
121            HashSet conflicts = new HashSet();
122            for (Enumeration e1=variable().constraints().elements();e1.hasMoreElements();) {
123                Constraint constraint = (Constraint)e1.nextElement();
124                constraint.computeConflicts(this, conflicts);
125                if (!conflicts.isEmpty()) return conflicts;
126            }
127            return null;
128        }
129    }