From c484938b7831fdb5540b18820be107aa47304dea Mon Sep 17 00:00:00 2001 From: Giuseppe Bilotta Date: Sun, 29 Jul 2007 01:42:11 +0200 Subject: [PATCH] Maximum markov order is now an initialization parameter --- mark2.rb | 42 +++++++++++++++++------------------------- 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/mark2.rb b/mark2.rb index 3738ec5..a986627 100644 --- a/mark2.rb +++ b/mark2.rb @@ -83,32 +83,24 @@ class ChanceHash end class MarkovChainer - # Maximum depth - MAX_ORDER = 5 - # Word or nonword regexp: # can be used to scan a string splitting it into # words and nonwords. WNW = /\w+|\W/u - def initialize + attr_reader :max_order + def initialize(ord=5) # mkv[i] holds the chains of order i - @mkv = Array.new - - # Each chain is in the form - # [:array, :of, :symbols] => { - # :prev => ChanceHash, - # :next => ChanceHash - # } - # except for order 0, which is a simple ChanceHash - # itself - @mkv[0] = ChanceHash.new - MAX_ORDER.times { |i| - @mkv[i+1] = Hash.new { |hash, key| - hash[key] = {:prev => ChanceHash.new, :next => ChanceHash.new} - } + @max_order = ord+1 + @mkv = Array.new(@max_order) { |i| + if i==0 + ChanceHash.new + else + @mkv[i] = Hash.new { |hash, key| + hash[key] = {:prev => ChanceHash.new, :next => ChanceHash.new} + } + end } - end def add_one(sym) @@ -118,7 +110,7 @@ class MarkovChainer def add_before(array, prev) raise "Not enough words in new data" if array.empty? - raise "Too many words in new data" if array.size > MAX_ORDER + raise "Too many words in new data" if array.size > @max_order size = array.size h = @mkv[size][array.dup] h[:prev].increase(prev) @@ -126,14 +118,14 @@ class MarkovChainer def add_after(array, nxt) raise "Not enough words in new data" if array.empty? - raise "Too many words in new data" if array.size > MAX_ORDER + raise "Too many words in new data" if array.size > @max_order size = array.size h = @mkv[size][array.dup] h[:next].increase(nxt) end def add_multi(array) - raise "Too many words in new data" if array.size > MAX_ORDER + 1 + raise "Too many words in new data" if array.size > @max_order + 1 add_before(array.butfirst, array.first) add_after(array.butlast, array.last) end @@ -152,7 +144,7 @@ class MarkovChainer syms.push(nil) syms.size.times { |i| - ([MAX_ORDER, syms.size-i].min+1).times { |ord| + ([@max_order, syms.size-i].min+1).times { |ord| v = syms[i, ord+1] # puts "Learning #{v.inspect}" add(*v) @@ -175,7 +167,7 @@ class MarkovChainer end def raw_next(syms) - ar = syms.last([MAX_ORDER, syms.size].min) + ar = syms.last([@max_order, syms.size].min) ord = ar.size if ord == 0 @mkv[0].random @@ -194,7 +186,7 @@ class MarkovChainer end def raw_prev(syms) - ar = syms.first([MAX_ORDER, syms.size].min) + ar = syms.first([@max_order, syms.size].min) ord = ar.size if ord == 0 @mkv[0].random -- 2.32.0.93.g670b81a890