<commit_before>package Experiment;
use v5.10;
use strict;
use Data::Dumper;
use Moo;
use Module::Load;
use AI::Genetic;

has generations      => (is => 'ro', default => 100);
has population       => (is => 'ro', default => 50);
has play             => (is => 'ro', default => 10);
has mutation         => (is => 'ro', default => 0.05);
has crossover        => (is => 'ro', default => 0.9);
has strategy         => (is => 'ro', default => 'rouletteTwoPoint');
has chromosome_class => (is => 'ro', default => 'Chromosome::40Bits');
has fitness_class    => (is => 'ro', default => 'Fitness::Base');
has fitness_function => (is => 'lazy');
has ga               => (is => 'lazy');

sub run {
    my $self = shift;

    load($self->fitness_class);
    load($self->chromosome_class);

    $self->ga->init($self->chromosome_class->init);
    $self->print_current_state();

    for my $n (0..$self->generations -1 ) {
        $self->ga->evolve($self->strategy, 1);
        $self->print_current_state();
    }
    my $best_chromosome = $self->chromosome_class->new({
        genes => [$self->ga->people->[0]->genes],
    });
    say 'Weights of best chromosome:';
    say Dumper($best_chromosome->to_string);

}

sub print_current_state {
    my $self = shift;

    say "---------------------------------";
    say "Generation " . $self->ga->generation();
    say "Best score: " . $self->ga->getFittest->score;
    say "---------------------------------";
}

sub _build_ga {
    my $self = shift;

    return AI::Genetic->new(
        -fitness         => $self->fitness_function,
        -type            => $self->chromosome_class->type,
        -population      => $self->population,
        -crossover       => $self->crossover,
        -mutation        => $self->mutation,
    );
}

sub _build_fitness_function {
    my $self = shift;

    my $fitness = $self->fitness_class->new({
        play => $self->play,
        chromosome_class => $self->chromosome_class,
    });<commit_msg>Output csv<commit_after>package Experiment;
use v5.10;
use strict;
use Data::Dumper;
use Moo;
use Module::Load;
use AI::Genetic;

has generations      => (is => 'ro', default => 100);
has population       => (is => 'ro', default => 50);
has play             => (is => 'ro', default => 10);
has mutation         => (is => 'ro', default => 0.05);
has crossover        => (is => 'ro', default => 0.9);
has strategy         => (is => 'ro', default => 'rouletteTwoPoint');
has chromosome_class => (is => 'ro', default => 'Chromosome::40Bits');
has fitness_class    => (is => 'ro', default => 'Fitness::Base');
has fitness_function => (is => 'lazy');
has ga               => (is => 'lazy');
has weights          => (is => 'lazy');

sub run {
    my $self = shift;

    load($self->fitness_class);
    load($self->chromosome_class);

    $self->_print_headers();
    $self->ga->init($self->chromosome_class->init);
    $self->_print_generation();

    for my $n (0..$self->generations -1 ) {
        $self->ga->evolve($self->strategy, 1);
        $self->_print_generation();
    }
}

sub _print_headers {
    my $self = shift;

    say join(',', 'Generation', 'Fitness', @{$self->weights});
}

sub _print_generation {
    my $self = shift;

    for my $individual (@{$self->ga->people}) {
        my $chromosome = $self->chromosome_class->new({
            genes => [$individual->genes]
        });

        my @weight_values = map { $chromosome->weights->{$_} } @{$self->weights};

        say join(',', $self->ga->generation, $individual->score, @weight_values);
    }
}

sub _build_weights {
    my $self = shift;

    return [sort keys %{$self->chromosome_class->new()->weights}];
}

sub _build_ga {
    my $self = shift;

    return AI::Genetic->new(
        -fitness         => $self->fitness_function,
        -type            => $self->chromosome_class->type,
        -population      => $self->population,
        -crossover       => $self->crossover,
        -mutation        => $self->mutation,
    );
}

sub _build_fitness_function {
    my $self = shift;

    my $fitness = $self->fitness_class->new({
        play => $self->play,
        chromosome_class => $self->chromosome_class,
    });
{'fraction_non_alphanumeric': 0.2014853857211308, 'fraction_numerical': 0.009822712026832775, 'mean_word_length': 2.4647302904564317, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 151, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1601345', 'n_tokens_mistral': 1440, 'n_tokens_neox': 1323, 'n_words': 307}