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 }