第十課 完整的Lua代碼示例

馬爾可夫鏈算法
根據原始文本中n個單詞的序列來確定後面的單詞,從而生成隨機的文本。
程序先讀取原始文本,並創建一個table。table的創建過程爲:以每兩個單詞 爲一個前綴,在table中創建一個列表,該列表記錄了原始文件中所有位於該前綴之後的單詞。當構建好這個table後,程序就利用它來生成隨機文本。結果中的每個單詞都來自於它在原始文本中的前綴,而具有相同前綴的單詞出現在結果中的概率也與原始文本一樣。最終會得到一串比較隨機的文本。
將兩個單詞以空格相連,編碼成一個前綴:
function prefix (w1, w2)
return w1 .. " " .. w2
end

使用字符串NOWORD("\n")來初始化一個前綴單詞,並且標記 文本的結尾。例如,對於原始文本:
the more we try the more we do
table內容:
{
["\n" "\n"] = {"the"},
["\n the"] = {"more"},
["the more"] = {"we", "we"},
["more we"] = {"try", "do"},
["we try"] = {"the"},
["try the"] = {"more"},
["we do"] = {"\n"},
}
程序將這個table保存在變量statetab中。若要 向此table中的某個前綴列表插入一個新 單詞,可以使用以下函數:
function insert (index, value)
local list = statetab[index]
if list == nil then
statetab[index] = {value} --沒有就新加
else
list[#list + 1] = value --有就在列表末尾增加一個
end
end
輔助函數:
function allwords ()
local line = io.read()
local pos = 1
return function () --迭代器函數
while line do
local s, e = string.find(line, "%w+", pos)
if s then
pos = e + 1
return string.sub(line, s ,e)
else
line = io.read()
pos = 1
end
end
return nil
end
end

主程序:
local N = 2
local MAXGEN = 10000
local NOWORD = "\n"

--構建table
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)

--生成文本
w1 = NOWORD; w2 = NOWORD
for i = 1, MAXGEN do
local list = statetab[prefix(w1, w2)]
--從列表中選擇一個 隨機項
local r = math.random(#list)
local nextword = list[r]
if nextword == NOWORD then return end
io.write(nextword, " ")
w1 = w2; w2 = nextword
end

輸入:
i am a pretty boy and i have a beautiful pig
i love my pig forever and i hope her happiness as long as her life
if you also have a cherished person i hope you can stay with her as long as possible
可能的輸出:
i am a pretty boy and i hope her happiness as long as possible











發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章