Click here to Skip to main content
15,892,005 members
Articles / Desktop Programming / MFC

Genetic Algorithm Library

Rate me:
Please Sign up or sign in to vote.
4.93/5 (175 votes)
7 Apr 2012GPL358 min read 439.2K   34.7K   555  
A framework for genetic algorithms
/*! \file Population.h
    \brief This file declares classes and datatypes of chromosomes population.
*/

/*
 * 
 * website: http://www.coolsoft-sd.com/
 * contact: support@coolsoft-sd.com
 *
 */

/*
 * Genetic Algorithm Library
 * Copyright (C) 2007-2008 Coolsoft Software Development
 * 
 * This program 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 2
 * of the License, or (at your option) any later version.
 * 
 * This program 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, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 */

#ifndef __GA_POPULATION_H__
#define __GA_POPULATION_H__

#include <list>

#include "Platform.h"
#include "Threading.h"
#include "Statistics.h"
#include "Chromosome.h"
#include "SortedGroup.h"
#include "ChromosomeOperations.h"
#include "PopulationOperations.h"

using namespace std;

using namespace Common;
using namespace Population;
using namespace Chromosome;

/// <summary>Contatins interfaces, classes and datatypes used to implement population of chromosomes and genetic operations.</summary>
namespace Population
{

	/// <summary><c>GaPopulationParameters</c> class represents parameters of population.
	///
	/// This class has no built-in synchronizator, so <c>LOCK_OBJECT</c> and <c>LOCK_THIS_OBJECT</c> macros cannot be used with instances of this class.
	/// No public or private methods are thread-safe.</summary></summary>
	class GaPopulationParameters : public GaParameters
	{

	private:

		/// <summary>Maximal population size (number of chromosomes in population).</summary>
		int _populationSize;

		/// <summary>This attribute indicate if number of chromosomes in population can change. If it is set to <c>true</c> number of chromosomes can vary.
		/// If this attribute is set to <c>false</c>, number of chromosomes in population is equal to maximal number.</summary>
		bool _resizable;

		/// <summary>If this attribute is set to <c>true</c>, chromosomes in population is sorted by their fitness value (original or scaled).</summary>
		bool _sorting;

		/// <summary>If this attribute is set to <c>true</c>, scaled fitness values are used for sorting chromosomes in population.
		/// If it is set to <c>false</c>, original (non-scaled) fitness values are used.</summary>
		bool _usingScaledFitness;

		/// <summary>This attribute stores number of best chromosomes of which population keeps track.
		/// This attribute is ignored if population is sorted.</summary>
		int _bestTrackCount;

		/// <summary>This attribute stores number of worst chromosomes of which population keeps track.
		/// This attribute is ignored if population is sorted.</summary>
		int _worstTrackCount;

	public:

		/// <summary>This constructor initializes population parameters with user-defined values.</summary>
		/// <param name="populationSize">size of population (maximal number of chromosomes in population).</param>
		/// <param name="resizable">instructs population that number of chromosomes can change.</param>
		/// <param name="sorting">instructs population to sort chromosomes according to their fitness values.</param>
		/// <param name="useScaldeFitness">instructs population to use scaled (transformed) fitness value for sorting chromosomes.</param>
		/// <param name="bestTrackCount">number of best chromosomes of which track is being kept.</param>
		/// <param name="worstTrackCount">number of worst chromosomes of which track is being kept.</param>
		GAL_API
		GaPopulationParameters(int populationSize,
			bool resizable,
			bool sorting,
			bool useScaldeFitness,
			int bestTrackCount,
			int worstTrackCount);

		/// <summary>More details are given in specification of <see cref="GaParameters::Clone" /> method.
		///
		/// This method is not thread-safe.</summary>
		virtual GaParameters* GACALL Clone() const { return new GaPopulationParameters( *this ); }

		/// <summary>This method is not thread-safe.</summary>
		/// <returns>Method returns maximal population size (number of chromosomes in population).</returns>
		inline int GACALL GetPopulationSize() const { return _populationSize; }

		/// <summary><c>SetPopulationSize</c> method sets maximal population size.
		///
		/// This method is not thread-safe.</summary>
		/// <param name="size">size of population.</param>
		inline void GACALL SetPopulationSize(int size) { _populationSize = size >= 2 ? size : 2; }

		/// <summary>This method is not thread-safe.</summary>
		/// <returns>Method returns <c>true</c> if number of chromosomes can change, otherwise it returns <c>false</c>.</returns>
		inline bool GACALL GetResizable() const { return _resizable; }

		/// <summary><c>SetResizable</c> method sets capability of population to accept changes of number of chromosomes in it. 
		///
		/// This method is not thread-safe.</summary>
		/// <param name="resizable">instructs population that number of chromosomes can change.</param>
		inline void GACALL SetResizable(bool resizable) { _resizable = resizable; }

		/// <summary>This method is not thread-safe.</summary>
		/// <returns>Method returns <c>true</c> if chromosomes in population is sorted by their fitness value (original or scaled),
		/// otherwise it returns <c>false</c>.</returns>
		inline bool GACALL GetSorting() const { return _sorting; }

		/// <summary><c>SetSorting</c> method sets capability of population to sort chromosomes by their fitness value.
		///
		/// This method is not thread-safe.</summary>
		/// <param name="sorting">instructs population to sort chromosomes according to their fitness values.</param>
		inline void GACALL SetSorting(bool sorting) { _sorting = sorting; }

		/// <summary>This method is not thread-safe.</summary>
		/// <returns>Method returns <c>true</c> if population use scaled fitness value to sort chromosomes,
		/// otherwise if non-scaled fitness values are used it returns <c>false</c>.</returns>
		inline bool GACALL GetUsingScaledFitness() const { return _usingScaledFitness; }

		/// <summary><c>SetUseScaledFitness</c> method sets capability of population to use scaled fitness values of chromosomes for sorting them. 
		///
		/// This method is not thread-safe.</summary>
		/// <param name="useScaledFitness">instructs population to use scaled (transformed) fitness value for sorting chromosomes.</param>
		inline void GACALL SetUsingScaledFitness(bool useScaledFitness) { _usingScaledFitness = useScaledFitness; }

		/// <summary>This method is not thread-safe.</summary>
		/// <returns>Method returns number of best chromosomes of which population keeps track.</returns>
		inline int GACALL GetBestTrackCount() const { return _bestTrackCount; }

		/// <summary><c>SetBestTrackCount</c> method sets number of best chromosomes of which population keeps track
		///
		/// This method is not thread-safe.</summary>
		/// <param name="count">number of best chromosomes of which track is being kept.</param>
		GAL_API
		void GACALL SetBestTrackCount(int count);

		/// <summary>This method is not thread-safe.</summary>
		/// <returns>Method returns number of best chromosomes of which population keeps track.</returns>
		inline int GACALL GetWorstTrackCount() const { return _worstTrackCount; }

		/// <summary><c>SetWorstTrackCount</c> method sets number of worst chromosomes of which population keeps track. 
		///
		/// This method is not thread-safe.</summary>
		/// <param name="count">number of worst chromosomes of which track is being kept.</param>
		GAL_API
		void  GACALL SetWorstTrackCount(int count);

	};// END CLASS DEFINITION GaPopulationParameters

	class GaPopulation;

	/// <summary>This class stores parameters and genetic operations of a population or a group of populations. All populations bound to the configuration,
	/// are updated and notified every time when configuration is changed. Note that each population copies parameters' of the population and use local copy.
	///
	/// This class has no built-in synchronizator, so <c>LOCK_OBJECT</c> and <c>LOCK_THIS_OBJECT</c> macros cannot be used with instances of this class.
	/// No public or private methods are thread-safe.</summary>
	class GaPopulationConfiguration
	{

	private:

		/// <summary>Global instance of default configuration.</summary>
		GAL_API
		static GaPopulationConfiguration* _default;

		/// <summary>Selection operation and its parameters.</summary>
		GaSelectionPair _selection;

		/// <summary>Replacement operation and its parameters.</summary>
		GaReplacementPair _replacement;

		/// <summary>Scaling operation and its parameters.</summary>
		GaScalingPair _scaling;

		/// <summary>Coupling operation and its parameters.</summary>
		GaCouplingPair _coupling;

		/// <summary>Population's parameters</summary>
		GaPopulationParameters _parameters;

		/// <summary>List of populations which use this configuration.</summary>
		list<GaPopulation*> _populations;

		/// <summary>Pointer to comparator used for sorting the chromosomes in population.</summary>
		const GaFitnessComparator* _sortingComparator;

	public:

		/// <summary><c>MakeDefault</c> method makes global instance of default configuration.
		///
		/// This method is not thread-safe.</summary>
		GAL_API
		static void GACALL MakeDefault();

		/// <summary><c>FreeDefault</c> method frees global instance of default configuration.
		///
		/// This method is not thread-safe.</summary>
		static void GACALL FreeDefault()
		{
			if( _default )
				delete _default;

			_default = NULL;
		}

		/// <summary>This method is not thread-safe.</summary>
		/// <returns>Method returns reference to default configuration.</returns>
		static GaPopulationConfiguration& GetDefault() { return *_default; }

		/// <summary>This constructor initializes configuration by cloning default configuration.</summary>
		GaPopulationConfiguration() : _parameters(_default->_parameters),
			_sortingComparator(_default->_sortingComparator),
			_selection(_default->_selection),
			_replacement(_default->_replacement),
			_coupling(_default->_coupling),
			_scaling(_default->_scaling) { }

		/// <summary>This constructor initializes configuration with user defined operations and parameters.</summary>
		/// <param name="populationParams">reference to populations' parameters.
		/// It makes copy of parameters object by using <c>GaParameters::Clone</c> method.</param>
		/// <param name="sortComparator"></param>
		/// <param name="selectionOperation">pointer to selection operation.</param>
		/// <param name="selectionParams">pointer to parameters of selection operation.</param>
		/// <param name="replacementOperation">pointer to replacement operation.</param>
		/// <param name="replacementParams">pointer to parameters of replacement operation.</param>
		/// <param name="couplingOperation">pointer to coupling operation.</param>
		/// <param name="couplingParams">pointer to parameters of coupling operation.</param>
		/// <param name="scalingOperation">pointer to scaling operation.</param>
		/// <param name="scalingParams">pointer to parameters of scaling operation.</param>
		GaPopulationConfiguration(const GaPopulationParameters& populationParams,
			const GaFitnessComparator* sortComparator,
			GaSelectionOperation* selectionOperation,
			GaSelectionParams* selectionParams,
			GaReplacementOperation* replacementOperation,
			GaReplacementParams* replacementParams,
			GaCouplingOperation* couplingOperation,
			GaCouplingParams* couplingParams,
			GaScalingOperation* scalingOperation,
			GaScalingParams* scalingParams): _parameters(populationParams),
			_sortingComparator(sortComparator),
			_selection(selectionOperation, *selectionParams),
			_replacement(replacementOperation, *replacementParams),
			_coupling(couplingOperation, *couplingParams),
			_scaling(scalingOperation, *scalingParams) { }

		/// <summary><c>BindPopulation</c> method binds population to this configuration.
		///
		/// This method is not thread-safe.</summary>
		/// <param name="population">pointer to population which should be bound.</param>
		/// <param name="refresh">this parameter should be set to <c>true</c> if population should be notified about change 
		/// and refreshed according to new parameters.</param>
		GAL_API
		void GACALL BindPopulation(GaPopulation* population,
			bool refresh);

		// Unbinds population form the configuration
		/// <summary><c>UnbindPopulation</c> method unbinds population from this configuration.
		///
		/// This method is not thread-safe.</summary>
		/// <param name="population">pointer to population which should be unbound.</param>
		inline void GACALL UnbindPopulation(GaPopulation* population)
		{
			if( population )
				_populations.remove( population );
		}

		// Returns parameter of the population(s)
		/// <summary>This method is not thread-safe.</summary>
		/// <returns></returns>
		inline const GaPopulationParameters& GACALL GetParameters() const { return _parameters; }

		// Sets parameter of the population(s)
		/// <summary></summary>
		/// <param name="parameters"></param>
		GAL_API
		void GACALL SetParameters(const GaPopulationParameters& parameters);

		/// <summary>This method is not thread-safe.</summary>
		/// <returns>Method returns reference to object that holds pointer to selection operation which should be executed by the algorithm
		/// and its parameters.</returns>
		inline const GaSelectionPair& GACALL Selection() const { return _selection; }

		/// <summary>This method is not thread-safe.</summary>
		/// <returns>Method returns reference to object that holds pointer to replacement operation which should be executed by the algorithm
		/// and its parameters.</returns>
		inline const GaReplacementPair& GACALL Replacement() const { return _replacement; }

		/// <summary>This method is not thread-safe.</summary>
		/// <returns>Method returns reference to object that holds pointer to scaling operation which should be executed by the algorithm
		/// and its parameters.</returns>
		inline const GaScalingPair& GACALL Scaling() const { return _scaling; }

		/// <summary>This method is not thread-safe.</summary>
		/// <returns>Method returns reference to object that holds pointer to coupling operation which should be executed by the algorithm
		/// and its parameters.</returns>
		inline const GaCouplingPair& GACALL Coupling() const { return _coupling; }

		/// <summary>This <c>SetOperation</c> method sets selection operation and its parameters which should be used by genetic algorithm.
		/// It makes copy of parameters object by using <c>GaParameters::Clone</c> method. The method also notifies all bound populations about the change.
		///
		/// This method is not thread safe.</summary>
		/// <param name="operation">pointer to new selection operation.</param>
		/// <param name="parameters">pointer to parameters of selection operation.</param>
		inline void GACALL SetOperation(GaSelectionOperation* operation,
			GaSelectionParams* parameters) { _selection.SetOperation( operation, *parameters ); }

		/// <summary>This <c>SetOperation</c> method sets replacement operation and its parameters which should be used by genetic algorithm.
		/// It makes copy of parameters object by using <c>GaParameters::Clone</c> method. The method also notifies all bound populations about the change.
		///
		/// This method is not thread safe.</summary>
		/// <param name="operation">pointer to new replacement operation.</param>
		/// <param name="parameters">pointer to parameters of replacement operation.</param>
		inline void GACALL SetOperation(GaReplacementOperation* operation,
			GaReplacementParams* parameters) { _replacement.SetOperation( operation, *parameters ); }

		/// <summary>This <c>SetOperation</c> method sets scaling operation and its parameters which should be used by genetic algorithm.
		/// It makes copy of parameters object by using <c>GaParameters::Clone</c> method. The method also notifies all bound populations about the change.
		///
		/// This method is not thread safe.</summary>
		/// <param name="operation">pointer to new scaling operation.</param>
		/// <param name="parameters">pointer to parameters of scaling operation.</param>
		GAL_API
		void GACALL SetOperation(GaScalingOperation* operation,
			GaScalingParams* parameters);

		/// <summary>This <c>SetOperation</c> method sets coupling operation and its parameters which should be used by genetic algorithm.
		/// It makes copy of parameters object by using <c>GaParameters::Clone</c> method. The method also notifies all bound populations about the change.
		///
		/// This method is not thread safe.</summary>
		/// <param name="operation">pointer to new coupling operation.</param>
		/// <param name="parameters">pointer to parameters of coupling operation.</param>
		inline void GACALL SetOperation(GaCouplingOperation* operation,
			GaCouplingParams* parameters) { _coupling.SetOperation( operation, *parameters ); }

		/// <summary>This <c>SetOperationParams</c> method sets parameters for selection operation.
		/// It makes copy of parameters object by using <c>GaParameters::Clone</c> method. The method also notifies all bound populations about the change.
		///
		/// This method is not thread safe.</summary>
		/// <param name="parameters">pointer to parameters of selection operation.</param>
		inline void GACALL SetOperationParams(GaSelectionParams* parameters) { _selection.SetParameters( *parameters ); }

		/// <summary>This <c>SetOperationParams</c> method sets parameters for replacement operation.
		/// It makes copy of parameters object by using <c>GaParameters::Clone</c> method. The method also notifies all bound populations about the change.
		///
		/// This method is not thread safe.</summary>
		/// <param name="parameters">pointer to parameters of replacement operation.</param>
		inline void GACALL SetOperationParams(GaReplacementParams* parameters) { _replacement.SetParameters( *parameters ); }

		/// <summary>This <c>SetOperationParams</c> method sets parameters for scaling operation.
		/// It makes copy of parameters object by using <c>GaParameters::Clone</c> method. The method also notifies all bound populations about the change.
		///
		/// This method is not thread safe.</summary>
		/// <param name="parameters">pointer to parameters of scaling operation.</param>
		GAL_API
		void GACALL SetOperationParams(GaScalingParams* parameters);

		/// <summary>This <c>SetOperationParams</c> method sets parameters for coupling operation.
		/// It makes copy of parameters object by using <c>GaParameters::Clone</c> method. The method also notifies all bound populations about the change.
		///
		/// This method is not thread safe.</summary>
		/// <param name="parameters">pointer to parameters of coupling operation.</param>
		inline void GACALL SetOperationParams(GaCouplingParams* parameters) { _coupling.SetParameters( *parameters ); }

		/// <summary>This method is not thread-safe.</summary>
		/// <returns>Method returns pointer to fitness comparator which is used for sorting chromosomes in population.</returns>
		inline const GaFitnessComparator* GACALL GetSortComparator() const { return _sortingComparator; }

		// Sets comparator used for sorting the chromosomes
		/// <summary><c>SetSortComaprator</c> method sets fitness comparator which is used for sorting chromosomes.
		/// The method also notifies all bound populations about the change.</summary>
		/// <param name="comparator">pointer to new fitness comparator.</param>
		GAL_API
		void GACALL SetSortComparator(const GaFitnessComparator* comparator);

	};// END CLASS DEFINITION GaPopulationConfiguration
		
	/// <summary><c>GaPopulation</c> class is used to host chromosomes. Population also provides statistical information about chromosomes in population
	/// by using <see cref="GaStatistics" /> class. Same chromosome can be hosted by multiple populations because they are stored in population using
	/// scaled chromosome object which contains smart pointer to chromosome and value of scaled fitness (because this value depends on population,
	/// but not on chromosome itself and same chromosome can be in multiple populations). Chromosomes in population can be sorted which provides easy way
	/// of tracking best and worst chromosomes, but if chromosomes are not sorted, population provides to sorted groups which stores indices of best and
	/// worst chromosomes. Sorting of chromosomes in population or in sorted groups is done my using provided sorting comparator. Both scaled and non-scaled
	/// fitness values of chromosomes can be used for sorting, which value is going to be used depends on specified parameters, but if scaling operation is not
	/// defined for the population, non-scaled fitness values are used. Maximal number of chromosomes which can be hosted is specified in population's parameters.
	/// Also whether the population is going to be fixed-size (number of chromosomes in population is always equals to maximal number of chromosomes it can store)
	/// or resizable (population can host from 0 to maximal number of chromosomes) is specified in population's parameters. During population initialization,
	/// provided prototype is used to create chromosomes which fill the population.  Fixed-size populations are always filled during initialization,
	/// which is not the case with resizable populations. Besides hosting of chromosomes, population also binds extern genetic operations (selection, coupling,
	/// scaling, and replacement) which are going to be used by genetic algorithm during evolution.
	///
	/// This class has built-in synchronizator so it is allowed to use <c>LOCK_OBJECT</c> and <c>LOCK_THIS_OBJECT</c> macros with instances of this class.
	/// No public or private methods are thread-safe.</summary>
	class GaPopulation
	{

		friend class GaPopulationConfiguration;

		DEFINE_SYNC_CLASS;

	private:

		/// <summary>If this attribute is set to <c>true</c>, scaled fitness values are used for sorting chromosomes in population.
		/// If it is set to <c>false</c>, original (non-scaled) fitness values are used. Value of this attribute is copied from population's parameters.</summary>
		bool _usingScaledFitness;

		/// <summary>Number of chromosomes currently in population.</summary>
		int _currentSize;

		/// <summary>Statistical information about population.</summary>
		GaStatistics _statistics;

		/// <summary>Pointer to array of scaled chromosome objects. Chromosomes which belong to population are stored in this array.</summary>
		GaScaledChromosome** _chromosomes;

		/// <summary>Pointer to chromosome which represents prototype for initialization of population.</summary>
		GaChromosome* _prototype;

		/// <summary>This sorted group keeps track of best chromosomes in population. If population is sorted, this group is ignored.
		/// Group uses same fitness comparator for sorting as population.</summary>
		GaSortedGroup _best;

		/// <summary>This sorted group keeps track of worst chromosomes in population. If population is sorted, this group is ignored.
		/// Group uses same fitness comparator for sorting as population, but it inverse results of comparisons in order to provide inverse sorting of chromosomes.</summary>
		GaSortedGroup _worst;

		/// <summary></summary>
		GaPopulationConfiguration* _configuration;

		/// <summary>Population's parameters.</summary>
		GaPopulationParameters _parameters;

	public:

		/// <summary>This constructor initializes population with its configuration and prototype chromosomes. It also allocates memory for array
		/// which is used to store chromosomes, and initializes sorted groups which keep track of best and worst chromosomes.</summary>
		/// <param name="prototype">pointer to chromosomes which is prototype for making chromosomes during population initialization.</param>
		/// <param name="configuration">pointer to population's configuration.</param>
		GAL_API
		GaPopulation(GaChromosome* prototype,
			GaPopulationConfiguration* configuration);

		/// <summary>Destructor frees memory used by scaled chromosome objects which are hosted in population and array which stores them.</summary>
		GAL_API
		~GaPopulation();

		/// <summary><c>Clone</c> method makes copy of population's object. It can make copy of whole object (with setup and chromosomes) or it can make empty
		/// copy of population's object (only setup, without coping chromosomes). Copying of chromosomes is done by making new scaled chromosomes object which
		/// holds smart pointers to same chromosomes. Caller is responsible for memory allocated by this method for new population's object.
		///
		/// This method is not thread-safe.</summary>
		/// <param name="copyChromosomes">if this parameter is set to <c>true</c>, both setup and chromosomes are copied to new object,
		/// otherwise new object is empty, but with same setup.</param>
		GAL_API
		GaPopulation* GACALL Clone(bool copyChromosomes) const;

		/// <summary>This method removes all chromosomes from population and clears sorted group and statistical information.
		/// If population is not resizable or user specified so, population is filled with new chromosomes which are built based on provided prototype,
		/// also it sorts new chromosomes if needed and update sorted groups and statistical information.
		///
		/// This method is not thread-safe.</summary>
		/// <param name="fill">if this parameter is set to <c>true</c>, population is filled wit new chromosomes built on specified prototype.
		/// If this parameter is set to <c>false</c>, population is only cleared. This parameter is ignored if population is not resizable, and population
		/// is always filled.</param>
		/// <returns>Method returns pointer to newly created chromosome's object.</returns>
		GAL_API
		void GACALL InitializePopulation(bool fill = true);

		/// <summary>This method fills provided array with indices of best chromosomes in population. If population is not sorted this method can only
		/// provide number of best chromosomes which is equal to number of tracked best chromosomes.
		///
		/// This method is not thread-safe.</summary>
		/// <param name="results">pointer to array which is going to be filled.</param>
		/// <param name="start">index of the first best chromosome which is going to be copied.</param>
		/// <param name="numberOfChromosomes">number of queried chromosomes' indices.</param>
		/// <returns>Method returns number of saved indices in output array.</returns>
		GAL_API
		int GACALL GetBestChromosomes(int* results,
			int start,
			int numberOfChromosomes) const;

		/// <summary>This method fills provided array with smart pointer to best chromosomes in population. If population is not sorted this method can only
		/// provide number of best chromosomes which is equal to number of tracked best chromosomes.
		///
		/// This method is not thread-safe.</summary>
		/// <param name="results">pointer to array which is going to be filled.</param>
		/// <param name="start">index of the first best chromosome which is going to be copied.</param>
		/// <param name="numberOfChromosomes">number of queried chromosome' indices.</param>
		/// <returns>Method returns number of saved smart pointer to chromosomes in output array.</returns>
		GAL_API
		int GACALL GetBestChromosomes(GaChromosomePtr* results,
			int start,
			int numberOfChromosomes) const;

		/// <summary>This method fills provided array with smart pointer to worst chromosomes in population. If population is not sorted this method can only
		/// provide number of worst chromosomes which is equal to number of tracked worst chromosomes.
		///
		/// This method is not thread-safe.</summary>
		/// <param name="results">pointer to array which is going to be filled.</param>
		/// <param name="start">index of the last worst chromosome which is going to be copied.</param>
		/// <param name="numberOfChromosomes">number of queried chromosome' indices.</param>
		/// <returns>Method returns number of saved indices in output array.</returns>
		GAL_API
		int GACALL GetWorsChromosomes(int* results,
			int start,
			int numberOfChromosomes) const;

		/// <summary>This method fills provided array with indices of worst chromosomes in population. If population is not sorted this method can only
		/// provide number of worst chromosomes which is equal to number of tracked worst chromosomes.
		///
		/// This method is not thread-safe.</summary>
		/// <param name="results">pointer to array which is going to be filled.</param>
		/// <param name="start">index of the last worst chromosome which is going to be copied.</param>
		/// <param name="numberOfChromosomes">number of queried chromosome' indices.</param>
		/// <returns>Method returns number of saved smart pointer to chromosomes in output array.</returns>
		GAL_API
		int GACALL GetWorsChromosomes(GaChromosomePtr* results,
			int start,
			int numberOfChromosomes) const;

		/// <summary><c>Replace</c> method removes chromosome with specified index from population and insert new chromosome. Scaled fitness value of
		/// new chromosome is automatically calculated. This method preserve sorting of chromosomes and update sorted group and statistical information.
		///
		/// This method is not thread-safe.</summary>
		/// <param name="index">index of chromosome which is going to be removed.</param>
		/// <param name="newChromosome">smart pointer to chromosome which is going to be inserted into population.</param>
		/// <returns>Method returns 1 if chromosome is replaced, otherwise returns 0.</returns>
		GAL_API
		int GACALL Replace(int index,
			GaChromosomePtr newChromosome);

		/// <summary><c>Replace</c> method removes group of chromosomes with specified indices from population and insert new chromosomes. Scaled fitness values
		/// of new chromosomes are automatically calculated. If index of one chromosome in specified more then once in array of chromosomes which
		/// should be removed, results are unexpected and may lead to failures. This method preserve sorting of chromosomes and update sorted group and
		/// statistical information.
		///
		/// This method is not thread-safe.</summary>
		/// <param name="indices">pointer to array of indices of chromosomes which are going to be removed.</param>
		/// <param name="newChromosomes">pointer to array of smart pointer to chromosomes which are going to be inserted into population.</param>
		/// <param name="numberOfChromosomes">number of chromosomes which are going to be replaced.</param>
		/// <returns>Method returns number of replaced chromosomes.</returns>
		GAL_API
		int GACALL ReplaceGroup(int* indices,
			GaChromosomePtr* newChromosomes,
			int numberOfChromosomes);

		/// <summary><c>Insert</c> method inserts new chromosome into population. If population is not sorted new chromosome can be inserted if population
		/// is resizable and is not full. If population is sorted new chromosome is inserted at appropriate place (according to sorting policy),
		/// but if population is fixed-size or resizable but full, this method virtually extends population size by one before it inserts chromosome,
		/// after inserting it removes chromosome with worst fitness value (new chromosome is also included). This method preserve sorting of chromosomes
		/// and update sorted group and statistical information.
		///
		/// This method is not thread-safe.</summary>
		/// <param name="chromosome">smart pointer to chromosome which is going to be inserted into population.</param>
		/// <returns>Method returns 1 if chromosome is inserted, otherwise returns 0.</returns>
		GAL_API
		int GACALL Insert(GaChromosomePtr chromosome);

		/// <summary><c>Insert</c> method inserts new chromosomes into population. If population is not sorted new chromosomes can be inserted if population
		/// is resizable and is not full, if there is more new chromosomes then space in population, only first chromosomes are inserted. If population is
		/// sorted new chromosomes are inserted at appropriate places (according to sorting policy), but if population is fixed-size or resizable but full,
		/// this method virtually extends population size so it is able to host all chromosome before it inserts chromosomes, after inserting it
		/// removes chromosomes with worst fitness values(new chromosomes are also included). This method preserve sorting of chromosomes and update sorted group
		/// and statistical information.
		///
		/// This method is not thread-safe.</summary>
		/// <param name="chromosomes">pointer to array of smart pointer to chromosomes which are going to be inserted into population.</param>
		/// <param name="numberOfChromosomes">number of chromosomes which should be inserted.</param>
		/// <returns>Method returns number of inserted chromosomes.</returns>
		GAL_API
		int GACALL InsertGroup(GaChromosomePtr* chromosomes,
			int numberOfChromosomes);

		/// <summary><c>Remove</c> method removes chromosome with specified index from population. To remove chromosome from population, it must be resizable.
		/// This method preserve sorting of chromosomes and update sorted group and statistical information.
		///
		/// This method is not thread-safe.</summary>
		/// <param name="chromosome">index of chromosome which is going to be removed.</param>
		/// <returns>Method returns 1 if chromosome is removed, otherwise returns 0.</returns>
		GAL_API
		int GACALL Remove(int chromosome);

		/// <summary><c>Remove</c> method removes chromosomes with specified indices from population. To remove chromosomes from population, it must be resizable.
		/// If index of one chromosome in specified more then once in array of chromosomes which should be removed, results are unexpected and
		/// may lead to failures. This method preserve sorting of chromosomes and update sorted group and statistical information.
		///
		/// This method is not thread-safe.</summary>
		/// <param name="chromosomes">pointer to array of indices of chromosomes which are going to be removed.</param>
		/// <param name="numberOfChromosomes">number of chromosomes which are going to be removed.</param>
		/// <returns>Method returns number of removed chromosomes.</returns>
		GAL_API
		int GACALL RemoveGroup(int* chromosomes,
			int numberOfChromosomes);

		/// <summary><c>NextGeneration</c> method prepares population for new generation. It should be called before new cycle of execution of
		/// genetic operations by genetic algorithm.
		///
		/// This method is not thread-safe.</summary>
		inline void GACALL NextGeneration() { _statistics.NextGeneration(); }

		/// <summary><c>EndOfGeneration</c> method is used for evolutions with non-overlapping population. It is used to finalize cycle of genetic operations'
		/// execution and should be called by genetic algorithm at the end of a generation.
		///
		/// This method is not thread-safe.</summary>
		/// <param name="previous">reference to population which is used in previous generation by the algorithm.</param>
		inline void GACALL EndOfGeneration(const GaPopulation& previous)
		{
			// rescale population if needed
			if( _configuration->Scaling().HasOperation() &&
				_configuration->Scaling().GetOperation().NeedRescaling( *this, _configuration->Scaling().GetParameters() ) )
				RescaleAll();

			// copy statistics from previous population
			_statistics.CopyFrom( previous._statistics, true, false, true );
		}

		/// <summary><c>EndOfGeneration</c> method is used for evolutions with overlapping population. It is used to finalize cycle of genetic operations'
		/// execution and should be called by genetic algorithm at the end of a generation.
		///
		/// This method is not thread-safe.</summary>
		inline void GACALL EndOfGeneration()
		{
			// rescale population if needed
			if( _configuration->Scaling().HasOperation() &&
				_configuration->Scaling().GetOperation().NeedRescaling( *this, _configuration->Scaling().GetParameters() ) )
				RescaleAll();
		}

		/// <summary><c>Clear</c> method removes all chromosomes form population and clears statistical information if specified.
		///
		/// This method is not thread-safe.</summary>
		/// <param name="clearStatistics">if this parameter is set to <c>true</c>, method clears statistics and removes chromosomes,
		/// otherwise it keeps statistics.</param>
		GAL_API
		void GACALL Clear(bool clearStatistics);

		/// <summary><c>GetChromosomeRanking</c> method returns ranking of chromosomes with specified index based on its fitness value (scaled or non-scaled).
		/// If population is sorted, all chromosomes has ranking. If it is unsorted only chromosomes in best and worst sorted groups has ranking.
		/// Also inverse chromosome ranking can be queried.
		///
		/// This method is not thread-safe.</summary>
		/// <param name="chromosomeIndex">index of chromosome which rank is queried.</param>
		/// <param name="reverse">if this is set to <c>true</c>, inverse ranking is queried, otherwise normal ranking is queried.</param>
		/// <returns>Method returns rnking of the chromosome in the population. If chromosome has no ranking, method returns -1.</returns>
		GAL_API
		int GACALL GetChromosomeRanking(int chromosomeIndex,
			bool reverse = false);

		/// <summary>This method is not thread-safe.</summary>
		/// <param name="position">index of chromosome.</param>
		/// <returns>Method returns reference to scaled chromosome with specified index.</returns>
		inline GaScaledChromosome& GACALL GetAt(int position) const { return *_chromosomes[ position ]; }

		/// <summary>This method is not thread-safe.</summary>
		/// <returns>Method returns reference to object which contains statistical information about population.</returns>
		inline const GaStatistics& GACALL GetStatistics() const { return _statistics; }

		/// <summary>This method is not thread-safe.</summary>
		/// <returns>Method returns reference to population configuration.</returns>
		inline const GaPopulationConfiguration& GetConfiguration() const { return *_configuration; }

		/// <summary><c>SetConfiguration</c> method sets population's configuration.
		///
		/// This method is not thread-safe.</summary>
		/// <param name="configuration">pointer to new configuration object.</param>
		void SetConfiguration(GaPopulationConfiguration* configuration)
		{ 
			if( _configuration != configuration )
			{
				_configuration->UnbindPopulation( this );

				_configuration = configuration;
			
				if( _configuration )
					_configuration->BindPopulation( this, true );
			}
		}

		/// <summary>This method is not thread-safe.</summary>
		/// <returns>Method returns <c>true</c> if population use scale fitness values for sorting.
		/// If population use non-scaled fitness values, it returns <c>false</c>. </returns>
		inline bool GACALL IsScaledFitnessUsed() { return _usingScaledFitness; }

		/// <summary>This method is not thread-safe.</summary>
		/// <returns>Method returns pointer to chromosome which is used as prototype during initialization of population.</returns>
		inline const GaChromosome& GACALL GetPrototype() const { return *_prototype; }

		/// <summary>This method is not thread-safe.</summary>
		/// <returns>Method returns number of chromosomes in population. If population is fixed size this method returns maximal number of chromosomes
		/// if population is initialized, or 0 if it is not.</returns>
		inline int GACALL GetCurrentSize() const { return _currentSize; }

	private:

		/// <summary><c>SetParameters</c> method sets parameters of population. It copies values of parameters into built-in parameters' object of population
		/// and updates population according to new parameters.
		///
		/// This method is not thread-safe.</summary>
		/// <param name="parameters">reference to object of new population's parameters.</param>
		GAL_API
		void SetParameters(const GaPopulationParameters& parameters);

		/// <summary><c>SetSortComaprator</c> method sets fitness comparator which is used for sorting chromosomes. It update sorting of chromosomes,
		/// sorted groups and statistical information according to new sorting policy.
		///
		/// This method is not thread-safe.</summary>
		/// <param name="comparator">pointer to new fitness comparator.</param>
		GAL_API
		void SetSortComparator(const GaFitnessComparator* comparator);

		/// <summary><c>RefreshBestGroup</c> method refreshes content of best sorted group.
		///
		/// This method is not thread-safe.</summary>
		inline void GACALL RefreshBestGroup()
		{
			for( int i = 0; i < _currentSize; i++ )
				_best.Add( i );
		}

		/// <summary><c>RefreshWorstGroup</c> method refreshes content of worst sorted group.
		/// This method is not thread-safe.</summary>
		inline void GACALL RefreshWorstGroup()
		{
			for( int i = 0; i < _currentSize; i++ )
				_worst.Add( i );
		}

		/// <summary><c>UpdateStatistics</c> method updates all population statistics.
		/// This method is not thread-safe.</summary>
		/// <param name="fitnessChange">value by which sum of non-scaled fitness values of all chromosomes in population has change after last update.</param>
		/// <param name="scaledFitnessChange">value by which sum of scaled fitness values of all chromosomes in population has change after last update.</param>
		GAL_API
		void GACALL UpdateStatistics(float fitnessChange,
			float scaledFitnessChange);

		/// <summary><c>RescaleAll</c> method recalculates scaled fitness values of all chromosomes in population and stores them.
		/// It also updates population statistics.</summary>
		GAL_API
		void GACALL RescaleAll();

		/// <summary>ResortPopulation method resorts population when some of part of sorting policy is changed. After resorting, method updates statistics.
		/// If population is not sorted, this method updates sorted group.
		///
		/// This method is not thread-safe.</summary>
		/// <param name="refreshFitnesses">if this parameter is set to true, before resorting all fitness values should be recalculated
		/// (i.e. after change of fitness operation).</param>
		/// <param name="scalingChanged">if this parameter is set to true, before resorting all scaled fitness values should be recalculated
		/// (i.e. after change of scaling operation).</param>
		/// <param name="comparatorChanged">this parameter indicates that fitness comparator which is used for sorting has changed.</param>
		GAL_API
		void GACALL ResortPopulation(bool refreshFitnesses,
			bool scalingChanged,
			bool comparatorChanged);

		/// <summary>This method is used by CRT's <c>qsort</c> function for sorting array which stores chromosomes.</summary>
		GAL_API
		static int APICALL SortComparison(const void* first,
			const void* second);

	};// END CLASS DEFINITION GaPopulation

} // Population

#endif // __GA_POPULATION_H__

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)


Written By
Software Developer
Serbia Serbia
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions