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

org.cicirello.search.concurrent.TimedParallelReoptimizableMultistarter Maven / Gradle / Ivy

Go to download

Chips-n-Salsa is a Java library of customizable, hybridizable, iterative, parallel, stochastic, and self-adaptive local search algorithms. The library includes implementations of several stochastic local search algorithms, including simulated annealing, hill climbers, as well as constructive search algorithms such as stochastic sampling. Chips-n-Salsa now also includes genetic algorithms as well as evolutionary algorithms more generally. The library very extensively supports simulated annealing. It includes several classes for representing solutions to a variety of optimization problems. For example, the library includes a BitVector class that implements vectors of bits, as well as classes for representing solutions to problems where we are searching for an optimal vector of integers or reals. For each of the built-in representations, the library provides the most common mutation operators for generating random neighbors of candidate solutions, as well as common crossover operators for use with evolutionary algorithms. Additionally, the library provides extensive support for permutation optimization problems, including implementations of many different mutation operators for permutations, and utilizing the efficiently implemented Permutation class of the JavaPermutationTools (JPT) library. Chips-n-Salsa is customizable, making extensive use of Java's generic types, enabling using the library to optimize other types of representations beyond what is provided in the library. It is hybridizable, providing support for integrating multiple forms of local search (e.g., using a hill climber on a solution generated by simulated annealing), creating hybrid mutation operators (e.g., local search using multiple mutation operators), as well as support for running more than one type of search for the same problem concurrently using multiple threads as a form of algorithm portfolio. Chips-n-Salsa is iterative, with support for multistart metaheuristics, including implementations of several restart schedules for varying the run lengths across the restarts. It also supports parallel execution of multiple instances of the same, or different, stochastic local search algorithms for an instance of a problem to accelerate the search process. The library supports self-adaptive search in a variety of ways, such as including implementations of adaptive annealing schedules for simulated annealing, such as the Modified Lam schedule, implementations of the simpler annealing schedules but which self-tune the initial temperature and other parameters, and restart schedules that adapt to run length.

There is a newer version: 7.0.1
Show newest version
/*
 * Chips-n-Salsa: A library of parallel self-adaptive local search algorithms.
 * Copyright (C) 2002-2023 Vincent A. Cicirello
 *
 * This file is part of Chips-n-Salsa (https://chips-n-salsa.cicirello.org/).
 *
 * Chips-n-Salsa is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Chips-n-Salsa is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see .
 */

package org.cicirello.search.concurrent;

import java.util.Collection;
import org.cicirello.search.ProgressTracker;
import org.cicirello.search.ReoptimizableMetaheuristic;
import org.cicirello.search.SolutionCostPair;
import org.cicirello.search.restarts.ConstantRestartSchedule;
import org.cicirello.search.restarts.ReoptimizableMultistarter;
import org.cicirello.search.restarts.RestartSchedule;
import org.cicirello.util.Copyable;

/**
 * This class is used for implementing parallel multistart metaheuristics. It can be used to restart
 * any class that implements the {@link ReoptimizableMetaheuristic} interface. A multistart
 * metaheuristic returns the best result from among all of the restarts. In the case of a parallel
 * multistart metaheuristic, the search returns the best result from among all restarts across all
 * threads.
 *
 * 

This parallel multistarter enables specifying the run length in terms of time, rather than by * number of restarts. It then executes as many restarts as that length of time allows. This may be * more desirable for multiple use cases. First, if the run lengths can vary from one restart to * another, each parallel instance of the search may have rather different run times if we were to * specify the number of times to restart. This would lead to some threads sitting idle. Second, if * we were executing different metaheuristics in different threads, then again one or more threads * may complete early sitting idle if we were to specify number of times to restart. Third, a * similar phenomena can result if we were executing the same metaheuristic (e.g., simulated * annealing) but where each parallel instance was using a different mutation operator. Finally, if * we know how much time we can afford to search, we don't need a priori know the length of time * required by a restart. * *

There are several constructors enabling different ways to configure the search. You can * initialize the search with a combination of a {@link ReoptimizableMetaheuristic} and number of * threads along with either a {@link RestartSchedule} for the purpose of specifying run lengths for * the restarts, or a run length if all runs are to be of the same length. You can also initialize * the search with a Collection of {@link RestartSchedule} objects, one for each thread (with number * of threads implied by size of Collection. Or you can initialize the search with a Collection of * {@link ReoptimizableMetaheuristic} objects and a Collection of {@link RestartSchedule} objects * (both Collections of the same size). You can also initialize the search with a {@link * ReoptimizableMultistarter} configured with your restart schedule, along with the number of * threads, or a Collection of {@link ReoptimizableMultistarter} objects. * * @param The type of object being optimized. * @author Vincent A. Cicirello, https://www.cicirello.org/ */ public final class TimedParallelReoptimizableMultistarter> extends TimedParallelMultistarter implements ReoptimizableMetaheuristic { /** * Constructs a parallel multistart metaheuristic that executes multiple runs of a specified * metaheuristic in parallel across multiple threads. All restarts are the same in length. * * @param search The metaheuristic to restart multiple times in parallel. * @param runLength The length of every restarted run of the metaheuristic. * @param numThreads The number of threads to use. * @throws IllegalArgumentException if numThreads is less than 1. * @throws IllegalArgumentException if nunLength is less than 1. */ public TimedParallelReoptimizableMultistarter( ReoptimizableMetaheuristic search, int runLength, int numThreads) { this(search, new ConstantRestartSchedule(runLength), numThreads); } /** * Constructs a parallel multistart metaheuristic that executes multiple runs of a specified * metaheuristic in parallel across multiple threads. All parallel instances follow the same * restart schedule of run lengths. * * @param search The metaheuristic to restart multiple times in parallel. * @param r The schedule of run lengths. Note that the threads do not share a single * RestartSchedule. Rather, each thread will be initialized with its own copy of r. * @param numThreads The number of threads to use. * @throws IllegalArgumentException if numThreads is less than 1. */ public TimedParallelReoptimizableMultistarter( ReoptimizableMetaheuristic search, RestartSchedule r, int numThreads) { this(new ReoptimizableMultistarter(search, r), numThreads); } /** * Constructs a parallel multistart metaheuristic that executes multiple runs of a specified * metaheuristic in parallel across multiple threads. Each parallel instance follows its own * restart schedule of run lengths. * * @param search The metaheuristic to restart multiple times in parallel. * @param schedules The schedules of run lengths, one for each thread. The number of threads will * be equal to the number of restart schedules. * @throws IllegalArgumentException if schedules.size() is less than 1. */ public TimedParallelReoptimizableMultistarter( ReoptimizableMetaheuristic search, Collection schedules) { super(ParallelMultistarterUtil.toReoptimizableMultistarters(search, schedules), false); } /** * Constructs a parallel multistart metaheuristic that executes multiple runs of a set of * specified metaheuristics in parallel across multiple threads. Each parallel search follows its * own restart schedule of run lengths. * * @param searches A collection of the metaheuristics to restart multiple times in parallel. The * number of threads will be equal to the size of this collection. * @param schedules The schedules of run lengths, one for each thread. * @throws IllegalArgumentException if searches.size() is not equal to schedules.size(). * @throws IllegalArgumentException if the Collection of Metaheuristics don't all share the same * problem (i.e., requires that s1.getProblem() == s2.getProblem() for all s1, s2 in * searches). * @throws IllegalArgumentException if the Collection of Metaheuristics don't all share a single * ProgressTracker (i.e., requires that s1.getProgressTracker() == s2.getProgressTracker() for * all s1, s2 in searches). */ public TimedParallelReoptimizableMultistarter( Collection> searches, Collection schedules) { super(ParallelMultistarterUtil.toReoptimizableMultistarters(searches, schedules), false); } /** * Constructs a parallel multistart metaheuristic that executes multiple runs of a set of * specified metaheuristics in parallel across multiple threads. All runs of all parallel * instances follows a constant run length. * * @param searches A collection of the metaheuristics to restart multiple times in parallel. The * number of threads will be equal to the size of this collection. * @param runLength The length of all restarted runs of all parallel metaheuristics. * @throws IllegalArgumentException if runLength < 1. * @throws IllegalArgumentException if the Collection of Metaheuristics don't all share the same * problem (i.e., requires that s1.getProblem() == s2.getProblem() for all s1, s2 in * searches). * @throws IllegalArgumentException if the Collection of Metaheuristics don't all share a single * ProgressTracker (i.e., requires that s1.getProgressTracker() == s2.getProgressTracker() for * all s1, s2 in searches). */ public TimedParallelReoptimizableMultistarter( Collection> searches, int runLength) { this(searches, ConstantRestartSchedule.createRestartSchedules(searches.size(), runLength)); } /** * Constructs a parallel multistart metaheuristic that executes multiple runs of a specified * metaheuristic in parallel across multiple threads. All parallel instances follow the same * restart schedule of run lengths. * * @param multistartSearch A ReoptimizableMultistarter configured with the metaheuristic and * restart schedule. Each of the threads will be an identical copy of this * ReoptimizableMultistarter. * @param numThreads The number of threads to use. * @throws IllegalArgumentException if numThreads is less than 1. */ public TimedParallelReoptimizableMultistarter( ReoptimizableMultistarter multistartSearch, int numThreads) { super(multistartSearch, numThreads); } /** * Constructs a parallel multistart metaheuristic that executes multiple runs of a set of * specified metaheuristics in parallel across multiple threads. Each of the Multistarters will * run in its own thread. The number of threads will be equal to the number of Multistarters * passed to the constructor. * * @param multistarters A collection of Multistarters configured with the metaheuristics and * restart schedules for the threads. * @throws IllegalArgumentException if the Collection of Multistarters don't all share the same * problem (i.e., requires that s1.getProblem() == s2.getProblem() for all s1, s2 in * multistarters). * @throws IllegalArgumentException if the Collection of Multistarters don't all share a single * ProgressTracker (i.e., requires that s1.getProgressTracker() == s2.getProgressTracker() for * all s1, s2 in multistarters). */ public TimedParallelReoptimizableMultistarter( Collection> multistarters) { super(multistarters, true); } /* * private copy constructor to support split() method. */ private TimedParallelReoptimizableMultistarter(TimedParallelReoptimizableMultistarter other) { super(other); } /** * Executes a parallel multistart search. The number of threads, the specific metaheuristic * executed by each thread, the restart schedules, etc are determined by how the * TimedParallelMultistarter was configured at the time of construction. All parallel instances of * the search are executed for approximately the length of time indicated by the time parameter, * restarting as many times as time allows, keeping track of the best solution across the multiple * parallel runs of the search. It may terminate earlier if one of the parallel searches indicates * the best possible solution was found. Each restart of each parallel search begins at the best * solution found so far, but reinitializes any search control parameters. * *

If this method is called multiple times, the restart schedules of the parallel * metaheuristics are not reinitialized, and the run lengths for the additional restarts will * continue where the schedules left off. * * @param time The approximate length of time for the search. The unit of time is as indicated by * the constant {@link TimedParallelMultistarter#TIME_UNIT_MS} unless changed by a call to the * {@link TimedParallelMultistarter#setTimeUnit} method. For example, assuming {@link * TimedParallelMultistarter#setTimeUnit} has not been called, then the search will run for * approximately: time * {@link TimedParallelMultistarter#TIME_UNIT_MS} milliseconds. * @return The best end of run solution (and its cost) of this set of parallel runs, which may or * may not be the same as the solution contained in this metaheuristic's {@link * ProgressTracker}, which contains the best of all runs. Returns null if the run did not * execute, such as if the ProgressTracker already contains the theoretical best solution. * @see TimedParallelMultistarter#setTimeUnit * @see TimedParallelMultistarter#getTimeUnit * @throws IllegalStateException if the {@link TimedParallelMultistarter#close} method was * previously called. */ @Override public SolutionCostPair reoptimize(int time) { return threadedOptimize(time, new CallableReoptimizerFactory(Integer.MAX_VALUE)); } @Override public TimedParallelReoptimizableMultistarter split() { return new TimedParallelReoptimizableMultistarter(this); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy