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}