001    package net.sf.cpsolver.ifs.model;
002    
003    import net.sf.cpsolver.ifs.model.Model;
004    import net.sf.cpsolver.ifs.model.Value;
005    import 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 Tomas Muller<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     */
029    public 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    }