Lua实现马尔可夫链算法

马尔可夫链算法

我们第二个例子是马尔可夫链算法的实现,我们的程序以前 n(n=2)个单词串为基础随机产生一个文本串。

程序的第一部分读出原文,并且对没两个单词的前缀建立一个表,这个表给出了具有那些前缀的单词的一个顺序。建表完成后,这个程序利用这张表生成一个随机的文本。

在此文本中,每个单词都跟随着它的的前两个单词,这两个单词在文本中有相同的概率。这样,我们就产生了一个非常随机,但并不完全随机的文本。例如,当应用这个程序的输出结果会出现“构造器也可以通过表构造器,那么一下几行的插入语对于整个文件来说,不是来存储每个功能的内容,而是来展示它的结构。”如果你想在队列里找到最大元素并返回最大值,接着显示提示和运行代码。下面的单词是保留单词,不能用在度和弧度之间转换。

我们编写一个函数用来将两个单词中间加上空个连接起来:

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
发布了268 篇原创文章 · 获赞 153 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_39885372/article/details/104352383