001package org.cpsolver.ifs.model;
002
003import java.util.HashMap;
004import java.util.Map;
005
006import org.cpsolver.ifs.assignment.Assignment;
007
008
009/**
010 * Lazy swap of two variables. See {@link LazyNeighbour}.
011 *  
012 * @version IFS 1.3 (Iterative Forward Search)<br>
013 * Copyright (C) 2013 - 2014 Tomáš Müller<br>
014 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
015 * <a href="http://muller.unitime.org">http://muller.unitime.org</a><br>
016 * <br>
017 * This library is free software; you can redistribute it and/or
018 * modify it under the terms of the GNU Lesser General Public
019 * License as published by the Free Software Foundation; either
020 * version 3 of the License, or (at your option) any later version.
021 * <br><br>
022 * This library is distributed in the hope that it will be useful,
023 * but WITHOUT ANY WARRANTY; without even the implied warranty of
024 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
025 * Lesser General Public License for more details.
026 * <br><br>
027 * You should have received a copy of the GNU Lesser General Public
028 * License along with this library; if not see
029 * <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>.
030 * 
031 * @param <V> Variable 
032 * @param <T> Value
033 */
034public class LazySwap<V extends Variable<V, T>, T extends Value<V, T>> extends LazyNeighbour<V, T> {
035    private T iV1, iV2, iOldV1 = null, iOldV2 = null; 
036    
037    /**
038     * Constructor
039     * @param v1 first variable
040     * @param v2 second variable
041     */
042    public LazySwap(T v1, T v2) {
043        iV1 = v1;
044        iV2 = v2;
045    }
046    
047    /** Perform swap */
048    @Override
049    protected void doAssign(Assignment<V, T> assignment, long iteration) {
050        iOldV1 = assignment.getValue(iV1.variable());
051        iOldV2 = assignment.getValue(iV2.variable());
052        if (iOldV1 != null) assignment.unassign(iteration, iV1.variable());
053        if (iOldV2 != null) assignment.unassign(iteration, iV2.variable());
054        assignment.assign(iteration, iV1);
055        assignment.assign(iteration, iV2);
056    }
057    
058    /** Undo the swap */
059    @Override
060    protected void undoAssign(Assignment<V, T> assignment, long iteration) {
061        assignment.unassign(iteration, iV1.variable());
062        assignment.unassign(iteration, iV2.variable());
063        if (iOldV1 != null) assignment.assign(iteration, iOldV1);
064        if (iOldV2 != null) assignment.assign(iteration, iOldV2);
065    }
066    /** Return problem model */
067    @Override
068    public Model<V,T> getModel() {
069        return iV1.variable().getModel();
070    }
071    
072    /** String representation */
073    @Override
074    public String toString() {
075        return "Lazy "+iOldV1+" -> "+iV1+", "+iOldV2+" -> "+iV2;
076    }
077
078    @Override
079    public Map<V, T> assignments() {
080        Map<V, T> ret = new HashMap<V, T>();
081        ret.put(iV1.variable(), iV1);
082        ret.put(iV2.variable(), iV2);
083        return ret;
084    }
085
086}