马尔科夫算法 awk 实现
之前一直看不懂马尔科夫算法的awk实现。最近学习了awk,基本上能看懂了。C++版的参见这里。
#!/bin/awk -f
#markov.awk: markov chain algorithm for 2-word perfixes
BEGIN { MAXGEN = 10000; NONWORD = "\n"; w1=w2=NONWORD }
{
for(i = 1; i <= NF; i++)
{
#read all words
statetab[w1,w2,++nsuffix[w1,w2] ] = $i
#print "IN",$i
w1 = w2
w2 = $i
}
}
END{
statetab[w1,w2,++nsuffix[w1,w2] ] = NONWORD #add tail
w1 = w2 = NONWORD
for( i = 0; i < MAXGEN; i++)
{
#generate
r = int(rand() * nsuffix[w1,w2]) + 1
#print "r: ",r
p = statetab[w1,w2,r]
if ( p == NONWORD )
exit
print p,
w1 = w2
w2 = p
}
}
Awk是一个模式—操作对的语言:输入总以一次一行的方式读入,每个读入行都拿来与程序里的模式做匹配,与此同时,对各个成功匹配执行有关动作。这里存在着两个特殊的模式,BEGIN和END,它们分别能在输入的第一行之前和最后一行之后匹配成功。动作是由花括号括起的一个语句块。在上面的 Aw k版本的马尔可夫程序里, BEGIN动作块对前缀和若干其他变量做初始化。随后的一个语句块没有模式部分,这是一种默认方式,意味着这个块将对每个输入行执行一次。Awk自动把每个读入的行分割成一些域 (由空白分隔的词),它们将分别成为$1到$NF。变量NF的值是域的个数。语句:
statetab[w1,w2,++nsuffix[w1,w2]] = $i
建立从前缀到后缀的映射。数组 nsuffix记录后缀个数,其元素 nsuffix[w1, w2]记录与前缀对应的后缀的个数。而后缀本身则被做为数组 statetab的元素,如 statetab [ w1,w2, 1],statetab[w1, w2, 2],等等。
make it simple, make it happen