001    package net.sf.cpsolver.ifs.multi;
002    
003    import net.sf.cpsolver.ifs.model.Value;
004    import net.sf.cpsolver.ifs.util.ToolBox;
005    
006    /**
007     * A value of {@link MultiVariable}. Such value contains a value for every "normal" variable of {@link MultiVariable}. 
008     *
009     * @version
010     * IFS 1.1 (Iterative Forward Search)<br>
011     * Copyright (C) 2006 Tomáš Müller<br>
012     * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
013     * Lazenska 391, 76314 Zlin, Czech Republic<br>
014     * <br>
015     * This library is free software; you can redistribute it and/or
016     * modify it under the terms of the GNU Lesser General Public
017     * License as published by the Free Software Foundation; either
018     * version 2.1 of the License, or (at your option) any later version.
019     * <br><br>
020     * This library is distributed in the hope that it will be useful,
021     * but WITHOUT ANY WARRANTY; without even the implied warranty of
022     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
023     * Lesser General Public License for more details.
024     * <br><br>
025     * You should have received a copy of the GNU Lesser General Public
026     * License along with this library; if not, write to the Free Software
027     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
028     *  
029     */
030    
031    public class MultiValue extends Value {
032            private Value[] iValues = null;
033            private Double iDoubleValue = null;
034            private int iHashCode = 0;
035            
036            /** Constructor
037             * @param variable multi variable
038             * @param values a value for every "normal" variable of the multi variable
039             */
040            public MultiValue(MultiVariable variable, Value[] values) {
041                    this(variable, values, null, false);
042            }
043            
044            /** Constructor
045             * @param variable multi variable
046             * @param values a value for every "normal" variable of the multi variable
047             * @param doubleValue valute to be returned as {@link MultiValue#toDouble()}
048             * @param correctOrder indicates whether the givan values are in the correct order (first value of the first variable etc.)
049             */
050            public MultiValue(MultiVariable variable, Value[] values, Double doubleValue, boolean correctOrder) {
051                    super(variable);
052                    iValues = new Value[values.length];
053                    for (int i=0;i<values.length;i++) {
054                            iValues[i] = values[i];
055                            if (values[i]!=null) values[i].setExtra(this);
056                    }
057                    iDoubleValue = doubleValue;
058                    if (correctOrder) {
059                            for (int i=0;i<iValues.length;i++) {
060                                    Value val = iValues[i];
061                                    int idx = variable.variables().indexOf(val.variable());
062                                    if (i!=idx) {
063                                            iValues[i]=iValues[idx]; iValues[idx]=val;
064                                    }
065                            }
066                    }
067                    iHashCode = getName().hashCode();
068            }
069            
070            public Value[] values() { return iValues; }
071            public int size() { return iValues.length; }
072            public int nrAssigned() {
073                    int ret = 0;
074                    for (int i=0;i<iValues.length;i++)
075                            if (iValues[i]!=null) ret++;
076                    return ret;
077            }
078            
079            public String getName() {
080                    StringBuffer sb = new StringBuffer("[");
081                    for (int i=0;i<iValues.length;i++) {
082                            if (i>0) sb.append(",");
083                            sb.append(iValues[i]==null?"null":iValues[i].getName());
084                    }
085                    sb.append("]");
086                    return sb.toString();
087            }
088            
089            public String toString() {
090                    return getName();
091            }
092            
093            public double toDouble() {
094                    if (iDoubleValue!=null) return iDoubleValue.intValue();
095                    int ret = 0;
096                    for (int i=0;i<iValues.length;i++) {
097                            ret += (iValues[i]==null?0:iValues[i].toDouble());
098                    }
099                    return ret;
100            }
101            
102            public int hashCode() {
103                    return iHashCode;
104            }
105    
106            public boolean equals(Object o) {
107                    if (o==null || !(o instanceof MultiValue)) return false;
108                    MultiValue m = (MultiValue)o;
109                    if (!m.variable().equals(variable())) return false;
110                    for (int i=0;i<iValues.length;i++)
111                            if (!ToolBox.equals(iValues[i],m.values()[i])) return false;
112                    return true;
113            }
114            
115            public Object clone() {
116                    return new MultiValue((MultiVariable)variable(), iValues, iDoubleValue, false);
117            }
118    }