Algorithm-MarkovChain
view release on metacpan or search on metacpan
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
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 )