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

org.jamesframework.core.search.neigh.subset.adv.GeneralSubsetMove 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.adv;

import java.util.Collections;
import java.util.Set;
import org.jamesframework.core.exceptions.SolutionModificationException;
import org.jamesframework.core.problems.solutions.SubsetSolution;
import org.jamesframework.core.search.neigh.subset.SubsetMove;

/**
 * A general subset move adds and/or removes several IDs at once to/from the current selection
 * of a subset solution.
 * 
 * @author Herman De Beukelaer
 */
public class GeneralSubsetMove implements SubsetMove {

    // set of IDs to add and remove
    private Set add;
    private Set delete;
    
    /**
     * Creates a general subset move, indicating which IDs are to be added to and removed from
     * the current selection when being applied to a given subset solution. Note that the sets
     * add and remove are not copied: a reference to the given
     * sets is stored in the subset move. If any of both sets is null, it will be
     * replaced with an empty set.
     * 
     * @param add set of IDs to add to the selection
     * @param remove set of IDs to remove from the selection
     */
    public GeneralSubsetMove(Set add, Set remove){
        // store sets (set empty set in case of nullpointers)
        if(add != null){
            this.add = add;
        } else {
            this.add = Collections.emptySet();
        }
        if(remove != null){
            this.delete = remove;
        } else {
            this.delete = Collections.emptySet();
        }
    }
    
    /**
     * Returns an unmodifiable view of the set of IDs added to the selection when applying
     * this move to a subset solution. The returned set may be empty.
     * 
     * @return set of added IDs
     */
    @Override
    public Set getAddedIDs() {
        return Collections.unmodifiableSet(add);
    }

    /**
     * Returns an unmodifiable view of the set of IDs removed from the selection when applying
     * this move to a subset solution. The returned set may be empty.
     * 
     * @return set of removed IDs
     */
    @Override
    public Set getDeletedIDs() {
        return Collections.unmodifiableSet(delete);
    }

    /**
     * Returns the number of added IDs. May be zero.
     * 
     * @return number of added IDs
     */
    @Override
    public int getNumAdded() {
        return add.size();
    }

    /**
     * Returns the number of removed IDs. May be zero.
     * 
     * @return number of removed IDs
     */
    @Override
    public int getNumDeleted() {
        return delete.size();
    }

    /**
     * Apply this move to a given subset solution. The move can only be applied to a solution
     * for which none of the added IDs are currently already selected and none of the removed
     * IDs are currently not selected. This guarantees that calling {@link #undo(SubsetSolution)}
     * will correctly undo the move.
     * 
     * @throws SolutionModificationException if some added ID is already selected, some removed ID is currently
     *                                       not selected, or any ID does not correspond to an underlying entity
     * @param solution solution to which to move will be applied
     */
    @Override
    public void apply(SubsetSolution solution) {
        // add IDs
        for(int ID : add){
            if(!solution.select(ID)){
                throw new SolutionModificationException("Cannot add ID " + ID + " to selection (already selected).", solution);
            }
        }
        // remove IDs
        for(int ID : delete){
            if(!solution.deselect(ID)){
                throw new SolutionModificationException("Cannot remove ID " + ID + " from selection (currently not selected).", solution);
            }
        }
    }

    /**
     * Undo this move after it has been successfully applied to the given subset solution,
     * by removing all added IDs and adding all removed IDs. If the subset solution has been
     * modified since successful application of this move, the result of this operation is
     * undefined.
     * 
     * @param solution solution to which the move has been successfully applied
     */
    @Override
    public void undo(SubsetSolution solution) {
        // remove all added IDs
        solution.deselectAll(add);
        // add all removed IDs
        solution.selectAll(delete);
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy