LUA教程完整示例马尔可夫链算法-40

function prefix (w1, w2)
    return w1 .. ' ' .. w2
end

我们用NOWORD(即\n)表示文件的结尾并且初始化前缀单词,例如,下面的文本:

the more we try the more we do

初始化构造的表为:

{
    ["\n \n"]     = {"the"}, 
    ["\n the"]    = {"more"}, 
    ["the more"]  = {"we", "we"}, 
    ["more we"]   = {"try", "do"}, 
    ["we try"]    = {"the"}, 
    ["try the"]   = {"more"}, 
    ["we do"]     = {"\n"}, 
}

我们使用全局变量statetab来保存这个表,下面我们完成一个插入函数用来在这个statetab中插入新的单词。

function insert (index, value)
    if not statetab[index] then
       statetab[index] = {value}
    else
       table.insert(statetab[index], value)
    end
end

这个函数中首先检查指定的前缀是否存在,如果不存在则创建一个新的并赋上新值。如果已经存在则调用table.insert将新值插入到列表尾部。

我们使用两个变量w1和w2来保存最后读入的两个单词的值,对于每一个前缀,我们保存紧跟其后的单词的列表。例如上面例子中初始化构造的表。

初始化表之后,下面来看看如何生成一个MAXGEN(=1000)个单词的文本。首先,重新初始化w1和w2,然后对于每一个前缀,在其next单词的列表中随机选择一个,打印此单词并更新w1和w2,完整的代码如下:

-- Markov Chain Program in Lua
function allwords ()
    local line = io.read() -- current line
    local pos = 1 -- current position in the line
    return function () -- iterator function
       while line do -- repeat while there are lines
           local s, e = string.find(line, "%w+", pos)
           if s then -- found a word?
              pos = e + 1 -- update next position
              return string.sub(line, s, e) -- return the word
           else
              line = io.read() -- word not found; try next line
              pos = 1 -- restart from first position
           end
       end
       return nil -- no more lines: end of traversal
    end
end
 
function prefix (w1, w2)
    return w1 .. ' ' .. w2
end
 
local statetab
 
function insert (index, value)
    if not statetab[index] then
       statetab[index] = {n=0}
    end
    table.insert(statetab[index], value)
end 
 
local N = 2
local MAXGEN = 10000
local NOWORD = "\n" 
 
-- build table
statetab = {}
local w1, w2 = NOWORD, NOWORD
for w in allwords() do
    insert(prefix(w1, w2), w)
    w1 = w2; w2 = w;
end
insert(prefix(w1, w2), NOWORD) 
 
-- generate text
w1 = NOWORD; w2 = NOWORD -- reinitialize
for i=1,MAXGEN do
    local list = statetab[prefix(w1, w2)]
    -- choose a random item from list
    local r = math.random(table.getn(list))
    local nextword = list[r]
    if nextword == NOWORD then return end
    io.write(nextword, " ")
    w1 = w2; w2 = nextword
end

发布日期:

所属分类: 易语言 标签: