001package org.cpsolver.ifs.assignment;
002
003import java.util.Collection;
004import java.util.HashMap;
005import java.util.LinkedHashMap;
006import java.util.Map;
007
008import org.cpsolver.ifs.assignment.context.AssignmentContextHolder;
009import org.cpsolver.ifs.assignment.context.AssignmentContextHolderMap;
010import org.cpsolver.ifs.model.Value;
011import org.cpsolver.ifs.model.Variable;
012
013
014/**
015 * An assignment using a {@link HashMap} to store values of all the variables of the model.
016 * This class is slower to store and retrieve a value than {@link AssignmentArray}, but 
017 * faster in retrieving a collection of assigned variables and values (methods 
018 * {@link Assignment#assignedVariables()} and {@link Assignment#assignedValues()}). 
019 * 
020 * @see Assignment
021 * 
022 * @author  Tomáš Müller
023 * @version IFS 1.3 (Iterative Forward Search)<br>
024 *          Copyright (C) 2014 Tomáš Müller<br>
025 *          <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
026 *          <a href="http://muller.unitime.org">http://muller.unitime.org</a><br>
027 * <br>
028 *          This library is free software; you can redistribute it and/or modify
029 *          it under the terms of the GNU Lesser General Public License as
030 *          published by the Free Software Foundation; either version 3 of the
031 *          License, or (at your option) any later version. <br>
032 * <br>
033 *          This library is distributed in the hope that it will be useful, but
034 *          WITHOUT ANY WARRANTY; without even the implied warranty of
035 *          MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
036 *          Lesser General Public License for more details. <br>
037 * <br>
038 *          You should have received a copy of the GNU Lesser General Public
039 *          License along with this library; if not see <a href='http://www.gnu.org/licenses'>http://www.gnu.org/licenses</a>.
040 * @param <V> Variable
041 * @param <T> Value
042 **/
043public class AssignmentMap<V extends Variable<V, T>, T extends Value<V, T>> extends AssignmentAbstract<V, T> {
044    private Map<V, T> iAssignments = new LinkedHashMap<V, T>();
045    private Map<V, Long> iIteration = new HashMap<V, Long>();
046    
047    /** Creates an empty assignment 
048     * @param contexts assignment context holder
049     **/
050    public AssignmentMap(AssignmentContextHolder<V, T> contexts) {
051        super(contexts);
052    }
053    
054    /** Creates an empty assignment */
055    public AssignmentMap() {
056        this(new AssignmentContextHolderMap<V, T>());
057    }
058    
059    /** Creates a copy of an existing assignment
060     * @param assignment current assignment
061     **/
062    public AssignmentMap(Assignment<V, T> assignment) {
063        super(new AssignmentContextHolderMap<V, T>());
064        for (T value: assignment.assignedValues())
065            iAssignments.put(value.variable(), value);
066    }
067
068    
069    @Override
070    public long getIteration(V variable) {
071        Long it = iIteration.get(variable);
072        return (it == null ? 0 : it);
073    }
074
075    @Override
076    public Collection<V> assignedVariables() {
077        return iAssignments.keySet();
078    }
079    
080    @Override
081    public Collection<T> assignedValues() {
082        return iAssignments.values();
083    }
084
085    @Override
086    public int nrAssignedVariables() {
087        return iAssignments.size();
088    }
089    
090    @Override
091    protected T getValueInternal(V variable) {
092        return iAssignments.get(variable);
093   }
094
095    @Override
096    protected void setValueInternal(long iteration, V variable, T value) {
097        if (value == null) {
098            iAssignments.remove(variable);
099            iIteration.remove(variable);
100        } else {
101            iAssignments.put(variable, value);
102            if (iteration > 0)
103                iIteration.put(variable, iteration);
104        }
105    }
106}