    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}