我要实现的是从具有数字的表中返回具有可变顺序的马尔可夫链作为表。马尔可夫链表的长度应与输入表的长度相同。
下面是我的代码(其对代码的修改:https://gist.github.com/weakish/f722e3035d441c0c1f032664b7b52127)。 “ N”是马尔科夫顺序,“ MAXGEN”是马尔科夫链的长度,“输入”输入字符串。它将markov链作为列表输出,但目前仅在达到MAXGEN的情况下。没有人知道如果“ nextword == NOWORD”时如何选择一个新的随机值,以便每次创建马尔可夫链时都能达到MAXGEN长度?
math.randomseed(os.time()- os.clock() * 1000);
local N = 2;
local MAXGEN = 8;
;
local function allwords();
local line = "1 1 1 1 0 0 1 0 1 0 1 0 1 1 0 0 1 0 0 1 0 1 0 0 0 1 1 0 1 0 1 1 0 1 0 1";
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);
end;
return nil;
end;
end;
end;
;
local function prefix(words);
local prefix_sequence = '';
for _, w in pairs(words) do;
prefix_sequence = prefix_sequence .. w .. " ";
end;
return prefix_sequence;
end;
;
local statetab = {};
;
local function insert(index, value);
local list = statetab[index];
if list == nil then;
statetab[index] = {value};
else;
list[#list+1] = value;
end;
end;
;
local NOWORD = "n";
;
-- build table;
local function init_words ();
local prefix_words = {};
local i = 1;
while i <= N do;
prefix_words[i] = NOWORD;
i = i + 1;
end;
return prefix_words;
end;
;
local prefix_words = init_words();
;
for w in allwords() do;
insert(prefix(prefix_words), w);
table.remove(prefix_words, 1);
table.insert(prefix_words, w);
end;
insert(prefix(prefix_words), NOWORD);
;
prefix_words = init_words();
;
;
-- generate text;
;
rl = {};
for i = 1, MAXGEN + N do;
local list = statetab[prefix(prefix_words)];
;
-- choose random item from list;
local r = math.random(#list);
local nextword = list[r];
if nextword == NOWORD then return end;
table.insert(rl, nextword);
table.remove(prefix_words, 1);
table.insert(prefix_words, nextword);
end;
for i = 1, #rl do;
rl[i] = tonumber(rl[(i)+N]);
end;
print (table.unpack(rl));
我还发现了这个python示例,它看起来非常优雅,如果我设法将其移植到lua,它可能是一个更好的解决方案: https://eli.thegreenplace.net/2018/elegant-python-code-for-a-markov-chain-text-generator/