Algorithm-MarkovChain

 view release on metacpan or  search on metacpan

README  view on Meta::CPAN


  use Algorithm::MarkovChain;

  my $chain = Algorithm::MarkovChain::->new();

  # learn about things from @symbols
  $chain->seed(symbols => \@symbols,
               longest => 6);

  # attempt to tell me something about the sky
  my @newness = $chain->spew(length   => 20,
                             complete => [ qw( the sky is ) ]);



=head1 INSTALLATION

 perl Build.PL
 perl Build test

and if all goes well

demos/dada  view on Meta::CPAN

    while (<IN>) {
        $mc->seed(symbols => [m/(\S+)/g],
                  longest => 4);
        print "\r$.        ";
    }
    print "\nseeded\n";
}


while (<>) {
    print join(' ', $mc->spew(length => 30)),"\n";
}

demos/textfile  view on Meta::CPAN


print "Seeded\n";

#poke where we're not invited.
#for my $key (sort { keys %{ $c->{_chains}{$b} } <=> keys %{ $c->{_chains}{$a} } } keys %{ $c->{_chains} }) {
#    print DumperX { $key => $c->{_chains}{$key} };
#}

while (<>) {
    print join(' ', $c->spew(complete => [ m/(\S+)/g ],
                             length => 20)),"\n";
}

lib/Algorithm/MarkovChain.pm  view on Meta::CPAN



sub longest_sequence {
    my Algorithm::MarkovChain $self = shift;

    local $; = $self->{seperator};

    my $l = 0;
    for (keys %{ $self->{chains} }) {
        my @tmp = split $;, $_;
        my $length = scalar @tmp;
        $l = $length if $length > $l;
    }
    return $l;
}


sub sequence_known  {
    my Algorithm::MarkovChain $self = shift;
    my ($sequence) = @_;

    return $self->{chains}{$sequence};

lib/Algorithm/MarkovChain.pm  view on Meta::CPAN


  use Algorithm::MarkovChain;

  my $chain = Algorithm::MarkovChain::->new();

  # learn about things from @symbols
  $chain->seed(symbols => \@symbols,
               longest => 6);

  # attempt to tell me something about the sky
  my @newness = $chain->spew(length   => 20,
                             complete => [ qw( the sky is ) ]);

=head1 DESCRIPTION

Algorithm::MarkovChain is an implementation of the Markov Chain
algorithm within an object container.

It is implemented as a base class, C<Algorithm::MarkovChain::Base>,
with storage implementations of a hash (C<Algorithm::MarkovChain>),
and an fairly memory efficent implementation using C<glib>

lib/Algorithm/MarkovChain.pm  view on Meta::CPAN

C<symbols> presents the symbols to seed from

C<longest> sets an upper limit on the longest chain to
construct. (defaults to 4)


=item $obj->spew()

Uses the constructed chains to produce symbol streams

Takes four optional parameters C<complete>, C<length>,
C<longest_subchain>, C<force_length>, C<stop_at_terminal> and
C<strict_start>

C<complete> provides a starting point for the generation of output.
Note: the algorithm will discard elements of this list if it does not
find a starting chain that matches it, this is infinite-loop avoidance.

C<length> specifies the minimum number of symbols desired (default is 30)

C<stop_at_terminal> directs the spew to stop chaining at the first
terminal point reached

C<force_length> ensures you get exactly C<length> symbols returned
(note this overrides the behaviour of C<stop_at_terminal>)

C<strict_start> makes the spew operation always take a known start
state rather than selecting a sequence at random

=item $obj->increment_seen($sequence, $symbol)

Increments the seeness of a symbol following a sequence.


lib/Algorithm/MarkovChain/Base.pm  view on Meta::CPAN


    our @symbols;
    *symbols = $args{symbols};

    push @{ $self->{_start_states} }, $symbols[0];

    if ($self->{_recover_symbols}) {
        $self->{_symbols}{$_} = $_ for @symbols;
    }

    for my $length (1..$longest) {
        for (my $i = 0; ($i + $length) < @symbols; $i++) {
            my $link = join($;, @symbols[$i..$i + $length - 1]);
            $self->increment_seen($link, $symbols[$i + $length]);
        }
    }
}


sub spew {
    my Algorithm::MarkovChain::Base $self = shift;
    my %args = @_;

    local $; = $self->{seperator};

    my $longest_sequence = $self->longest_sequence()
      or croak "don't appear to be seeded";

    my $length   = $args{length} || 30;
    my $subchain = $args{longest_subchain} || $length;

    my @fin; # final chain
    my @sub; # current sub-chain
    if ($args{complete} && ref $args{complete} eq 'ARRAY') {
        @sub = @{ $args{complete} };
    }

    while (@fin < $length) {
        if (@sub && (!$self->sequence_known($sub[-1]) || (@sub > $subchain))) { # we've gone terminal
            push @fin, @sub;
            @sub = ();
            next if $args{force_length}; # ignore stop_at_terminal
            last if $args{stop_at_terminal};
        }

        unless (@sub) {
            if ($args{strict_start}) {
                our @starts;
                *starts = $self->{_start_states};
                @sub = $starts[rand $#starts];
            }
            else {

lib/Algorithm/MarkovChain/Base.pm  view on Meta::CPAN

        my %options = $self->get_options($start);
        for my $word (keys %options) {
            $cprob += $options{$word};
            if ($cprob >= $target) {
                push @sub, $word;
                last;
            }
        }
    }

    $#fin = $length
      if $args{force_length};

    @fin = map { $self->{_symbols}{$_} } @fin
      if $self->{_recover_symbols};

    return @fin;
}


sub increment_seen   { croak "virtual method call" }
sub get_options      { croak "virtual method call" }



( run in 0.654 second using v1.01-cache-2.11-cpan-65fba6d93b7 )