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