    001package org.cpsolver.ifs.model;
    002
    003import java.util.HashMap;
    004import java.util.Map;
    005import java.util.Set;
    006
    007import org.cpsolver.ifs.assignment.Assignment;
    008
    009
    010/**
    011 * A neighbour consisting of a change (either assignment or unassignment) of a
    012 * single variable.
    013 *
    014 * @see org.cpsolver.ifs.heuristics.NeighbourSelection
    015 *
    016 * @version IFS 1.3 (Iterative Forward Search)<br>
    017 *          Copyright (C) 2006 - 2014 Tomáš Müller<br>
    018 *          <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
    019 *          <a href="http://muller.unitime.org">http://muller.unitime.org</a><br>
    020 * <br>
    021 *          This library is free software; you can redistribute it and/or modify
    022 *          it under the terms of the GNU Lesser General Public License as
    023 *          published by the Free Software Foundation; either version 3 of the
    024 *          License, or (at your option) any later version. <br>
    025 * <br>
    026 *          This library is distributed in the hope that it will be useful, but
    027 *          WITHOUT ANY WARRANTY; without even the implied warranty of
    028 *          MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    029 *          Lesser General Public License for more details. <br>
    030 * <br>
    031 *          You should have received a copy of the GNU Lesser General Public
    032 *          License along with this library; if not see
    033 *          <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>.
    034 *
    035 * @param <V> Variable
    036 * @param <T> Value
    037 */
    038public class SimpleNeighbour<V extends Variable<V, T>, T extends Value<V, T>> implements Neighbour<V, T> {
    039    private V iVariable = null;
    040    private T iValue = null;
    041    private Set<T> iConflicts = null;
    042
    043    /**
    044     * Model
    045     *
    046     * @param variable
    047     *            variable to be assigned
    048     * @param value
    049     *            value to be assigned to the given variable, null if the
    050     *            variable should be unassigned
    051     */
    052    public SimpleNeighbour(V variable, T value) {
    053        iVariable = variable;
    054        iValue = value;
    055    }
    056
    057    public SimpleNeighbour(V variable, T value, Set<T> conflicts) {
    058        iVariable = variable;
    059        iValue = value;
    060        iConflicts = conflicts;
    061    }
    062
    063    /** Selected variable
    064     * @return a variable
    065     **/
    066    public V getVariable() {
    067        return iVariable;
    068    }
    069
    070    /** Selected value
    071     * @return a value, null if the variable is to be unassigned
    072     **/
    073    public T getValue() {
    074        return iValue;
    075    }
    076
    077    /** Perform assignment */
    078    @Override
    079    public void assign(Assignment<V, T> assignment, long iteration) {
    080        if (iVariable == null)
    081            return;
    082        if (iValue != null)
    083            assignment.assign(iteration, iValue);
    084        else
    085            assignment.unassign(iteration, iVariable);
    086    }
    087
    088    /** Improvement in the solution value if this neighbour is accepted. */
    089    @Override
    090    public double value(Assignment<V, T> assignment) {
    091        T old = assignment.getValue(iVariable);
    092        return (iValue == null ? 0 : iValue.toDouble(assignment)) - (iVariable == null || old == null ? 0 : old.toDouble(assignment));
    093    }
    094
    095    @Override
    096    public String toString() {
    097        return iVariable.getName() + " := " + (iValue == null ? "null" : iValue.getName());
    098    }
    099
    100    @Override
    101    public Map<V, T> assignments() {
    102        HashMap<V, T> ret = new HashMap<V, T>();
    103        if (iVariable != null)
    104            ret.put(iVariable, iValue);
    105        if (iConflicts != null)
    106            for (T conflict: iConflicts)
    107                ret.put(conflict.variable(), null);
    108        return ret;
    109    }
    110}