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