#!perl

use strict;
use warnings;

use Algorithm::Evolutionary::Experiment;
use Algorithm::Evolutionary::Op::Creator;
use Algorithm::Evolutionary::Op::Bitflip;
use Algorithm::Evolutionary::Op::Crossover;
use Algorithm::Evolutionary::Op::RouletteWheel;
use Algorithm::Evolutionary::Op::GeneralGeneration;
use Algorithm::Evolutionary::Op::DeltaTerm;
use Algorithm::Evolutionary::Op::FullAlgorithm;

my $numberOfBits = shift || 32;
my $popSize = 100;

my $fitness = sub {
  my $indi = shift;
  my $total = grep( $_ == 1, split(//,$indi->Chrom() ));
  return $total; 
};

#First, the creator
my $creator = new Algorithm::Evolutionary::Op::Creator( $popSize, 'BitString', 
						    { length => $numberOfBits });

#Then, the genetic operators and variables needed for GeneralGeneration
my $selector = new Algorithm::Evolutionary::Op::RouletteWheel $popSize; #One of the possible selectors
my $mutation = new Algorithm::Evolutionary::Op::Bitflip; #Changes a single bit
my $crossover = new Algorithm::Evolutionary::Op::Crossover; #Classical 2-point crossover
my $replacementRate = 0.4; #Replacement rate
my $generation = 
  new Algorithm::Evolutionary::Op::GeneralGeneration( $fitness, $selector, 
						      [$mutation, $crossover], $replacementRate );

#This will be included in a full algorithm, along with the terminators
my $terminator = new Algorithm::Evolutionary::Op::DeltaTerm $numberOfBits, 0; 
my $algorithm =  new Algorithm::Evolutionary::Op::FullAlgorithm $generation, $terminator;

#Create experiment
my $experiment = new Algorithm::Evolutionary::Experiment $creator, $algorithm;

print<<EOC;
<?xml version="1.0" standalone="no"?>
<experiment>
EOC
print $experiment->asXML();
$experiment->go();
print $experiment->asXML(), "</experiment>";

 
