org.jamesframework.core.search.neigh.subset.SwapMove Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of james-core Show documentation
Show all versions of james-core Show documentation
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.
// 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;
}
}