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

org.jamesframework.core.search.MultiNeighbourhoodSearch 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;

import java.util.List;
import org.jamesframework.core.exceptions.SearchException;
import org.jamesframework.core.problems.Problem;
import org.jamesframework.core.problems.solutions.Solution;
import org.jamesframework.core.search.neigh.Neighbourhood;

/**
 * Abstract neighbourhood search that uses multiple neighbourhoods to modify the current solution. This
 * includes variable neighbourhood descent and variable neighbourhood search.
 *
 * @param  solution type of the problems that may be solved using this search, required to extend {@link Solution}
 * @author Herman De Beukelaer
 */
public abstract class MultiNeighbourhoodSearch extends NeighbourhoodSearch {

    // neighbourhoods
    private List> neighs;
    
    /**
     * Create a new multi neighbourhood search, specifying the problem to be solved and the neighbourhoods used to
     * modify the current solution. None of both arguments may be null and the list of neighbourhoods
     * may not be empty and may not contain any null elements The default search name "MultiNeighbourhoodSearch"
     * is assigned.
     * 
     * @throws NullPointerException if problem or neighs are null, or if
     *                              neighs contains a null element
     * @throws IllegalArgumentException if neighs is empty
     * @param problem problem to be solved
     * @param neighs neighbourhoods used to modify the current solution
     */
    public MultiNeighbourhoodSearch(Problem problem, List> neighs){
        this(null, problem, neighs);
    }
    
    /**
     * Create a new multi neighbourhood search, specifying the problem to be solved, the neighbourhoods used to
     * modify the current solution, and a custom search name. The problem and neighbourhood list may not be
     * null and the neighbourhood list may not be empty and may not contain any null
     * elements. The search name may be null in which case the default name "MultiNeighbourhoodSearch"
     * is assigned.
     * 
     * @throws NullPointerException if problem or neighs are null, or if
     *                              neighs contains a null element
     * @throws IllegalArgumentException if neighs is empty
     * @param name custom search name
     * @param problem problem to be solved
     * @param neighs neighbourhoods used to modify the current solution
     */
    public MultiNeighbourhoodSearch(String name, Problem problem, List> neighs){
        // pass problem to super
        super(name != null ? name : "MultiNeighbourhoodSearch", problem);
        // check neighs not null
        if(neighs == null){
            throw new NullPointerException("Error while creating multi neighbourhood search: neighbourhood list can not be null.");
        }
        // check that neighs does not contain any null elements
        for(Neighbourhood n : neighs){
            if(n == null){
                throw new NullPointerException("Error while creating multi neighbourhood search: neighbourhood list can not"
                                                    + " contain any null elements.");
            }
        }
        // check neighs not empty
        if(neighs.isEmpty()){
            throw new IllegalArgumentException("Error while creating multi neighbourhood search: neighbourhood list can not be empty.");
        }
        // store neighbourhoods
        this.neighs = neighs;
    }
    
    /**
     * Get the list of neighbourhoods used to modify the current solution.
     * 
     * @return list of applied neighbourhoods
     */
    public List> getNeighbourhoods(){
        return neighs;
    }
    
    /**
     * Sets the list of neighbourhoods used to modify the current solution. Note that neighs
     * can not be null nor empty and can not contain any null elements. This method
     * may only be called when the search is idle. It should be used with care for searches that have already
     * been run before and will be restarted later, as updating the neighbourhoods might break the execution
     * of a restarted search that tries to continue from where it had arrived.
     * 
     * @throws NullPointerException if neighs is null or contains any null elements
     * @throws IllegalArgumentException if neighs is empty
     * @throws SearchException if the search is currently not idle
     * @param neighs list of neighbourhoods used to modify the current solution
     */
    public void setNeighbourhoods(List> neighs){
        // synchronize with status updates
        synchronized(getStatusLock()){
            // assert idle
            assertIdle("Cannot set list of neighbourhoods.");
            // check not null
            if(neighs == null){
                throw new NullPointerException("Can not set neighbourhoods: received null.");
            }
            // check that neighs does not contain any null elements
            for(Neighbourhood n : neighs){
                if(n == null){
                    throw new NullPointerException("Can not set neighbourhoods: neighbourhood list can not"
                                                        + " contain any null elements.");
                }
            }
            // check not empty
            if(neighs.isEmpty()){
                throw new NullPointerException("Can not set neighbourhoods: received empty list.");
            }
            // go ahead
            this.neighs = neighs;
        }
    }
    
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy