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