这是我参与更文挑战的第4天,活动详情查看: 更文挑战
定理
在有穷自动机的理论里,有这样的定理:
设L为一个由不确定的有穷自动机接受的集合,则存在一个接受L的确定的有穷自动机。
算法
介绍一种算法称为子集法,可以将NFA转换为等价的DFA
先定义状态集合I的两个运算
状态集合I的ε-闭包(ε-closure(I)):
定义为一个状态集,是状态集I中的任何状态S经过任意条ε弧而能到达的状态的集合。
显然,状态集合I中的任何元素都属于ε-closure(I)
状态集合I的a弧转换(move(I,a)):
定义为一个状态集J,其中J是所有可从I中的某一状态经过一条a弧而到达的状态的全体。
举例
- 初始化子集族C为空[],用表格表示
子集 | 是否被标记 |
---|---|
- 计算ε-closure(0),令 T0 = ε-closure(0) = {0,1,2,4,7},将T0加入C中,T0未被标记。
子集 | 是否被标记 |
---|---|
T0 = {0,1,2,4,7} | 0 |
- 标记T0, 令T1 = ε-closure(move(T0,a)) = {1,2,3,4,6,7,8},将T1加入C中,T1未被标记。
令T2 = ε-closure(move(T0,b)) = {1,2,4,5,6,7},将T2加入C中,T2未被标记。
子集 | 是否被标记 |
---|---|
T0 = {0,1,2,4,7} | 1 |
T1 = {1,2,3,4,6,7,8} | 0 |
T2 = {1,2,4,5,6,7} | 0 |
- 标记T1, 令T3 = ε-closure(move(T1,a)) = {1,2,3,4,6,7,8},即T1,T1已经在C中
令T3 = ε-closure(move(T1,b)) = {1,2,4,5,6,7},将T3加入C中,T3 未被标记。
子集 | 是否被标记 |
---|---|
T0 = {0,1,2,4,7} | 1 |
T1 = {1,2,3,4,6,7,8} | 1 |
T2 = {1,2,4,5,6,7} | 0 |
T3 = {1,2,4,5,6,7,9} | 0 |
- 标记T2, 令T4 = ε-closure(move(T2,a)) = {1,2,3,4,6,7,8},即T1,T1已经在C中
令T4 = ε-closure(move(T2,b)) = {1,2,4,5,6,7},即T2,T2已经在C中
子集 | 是否被标记 |
---|---|
T0 = {0,1,2,4,7} | 1 |
T1 = {1,2,3,4,6,7,8} | 1 |
T2 = {1,2,4,5,6,7} | 1 |
T3 = {1,2,4,5,6,7,9} | 0 |
- 标记T3, 令T4 = ε-closure(move(T3,a)) = {1,2,3,4,6,7,8},即T1,T1已经在C中
令T4 = ε-closure(move(T3,b)) = {1,2,4,5,6,7,10},将T4加入C中,T4 未被标记。
子集 | 是否被标记 |
---|---|
T0 = {0,1,2,4,7} | 1 |
T1 = {1,2,3,4,6,7,8} | 1 |
T2 = {1,2,4,5,6,7} | 1 |
T3 = {1,2,4,5,6,7,9} | 1 |
T4 = {1,2,4,5,6,7,10} | 0 |
- 标记T4, 令T4 = ε-closure(move(T4,a)) = {1,2,3,4,6,7,8},即T1,T1已经在C中
令T4 = ε-closure(move(T4,b)) = {1,2,4,5,6,7},即T2,T2已经在C中
子集 | 是否被标记 |
---|---|
T0 = {0,1,2,4,7} | 1 |
T1 = {1,2,3,4,6,7,8} | 1 |
T2 = {1,2,4,5,6,7} | 1 |
T3 = {1,2,4,5,6,7,9} | 1 |
T4 = {1,2,4,5,6,7,10} | 1 |
子集族C中所有子集都已标记,算法结束。 一共构造了5个子集
T0 = {0,1,2,4,7}
T1 = {1,2,3,4,6,7,8}
T2 = {1,2,4,5,6,7}
T3 = {1,2,4,5,6,7,9}
T4 = {1,2,4,5,6,7,10}
那么图3.6的 NFA N 构造的 DFA M 如下:
(1) S = {[T0],[T1],[T2],[T3],[T4]}
(2) ∑ = {a,b}
(3)
D([T0],a)=[T1]
D([T0],b)=[T2]
D([T1],a)=[T1]
D([T1],b)=[T3]
D([T2],a)=[T1]
D([T2],b)=[T2]
D([T3],a)=[T1]
D([T3],b)=[T4]
D([T4],a)=[T1]
D([T4],b)=[T2]
(4) S0=[T0]
(5) ST=[T4]
为便于书写,不妨将[T0],[T1],[T2],[T3],[T4]重新命名,
用0、1、2、3、4分别表示,
该 DFA M的状态转换图如图3.8所示
总结
子集法简单来说就是通过ε-closure(0)加入子集族C中的第一个子集。
对子集族C中的子集进行遍历。
对每一个未被标记的子集Ti,先标记Ti,然后对Ti的每一个输入字符i进行ε-closure(move(Ti,i))运算。
若运算产生新的子集,则将新的子集加入子集族C中。
若子集族C中的所有自己都被标记,算法结束。