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

gov.sandia.cognition.learning.algorithm.genetic.ParallelizedGeneticAlgorithm Maven / Gradle / Ivy

/*
 * 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 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 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);
        }
        
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy