Skip to content

Commit

Permalink
Finished 'src/lua_tut/interlude_markov_chain.md'.
Browse files Browse the repository at this point in the history
  • Loading branch information
gnu4cn committed Nov 24, 2023
1 parent f05b3e1 commit fbfe358
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 31 deletions.
52 changes: 52 additions & 0 deletions scripts/lua/markov.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,58 @@
#!/usr/bin/env lua
function prefix (w1, w2)
return w1 .. " " .. w2
end

local statetab = {}

function insert (prefix, value)
local list = statetab[prefix]
if list == nil then
statetab[prefix] = {value}
else
list[#list + 1] = value
end
end

function allwords ()
local line = io.read() -- 当前行
local pos = 1 -- 行中的当前位置
return function () -- 迭代器函数
while line do -- 在有行时重复
local w, e = string.match(line, "(%w+[,;.:]?)()", pos)
if w then -- 找了个单词?
pos = e -- 更新下一位置
return w -- 返回该单词
else
line = io.read() -- 未找到单词;尝试下一行
pos = 1
end
end
return nil
end
end

io.input("article")

local MAXGEN = 200
local NOWORD = "\n"

-- 构建出表
local w1, w2 = NOWORD, NOWORD
for nextword in allwords() do
insert(prefix(w1, w2), nextword)
w1 = w2; w2 = nextword
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
30 changes: 0 additions & 30 deletions scripts/lua/markov_chain.lua
Original file line number Diff line number Diff line change
@@ -1,33 +1,3 @@
#!/usr/bin/env lua

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

function insert (prefix, value)
local list = statetab[prefix]
if list == nil then
statetab[prefix] = {value}
else
list[#list + 1] = value
end
end


function allwords ()
local line = io.read() -- 当前行
local pos = 1 -- 行中的当前位置
return function () -- 迭代器函数
while line do -- 在有行时重复
local w, e = string.match(line, "(%w+[,;.:]?)()", pos)
if w then -- 找了个单词?
pos = e -- 更新下一位置
return w -- 返回该单词
else
line = io.read() -- 未找到单词;尝试下一行
pos = 1
end
end
return nil
end
end
31 changes: 30 additions & 1 deletion src/lua_tut/markov_chain_algorithm.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ end
建立了这个表后,程序会开始生成包含 `MAXGEN` 个单词的文本。首先,程序会重新初始化变量 `w1``w2`。随后,对于每个前缀,程序从有效的下一单词列表,随机选择一个下一单词,打印出该单词,并更新 `w1``w2`。下面的图 19.1,“马尔可夫程序的辅助定义” 和图 19.2,“马尔可夫程序” 给出了完整程序。


### 图 19.1,马科夫程序的辅助定义
### 图 19.1,马科夫程序的一些辅助定义

```lua
function prefix (w1, w2)
Expand Down Expand Up @@ -98,4 +98,33 @@ local statetab = {}

### 图 19.2,马科夫程序

```lua
local MAXGEN = 200
local NOWORD = "\n"

-- 构建出表
local w1, w2 = NOWORD, NOWORD
for nextword in allwords() do
insert(prefix(w1, w2), nextword)
w1 = w2; w2 = nextword
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
```


## 练习


练习 19.1:将马尔可夫链算法推广扩大,使其能够在选择下一个单词时,使用的任意大小的前导单词序列。

0 comments on commit fbfe358

Please sign in to comment.