NAME

AI::Genetic::Pro - Efficient genetic algorithms for professional purpose.

SYNOPSIS

    use AI::Genetic::Pro;
    
    sub fitness {
        my ($ga, $chromosome) = @_;
        return oct('0b' . $ga->as_string($chromosome)); 
    }
    
    sub terminate {
        my ($ga) = @_;
        my $result = oct('0b' . $ga->as_string($ga->getFittest));
        return $result == 4294967295 ? 1 : 0;
    }
    
    my $ga = AI::Genetic::Pro->new(        
        -fitness        => \&fitness,        # fitness function
        -terminate      => \&terminate,      # terminate function
        -type           => 'bitvector',      # type of individuals/chromosomes
        -population     => 1000,             # population
        -crossover      => 0.9,              # probab. of crossover
        -mutation       => 0.01,             # probab. of mutation
        -parents        => 2,                # number  of parents
        -selection      => [ 'Roulette' ],   # selection strategy
        -strategy       => [ 'Points', 2 ],  # crossover strategy
        -cache          => 0,                # cache results
        -history        => 1,                # remember best results
        -preserved      => 1,                # remember the best chromosome
    );
	
    # init population of 32-bit vectors
    $ga->init(32);
	
    # evolve 10 generations
    $ga->evolve(10);
    
    # best score
    print "SCORE: ", $ga->as_value($ga->getFittest), ".\n";
    
    # save evolution path as a chart
    $ga->chart(-filename => 'evolution.png');
     
    # save state of GA
    $ga->save('genetic.sga');
    
    # load state of GA
    $ga->load('genetic.sga');

DESCRIPTION

This module provides efficient implementation of a genetic algorithm for a professional purpose. It was designed to operate as fast as possible even on very large populations and big individuals/chromosomes. AI::Genetic::Pro was inspired by AI::Genetic, so it is in most cases compatible (there are some changes). Additionaly AI::Genetic::Pro isn't pure Perl solution, so it doesn't have limitations of its ancestor (ie. seriously slow down in case of big populations ( >10000 ) or vectors with size > 33 fields).

If You are looking for pure Perl solution, consider AI::Genetic.

Speed

To increase speed XS code are used, however with portability in mind. This distribution was tested on Windows and Linux platforms (should work on any other).

Memory

This module was designed to use as little memory as possible. Population of size 10000 consist 92-bit vectors uses only ~24MB (in AI::Genetic something about ~78MB!!!).

Advanced options

To provide more flexibility AI::Genetic::Pro supports many statistic distributions, such as: uniform, natural, chi_square and others. This feature can be used in selection or/and crossover. See documentation below.

METHODS

Simply description of available methods. See below.

$ga->new( %options )

Constructor. It accepts options in hash-value style. See options and an example below.

-fitness

This defines a fitness function. It expects a reference to a subroutine.

-terminate

This defines a terminate function. It expects a reference to a subroutine.

-type

This defines the type of chromosomes. Currently, AI::Genetic::Pro supports four types:

bitvector

Individuals/chromosomes of this type have genes that are bits. Each gene can be in one of two possible states, on or off.

listvector

Each gene of a "listvector" individual/chromosome can assume one string value from a specified list of possible string values.

rangevector

Each gene of a "rangevector" individual/chromosome can assume one integer value from a range of possible integer values. Note that only integers are supported. The user can always transform any desired fractional values by multiplying and dividing by an appropriate power of 10.

combination

Each gene of a "combination" individual/chromosome can assume one string value from a specified list of possible string values. All genes are unique.

-population

This defines the size of the population, i.e. how many chromosomes to simultaneously exist at each generation.

-crossover

This defines the crossover rate. Fairest results are achieved with crossover rate ~0.95.

-mutation

This defines the mutation rate. Fairest results are achieved with mutation rate ~0.01.

-preserve

This defines injection of the best chromosome into a next generation. It causes a little slow down, however (very often) much better results are achieved.

-parents

This defines how many parents should used in corssover.

-selection

This defines how individuals/chromosomes are selected to crossover. It expects an array reference listed below:

-selection => [ $type, @params ]

where type is one of:

RouletteBasic

Each individual/chromosome can be selected with probability poportionaly to its fitness.

Roulette

At the first best individuals/chromosomes are selected. From this collection parents are selected with probability poportionaly to its fitness.

RouletteDistribution

Each individual/chromosome has portion of roulette wheel proportionaly to its fitness. Selection is done with specified distribution. Supported distributions and paremeters are listed below.

-selection => [ 'RouletteDistribution', 'uniform' ]

Standard uniform distribution. No additional parameters are needed.

-selection => [ 'RouletteDistribution', 'normal', $av, $sd ]

Normal distribution, where $av is average (default: size of population /2) and $$sd is standard deviation (default: size of population).

-selection => [ 'RouletteDistribution', 'beta', $aa, $bb ]

Beta distribution. The density of the beta is:

X^($aa - 1) * (1 - X)^($bb - 1) / B($aa , $bb) for 0 < X < 1.

$aa and $bb are set by default to number of parents.

Argument restrictions: Both $aa and $bb must not be less than 1.0E-37.

-selection => [ 'RouletteDistribution', 'binomial' ]

Binomial distribution. No additional parameters are needed.

-selection => [ 'RouletteDistribution', 'chi_square', $df ]

Chi-square distribution with $df degrees of freedom. $df by default is set to size of population.

-selection => [ 'RouletteDistribution', 'exponential', $av ]

Exponential distribution, where $av is average . $av by default is set to size of population.

-selection => [ 'RouletteDistribution', 'poisson', $mu ]

Poisson distribution, where $mu is mean. $mu by default is set to size of population.

Distribution

Chromosomes/individuals are selected with specified distribution. See below.

-selection => [ 'Distribution', 'uniform' ]

Standard uniform distribution. No additional parameters are needed.

-selection => [ 'Distribution', 'normal', $av, $sd ]

Normal distribution, where $av is average (default: size of population /2) and $$sd is standard deviation (default: size of population).

-selection => [ 'Distribution', 'beta', $aa, $bb ]

Beta distribution. The density of the beta is:

X^($aa - 1) * (1 - X)^($bb - 1) / B($aa , $bb) for 0 < X < 1.

$aa and $bb are set by default to number of parents.

Argument restrictions: Both $aa and $bb must not be less than 1.0E-37.

-selection => [ 'Distribution', 'binomial' ]

Binomial distribution. No additional parameters are needed.

-selection => [ 'Distribution', 'chi_square', $df ]

Chi-square distribution with $df degrees of freedom. $df by default is set to size of population.

-selection => [ 'Distribution', 'exponential', $av ]

Exponential distribution, where $av is average . $av by default is set to size of population.

-selection => [ 'Distribution', 'poisson', $mu ]

Poisson distribution, where $mu is mean. $mu by default is set to size of population.

-strategy

This defines strategy of crossover operation. It expects an array reference listed below:

-strategy => [ $type, @params ]

where type is one of:

PointsSimple

Simple crossover in one or many points. Best chromosomes/individuals are selected to new generation. In example:

-strategy => [ 'PointsSimple', $n ]

where $n is number of points for crossing.

PointsBasic

Crossover in one or many points. In basic crossover selected parents are crossed and one (random) of children is moved to new generation. In example:

-strategy => [ 'PointsBasic', $n ]

where $n is number of points for crossing.

Points

Crossover in one or many points. In normal crossover selected parents are crossed and the best of child is moved to new generation. In example:

-strategy => [ 'Points', $n ]

where $n is number of points for crossing.

PointsAdvenced

Crossover in one or many points. After crossover best chromosomes/individuals from all parents and chidren are selected to new generation. In example:

-strategy => [ 'PointsAdvanced', $n ]

where $n is number of points for crossing.

Distribution

In distribution crossover parents are crossed in points selected with specified distribution. See below.

-strategy => [ 'Distribution', 'uniform' ]

Standard uniform distribution. No additional parameters are needed.

-strategy => [ 'Distribution', 'normal', $av, $sd ]

Normal distribution, where $av is average (default: size of population /2) and $$sd is standard deviation (default: size of population).

-strategy => [ 'Distribution', 'beta', $aa, $bb ]

Beta distribution. The density of the beta is:

X^($aa - 1) * (1 - X)^($bb - 1) / B($aa , $bb) for 0 < X < 1.

$aa and $bb are set by default to number of parents.

Argument restrictions: Both $aa and $bb must not be less than 1.0E-37.

-strategy => [ 'Distribution', 'binomial' ]

Binomial distribution. No additional parameters are needed.

-strategy => [ 'Distribution', 'chi_square', $df ]

Chi-square distribution with $df degrees of freedom. $df by default is set to size of population.

-strategy => [ 'Distribution', 'exponential', $av ]

Exponential distribution, where $av is average . $av by default is set to size of population.

-strategy => [ 'Distribution', 'poisson', $mu ]

Poisson distribution, where $mu is mean. $mu by default is set to size of population.

PMX

PMX method defined by Goldberg and Lingle in 1985. Parameters: none.

OX

OX method defined by Davis (?) in 1985. Parameters: none.

-cache

This defines if cache should be used. Correct values are: 1 or 0 (default: 0).

-history

This defines if history should be collected. Correct values are: 1 or 0 (default: 0).

Collect history.

$ga->population($population)

Set/get size of the population. This defines the size of the population, i.e. how many chromosomes to simultaneously exist at each generation.

$ga->indType()

Get type of individuals/chromosomes. Currently supported types are:

bitvector

Chromosomes will be just bitvectors. See documentation of new method.

listvector

Chromosomes will be lists of specified values. See documentation of new method.

rangevector

Chromosomes will be lists of values from specified range. See documentation of new method.

combination

Chromosomes will be uniq lists of specified values. This is used for example in Traveling Salesman Problem. See documentation of new method.

In example:

my $type = $ga->type();
$ga->type()

Alias for indType.

$ga->crossProb()

This method is used to query and set the crossover rate.

$ga->crossover()

Alias for crossProb.

$ga->mutProb()

This method is used to query and set the mutation rate.

$ga->mutation()

Alias for mutation.

$ga->parents($parents)

Set/get number of parents in a crossover.

$ga->init($args)

This method initializes the population with random individuals/chromosomes. It MUST be called before any call to evolve(). It expects one argument, which depends on the type of individuals/chromosomes:

bitvector

For bitvectors, the argument is simply the length of the bitvector.

$ga->init(10);

This initializes a population where each individual/chromosome has 10 genes.

listvector

For listvectors, the argument is an anonymous list of lists. The number of sub-lists is equal to the number of genes of each individual/chromosome. Each sub-list defines the possible string values that the corresponding gene can assume.

$ga->init([
           [qw/red blue green/],
           [qw/big medium small/],
           [qw/very_fat fat fit thin very_thin/],
          ]);

This initializes a population where each individual/chromosome has 3 genes and each gene can assume one of the given values.

rangevector

For rangevectors, the argument is an anonymous list of lists. The number of sub-lists is equal to the number of genes of each individual/chromosome. Each sub-list defines the minimum and maximum integer values that the corresponding gene can assume.

$ga->init([
           [1, 5],
           [0, 20],
           [4, 9],
          ]);

This initializes a population where each individual/chromosome has 3 genes and each gene can assume an integer within the corresponding range.

combination

For combination, the argument is an anonymous list of possible values of gene.

$ga->init( [ 'a', 'b', 'c' ] );

This initializes a population where each chromosome has 3 genes and each gene is uniq combination of 'a', 'b' and 'c'. For example genes looks something like that:

[ 'a', 'b', 'c' ]    # gene 1
[ 'c', 'a', 'b' ]    # gene 2
[ 'b', 'c', 'a' ]    # gene 3
# ...and so on...
$ga->evolve()

This method causes the GA to evolve the population for the specified number of generations.

$ga->getHistory()

Get history of the evolution. It is in a format listed below:

[
	# gen0   gen1   gen2   ...          # generations
	[ max0,  max1,  max2,  ... ],       # max values
	[ mean,  mean1, mean2, ... ],       # mean values
	[ min0,  min1,  min2,  ... ],       # min values
]
$ga->getAvgFitness()

Get max, mean and min score of the current generation. In example:

my ($max, $mean, $min) = $ga->getAvgFitness();
$ga->getFittest()

Get fittest chromosome.

$ga->generation()

Get number of generation.

$ga->people()

Returns an anonymous list of individuals/chromosomes of the current population.

IMPORTANT: the actual array reference used by the AI::Genetic::Pro object is returned, so any changes to it will be reflected in $ga.

$ga->chromosomes()

Alias for people.

$ga->chart(%options)

Generate a chart describing changes of min, mean, max scores in Your population. To satisfy Your needs, You can pass following options:

-filename

File to save a chart in (obligatory).

-title

Title of a chart (default: Evolution).

-x_label

X label (default: Generations).

-y_label

Y label (default: Value).

-format

Format of values, like sprintf (default: '%.2f').

-legend1

Description of min line (default: Min value).

-legend2

Description of min line (default: Mean value).

-legend3

Description of min line (default: Max value).

-width

Width of a chart (default: 640).

-height

Height of a chart (default: 480).

-font

Path to font in (*.ttf format) to be used (default: none).

Path to logo (png/jpg image) to embed in a chart (default: none).

In example:
$ga->chart(-width => 480, height => 320, -filename => 'chart.png');
$ga->save($file)

Save current state of the genetic algorithm to a specified file.

$ga->load($file)

Load a state of the genetic algorithm from a specified file.

$ga->as_array($chromosome)

Return an array representing specified chromosome.

$ga->as_value($chromosome)

Return score of specified chromosome. Value of chromosome is calculated by fitness function.

$ga->as_string($chromosome)

Return string-representation of specified chromosome.

DOCUMENTATION

This documentation is still incomplete, however it is based on POD of AI::Genetic. So if You are in a trouble, try to take a look to the documentation of AI::Genetic.

SUPPORT

AI::Genetic::Pro is still under development and it has poor documentation (for now). However it is used in many production environments.

TODO

Examples.
More tests.
Warnings in case of incorrect parameters.

REPORTING BUGS

When reporting bugs/problems please include as much information as possible. It may be difficult for me to reproduce the problem as almost every setup is different.

A small script which yields the problem will probably be of help.

THANKS

Christoph Meissner for reporting a bug.

Alec Chen for reporting some bugs.

AUTHOR

Strzelecki Lukasz <strzelec@rswsystems.com>

SEE ALSO

AI::Genetic

COPYRIGHT

Copyright (c) Strzelecki Lukasz. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.