【编译原理】DFA最小化算法

【编译原理】DFA最小化算法

DFA的定义

DFA是Determinant Finite Automata,确定性有穷自动机这个定义有几个关键点

  • 确定性,Determinant的,也就是说,对于一个串,只有一种可接受方法。(这等价于不存在符号相同的边。)

  • 有限,Finite,也就是说节点数量是有限的。

数学地来说:DFA是一个五元组,包括\((S,state,\Sigma,Mov,T)\):初始状态,状态,字符集,状态转移函数,结束状态。

对于OIer的快速入门:一个AC自动机/SAM就是一个DFA,一个\(state\)可以对应成图上的一个节点,\(\Sigma\)就是AC自动机/SAM的字符集,\(S\)就是AC自动机/SAM的开始节点,\(T\)就是接受节点,而\(Mov(A,b)=C\)就是查询\(A\)走一条字符为\(b\)的边到了哪个节点(\(C\)),如果没有这条边那么\((A,b)\)没有不在\(Mov\)函数的定义域。

本文不对DFA做过于严格的定义。

最小DFA定义

可接受字符串集合相同的DFA称为等价DFA,最小DFA的定义是所有等价DFA中节点最小的,可以证明节点最小的DFA只有一种。

状态(也就是DFA的某个节点)的可区分性

两个点不可区分记为\(A\sim B\)

\(A\sim B\)A和B不可区分当且仅当两个状态的所有出边都对应不可区分

所有出边对应不可区分当且仅当\(\not \exists c\in \Sigma , Mov(A,c)\not \sim Mov(B,c)\),即符号对应的出边到达的节点不可区分

迭代法求最小化DFA

初始情况,我们能确定,至少所有结束状态和其他节点(非结束状态)是不一样的。

算法的思路是不断寻找可区分的点,并且分裂,层次有点类似B算法求最小生成树。

  • 初始情况:\(\prod_0 = S_1,S_2\)\(S_1\)是所有结束状态,\(S_2\)是所有非结束状态

  • 迭代方法:假设本次为第\(n\)次迭代。

    • 枚举一个\(S_k\in \prod_{n-1}\)

    • 枚举所有\(c\in \Sigma\),得到一个集合\(Mov(S_k,c)=\{Mov(X,c):X\in S_k\}\)

      • 确认是否每个\(Mov(X,c)\)都有定义(有这条边),都有定义则通过
      • 确认是否存在\(S_t\in \prod_{n-1}\)\(Mov(S_k,c)\subseteq S_t\)(所有边都不可区分),存在\(S_t\)则通过
    • 若通过以上两种检查(说明\(S_k\)不可区分),则\(S_k\rightarrow \prod_n\)(加入这个集合)

    • 若没有通过以上两种检查,则将\(S_k\)不相交地划分成若干个极大集合\(T_1,T_2\dots T_m\)使得\(\forall i,\exist S_t\in \prod_{n-1},Mov(T_i,c)\subseteq S_t\),这里极大集合的意思是, \(\not \exist i\not = j, \textbf{ s.t. } Mov(T_i,c)\cup Mov(T_j,c) \subseteq S_t\)

      随后执行\(T_1,T_2\dots T_m \rightarrow \prod\)

    (人话:将\(S_k\)分裂成若干集合,使得集合内的点的所有出边在\(\prod_{n-1}\)意义下中不可区分,并且希望分裂出的集合数量最小)

复杂度分析

这个论文

(记得把后缀改成.pdf)

简单实现迭代可以做到\(O(m \log m)\)

指的一提的是,这个算法的发明者最终获得了图灵奖!

代码

代码到时候再说吧。

posted @ 2022-04-08 00:42  谁是鸽王  阅读(1165)  评论(0编辑  收藏  举报