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 }