All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jamesframework.core.search.neigh.subset.SwapMove Maven / Gradle / Ivy

Go to download

The James core module is part of the James framework for optimization using local search metaheuristics in Java. The core contains general components to model problems, objectives and constraints, as well as generic algorithms to solve the problems. Moreover, the core provides implementations of specific utilities for subset selection.

There is a newer version: 1.2
Show newest version
//  Copyright 2014 Herman De Beukelaer
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.

package org.jamesframework.core.search.neigh.subset;

import java.util.Collections;
import java.util.Set;
import org.jamesframework.core.exceptions.SolutionModificationException;
import org.jamesframework.core.problems.solutions.SubsetSolution;

/**
 * Simple subset move that removes a single ID from the current selection
 * and replaces it with a new ID which was previously not selected.
 * 
 * @author Herman De Beukelaer
 */
public class SwapMove implements SubsetMove{

    // added and deleted ID
    private final int add, delete;
    
    /**
     * Creates a new swap move with specified IDs to add to and remove from the current selection
     * when being applied to a given subset solution. Both IDs can not be equal.
     * 
     * @throws IllegalArgumentException if add == delete
     * @param add ID to add
     * @param delete ID to delete
     */
    public SwapMove(int add, int delete){
        // check not equal
        if(add == delete){
            throw new IllegalArgumentException("Error while creating swap move: added and deleted ID can not be equal.");
        }
        // store IDs
        this.add = add;
        this.delete = delete;
    }
    
    /**
     * Apply this swap move to a given subset solution. The move can only be applied to a solution
     * for which the added ID is currently not selected and the deleted ID is currently
     * selected. This guarantees that calling {@link #undo(SubsetSolution)} will correctly
     * undo the move.
     * 
     * @throws SolutionModificationException if the added ID is already selected, the deleted ID is already unselected,
     *                                       or any of both IDs does not correspond to an underlying entity
     * @param solution solution to which to move will be applied
     */
    @Override
    public void apply(SubsetSolution solution) {
        // add new ID to selection
        if(solution.select(add)){
            // succesfully added new ID, now try to remove deleted ID
            if(!solution.deselect(delete)){
                // deselecting ID failed (currently not selected)
                throw new SolutionModificationException("Error while applying swap move to subset solution: deleted ID currently not selected.", solution);
            }
        } else {
            // selecting new ID failed (already selected)
            throw new SolutionModificationException("Error while applying swap move to subset solution: added ID already selected.", solution);
        }
    }

    /**
     * Undo this swap move after it has been successfully applied to the given subset solution,
     * by removing the newly added ID and re-adding the deleted ID.
     * 
     * @param solution solution to which the move has been applied
     */
    @Override
    public void undo(SubsetSolution solution) {
        // re-add deleted ID
        solution.select(delete);
        // remove newly added ID
        solution.deselect(add);
    }

    /**
     * Returns an unmodifiable singleton containing the only added ID.
     * 
     * @return unmodifiable singleton containing added ID
     */
    @Override
    public Set getAddedIDs() {
        return Collections.singleton(add);
    }
    
    /**
     * Returns the added ID.
     * 
     * @return added ID
     */
    public int getAddedID() {
        return add;
    }

    /**
     * Returns an unmodifiable singleton containing the only deleted ID.
     * 
     * @return unmodifiable singleton containing deleted ID
     */
    @Override
    public Set getDeletedIDs() {
        return Collections.singleton(delete);
    }
    
    /**
     * Returns the deleted ID.
     * 
     * @return deleted ID
     */
    public int getDeletedID(){
        return delete;
    }

    /**
     * Always returns 1.
     * 
     * @return 1
     */
    @Override
    public int getNumAdded() {
        return 1;
    }

    /**
     * Always return 1.
     * 
     * @return 1
     */
    @Override
    public int getNumDeleted() {
        return 1;
    }

    /**
     * Hash code corresponding to implementation of {@link #equals(Object)}.
     * 
     * @return hash code of this swap move
     */
    @Override
    public int hashCode() {
        int hash = 7;
        hash = 23 * hash + add;
        hash = 23 * hash + delete;
        return hash;
    }

    /**
     * Two swap moves are considered equal if they swap the same IDs.
     * 
     * @param obj object to compare with this swap move for equality
     * @return true if the given object is also a swap move and swaps the same IDs
     */
    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final SwapMove other = (SwapMove) obj;
        if (this.add != other.add) {
            return false;
        }
        return this.delete == other.delete;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy