gov.sandia.cognition.learning.algorithm.genetic.ParallelizedGeneticAlgorithm Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cognitive-foundry Show documentation
Show all versions of cognitive-foundry Show documentation
A single jar with all the Cognitive Foundry components.
/*
* File: ParallelizedGeneticAlgorithm.java
* Authors: Christina Warrender
* Company: Sandia National Laboratories
* Project: Cognitive Foundry
*
* Copyright October 08, 2008, Sandia Corporation.
* Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive
* license for use of this work by or on behalf of the U.S. Government. Export
* of this program may require a license from the United States Government.
* See CopyrightHistory.txt for complete details.
*
*/
package gov.sandia.cognition.learning.algorithm.genetic;
import gov.sandia.cognition.algorithm.ParallelAlgorithm;
import gov.sandia.cognition.algorithm.ParallelUtil;
import gov.sandia.cognition.learning.algorithm.genetic.reproducer.Reproducer;
import gov.sandia.cognition.learning.data.SequentialDataMultiPartitioner;
import gov.sandia.cognition.learning.function.cost.CostFunction;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* This is a parallel implementation of the genetic algorithm. The
* default is to use n-1 available cores/hyperthreads on a machine and spread
* the cost function evaluations across these computational units.
*
* @param Type of genome used to represent a single element in
* the genetic population. For example, a {@code Vector}.
* @param Type of parameters that the cost function
* takes. For example, {@code Collection}.
* @author cewarr
*/
public class ParallelizedGeneticAlgorithm
extends GeneticAlgorithm
implements ParallelAlgorithm
{
/**
* Parallel tasks that evaluate genome fitness
*/
private ArrayList>>> evaluateTasks;
/**
* Thread pool used to parallelize the computation
*/
private transient ThreadPoolExecutor threadPool;
/**
* Default constructor
*/
public ParallelizedGeneticAlgorithm()
{
this( null, null, null, null );
}
/**
* @param initialPopulation The initial population to start the algorithm
* @param reproducer The reproduction method to use.
* @param cost The cost function for genomes.
* @param threadPool Thread pool to use for parallelization
*/
public ParallelizedGeneticAlgorithm(
Collection initialPopulation,
Reproducer reproducer,
CostFunction super GenomeType, ? super CostParametersType> cost,
ThreadPoolExecutor threadPool)
{
super(initialPopulation, reproducer, cost);
this.setThreadPool( threadPool );
}
/**
* @param initialPopulation The initial population to start the algorithm
* @param reproducer The reproduction method to use.
* @param cost The cost function for genomes.
* @param threadPool Thread pool to use for parallelization
* @param maxIterations The maximum number of iterations to run.
* @param maxIterationsWithoutImprovement The maximum number of iterations
* to go without improvement before stopping.
*/
public ParallelizedGeneticAlgorithm(
Collection initialPopulation,
Reproducer reproducer,
CostFunction super GenomeType, ? super CostParametersType> cost,
ThreadPoolExecutor threadPool,
int maxIterations,
int maxIterationsWithoutImprovement)
{
super(initialPopulation, reproducer, cost, maxIterations,
maxIterationsWithoutImprovement);
this.setThreadPool( threadPool );
}
/**
* Getter for threadPool
* @return
* Thread pool used to parallelize the computation
*/
public ThreadPoolExecutor getThreadPool()
{
return this.threadPool;
}
/**
* Setter for threadPool
* @param threadPool
* Thread pool used to parallelize the computation
*/
public void setThreadPool(
ThreadPoolExecutor threadPool )
{
this.threadPool = threadPool;
}
/**
* Getter for #threads
* @return
* #threads
*/
public int getNumThreads()
{
return ParallelUtil.getNumThreads( this );
}
/**
* Creates the evaluation tasks to execute in parallel.
*
* @param population
* The population to create tasks for.
*/
protected void createEvaluationTasks( Collection population )
{
if( this.getThreadPool() == null )
{
this.setThreadPool( ParallelUtil.createThreadPool() );
}
int numThreads = this.getNumThreads();
ArrayList> partitions =
SequentialDataMultiPartitioner.create(
population, numThreads );
this.evaluateTasks = new
ArrayList>>>( numThreads );
for( int i = 0; i < numThreads; i++ )
{
this.evaluateTasks.add( new EvaluateGenome( partitions.get( i ) ) );
}
}
/**
* Converts a population of genomes into evaluated genomes.
*
* @param population The population of genomes to evaluate.
* @return A population of evaluated genomes.
*/
@Override
protected ArrayList> evaluatePopulation(
Collection population)
{
if (population == null)
return null;
// create tasks to evaluate population in parallel
this.createEvaluationTasks( population );
// Convert the Genome to an EvaluatedGenome.
ArrayList> evaluatedPopulation =
new ArrayList>(population.size());
try
{
// Execute the evaluations in parallel
List>>> results =
this.getThreadPool().invokeAll( this.evaluateTasks );
for( Future>> result : results )
{
evaluatedPopulation.addAll( 0, result.get() );
}
}
catch (Exception ex)
{
Logger.getLogger( ParallelizedGeneticAlgorithm.class.getName() ).log( Level.SEVERE, null, ex );
}
return evaluatedPopulation;
}
/**
* Callable task for the evaluate() method.
*/
protected class EvaluateGenome
implements Callable>>
{
private Collection population;
/**
* Creates a new instance of EvaluateGenome
* @param population
* Population to evaluate
*/
public EvaluateGenome(
ArrayList population )
{
this.population = population;
}
public ArrayList> call()
{
return ParallelizedGeneticAlgorithm.super.evaluatePopulation(this.population);
}
}
}