    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.InheritedAssignmentContextHolder;
    011import org.cpsolver.ifs.model.Value;
    012import org.cpsolver.ifs.model.Variable;
    013import org.cpsolver.ifs.solution.Solution;
    014
    015
    016/**
    017 * Optimistic inherited assignment. This assignment does not expect the parent assignment to change
    018 * much and it only remembers local changes made in this assignment. Use with caution.
    019 *
    020 * @see InheritedAssignment
    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 OptimisticInheritedAssignment<V extends Variable<V, T>, T extends Value<V, T>> extends AssignmentAbstract<V, T> implements InheritedAssignment<V, T> {
    044    private Assignment<V, T> iParent;
    045    private Map<V, T> iAssignments = new LinkedHashMap<V, T>();
    046    private Set<V> iDirty = new HashSet<V>();
    047    private Map<V, Long> iIteration = new HashMap<V, Long>();
    048    private long iVersion = -1;
    049
    050    public OptimisticInheritedAssignment(Solution<V, T> parent, int index) {
    051        // super(new InheritedAssignmentContextHolder<V, T>(index, parent.getIteration()), index, parent);
    052        super(new InheritedAssignmentContextHolder<V, T>(index, parent.getIteration()));
    053        iParent = parent.getAssignment();
    054        iVersion = parent.getIteration();
    055    }
    056
    057    @Override
    058    public long getIteration(V variable) {
    059        Long it = iIteration.get(variable);
    060        return (it != null ? it : iDirty.contains(variable) ? 0 : iParent.getIteration(variable));
    061    }
    062
    063    @Override
    064    public Collection<V> assignedVariables() {
    065        Set<V> variables = new HashSet<V>(iParent.assignedVariables());
    066        variables.removeAll(iDirty);
    067        variables.addAll(iAssignments.keySet());
    068        return variables;
    069    }
    070
    071    @Override
    072    public Collection<T> assignedValues() {
    073        Set<T> values = new HashSet<T>();
    074        for (T val: iParent.assignedValues()) {
    075            if (val != null && !iDirty.contains(val.variable()))
    076                values.add(val);
    077        }
    078        values.addAll(iAssignments.values());
    079        return values;
    080    }
    081
    082    @Override
    083    public int nrAssignedVariables() {
    084        return iAssignments.size() + iParent.nrAssignedVariables() - iDirty.size();
    085    }
    086
    087    @Override
    088    protected T getValueInternal(V variable) {
    089        T value = (iAssignments.isEmpty() ? null : iAssignments.get(variable));
    090        return (value != null ? value : iDirty.contains(variable) ? null : iParent.getValue(variable));
    091   }
    092
    093    @Override
    094    protected void setValueInternal(long iteration, V variable, T value) {
    095        if (value == null) {
    096            iAssignments.remove(variable);
    097            iIteration.remove(variable);
    098            if (iParent.getValue(variable) != null)
    099                iDirty.add(variable);
    100        } else {
    101            iAssignments.put(variable, value);
    102            if (iteration > 0)
    103                iIteration.put(variable, iteration);
    104            iDirty.remove(variable);
    105        }
    106    }
    107
    108    @Override
    109    public Assignment<V, T> getParentAssignment() {
    110        return iParent;
    111    }
    112
    113    @Override
    114    public long getVersion() {
    115        return iVersion;
    116    }
    117
    118    @Override
    119    public String toString() {
    120        String ret = "OptAssignment{";
    121        for (Map.Entry<V, T> e: iAssignments.entrySet()) {
    122            T v = iParent.getValue(e.getKey());
    123            if (!e.getValue().equals(v))
    124                ret += "\n  " + e.getKey() + " := " + e.getValue() +
    125                    "\n    -- original " + (v == null ? "not-assigned" : v);
    126        }
    127        for (V v: iDirty)
    128            ret += "\n  " + v + " := not-assigned" +
    129                    "\n    -- original " + iParent.getValue(v);
    130        return ret + "}";
    131    }
    132}