001 package net.sf.cpsolver.ifs.model;
002
003 import java.util.*;
004
005 import net.sf.cpsolver.ifs.util.*;
006
007 /**
008 * Generic value.
009 * <br><br>
010 * Every value has a notion about the variable it belongs to. It has also a unique id.
011 * By default, every Value has an integer value which is used in general heuristics,
012 * the task is than to minimimize the total value of assigned values in the solution.
013 *
014 * @see Variable
015 * @see Model
016 * @see net.sf.cpsolver.ifs.solver.Solver
017 *
018 * @version
019 * IFS 1.1 (Iterative Forward Search)<br>
020 * Copyright (C) 2006 Tomáš Müller<br>
021 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
022 * Lazenska 391, 76314 Zlin, Czech Republic<br>
023 * <br>
024 * This library is free software; you can redistribute it and/or
025 * modify it under the terms of the GNU Lesser General Public
026 * License as published by the Free Software Foundation; either
027 * version 2.1 of the License, or (at your option) any later version.
028 * <br><br>
029 * This library is distributed in the hope that it will be useful,
030 * but WITHOUT ANY WARRANTY; without even the implied warranty of
031 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
032 * Lesser General Public License for more details.
033 * <br><br>
034 * You should have received a copy of the GNU Lesser General Public
035 * License along with this library; if not, write to the Free Software
036 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
037 */
038 public class Value implements Comparable {
039 private static IdGenerator sIdGenerator = new IdGenerator();
040
041 private long iId;
042 private Variable iVariable = null;
043
044 private long iAssignmentCounter = 0;
045 private long iLastAssignmentIteration = -1;
046 private long iLastUnassignmentIteration = -1;
047
048 /** Integer value */
049 protected double iValue = 0;
050 /** Extra information which can be used by an IFS extension (see {@link net.sf.cpsolver.ifs.extension.Extension})*/
051 private Object iExtra = null;
052
053 /** Constructor
054 * @param variable variable which the value belongs to
055 */
056 public Value(Variable variable) {
057 iId = sIdGenerator.newId();
058 iVariable = variable;
059 }
060
061 /** Constructor
062 * @param variable variable which the value belongs to
063 * @param value integer value
064 */
065 public Value(Variable variable, double value) {
066 iId = sIdGenerator.newId();
067 iVariable = variable;
068 iValue = value;
069 }
070
071 /** Returns the variable which this value belongs to */
072 public Variable variable() { return iVariable; }
073 /** Sets the variable which this value belongs to */
074 public void setVariable(Variable variable) { iVariable = variable; }
075
076 /** Notification (called by variable) that this value is assigned
077 * @param iteration current iteration
078 */
079 public void assigned(long iteration) {
080 iAssignmentCounter++; iLastAssignmentIteration = iteration;
081 }
082
083 /** Notification (called by variable) that this value is unassigned
084 * @param iteration current iteration
085 */
086 public void unassigned(long iteration) { iLastUnassignmentIteration = iteration; }
087
088 /** Returns the iteration when the value was assigned at last (-1 if never).*/
089 public long lastAssignmentIteration() { return iLastAssignmentIteration; }
090 /** Returns the iteration when the value was unassigned at last (-1 if never).*/
091 public long lastUnassignmentIteration() { return iLastUnassignmentIteration; }
092 /** Returns the number of assignments of this value to its variable.*/
093 public long countAssignments() { return iAssignmentCounter; }
094
095 /** Unique id */
096 public long getId() { return iId;}
097
098 /** Values name -- for printing purposes (E.g., Monday 7:30)*/
099 public String getName() { return String.valueOf(iId); }
100
101 /** Values description -- for printing purposes*/
102 public String getDescription() { return null; }
103
104 /** Dobouble representaion. This allows us to have generic optimization criteria. The task
105 * is than to minimize total value of assigned variables of a solution.
106 */
107 public double toDouble() { return iValue; }
108
109 public String toString() { return getName(); }
110
111 public int hashCode() { return (int)iId; }
112
113 /** Comparison of two values which is based only on the value (not appropriate variable etc.). toDouble() is compared by default. */
114 public boolean valueEquals(Value value) {
115 if (value==null) return false;
116 return toDouble()==value.toDouble();
117 }
118
119 public int compareTo(Object o) {
120 if (o==null || !(o instanceof Value)) return -1;
121 int cmp = Double.compare(toDouble(),((Value)o).toDouble());
122 if (cmp!=0) return cmp;
123 return Double.compare(getId(),((Value)o).getId());
124 }
125
126 /** By default, comparison is made on unique ids */
127 public boolean equals(Object o) {
128 try {
129 if (o==null) return false;
130 return getId()==((Value)o).getId();
131 } catch (Exception e) { return false; }
132 }
133
134 /** Extra information to which can be used by an extension (see {@link net.sf.cpsolver.ifs.extension.Extension}). */
135 public Object getExtra() { return iExtra; }
136 /** Extra information to which can be used by an extension (see {@link net.sf.cpsolver.ifs.extension.Extension}). */
137 public void setExtra(Object object) { iExtra = object; }
138
139 /** True, if the value is consistent with the given value */
140 public boolean isConsistent(Value value) {
141 for (Enumeration e1=variable().constraints().elements();e1.hasMoreElements();) {
142 Constraint constraint = (Constraint)e1.nextElement();
143 if (!constraint.isConsistent(this, value))
144 return false;
145 }
146 for (Enumeration e1=variable().getModel().globalConstraints().elements();e1.hasMoreElements();) {
147 Constraint constraint = (Constraint)e1.nextElement();
148 if (!constraint.isConsistent(this, value))
149 return false;
150 }
151 return true;
152 }
153
154 /** Returns a set of conflicting values with this value. When empty, the value is consistent with the existing assignment. */
155 public java.util.Set conflicts() {
156 HashSet conflicts = new HashSet();
157 for (Enumeration e1=variable().constraints().elements();e1.hasMoreElements();) {
158 Constraint constraint = (Constraint)e1.nextElement();
159 constraint.computeConflicts(this, conflicts);
160 }
161 if (!conflicts.isEmpty()) return conflicts;
162 return null;
163 }
164 }