NFA(Non-deterministic Finite Automata)
不确定有限自动机
构造NFA分成两步:画出每一个小单元的NFA;将每一个小单元的NFA组合。
小单元的NFA
- 单个输入符号
a
a
a
- 连接运算
a
b
ab
ab
- 选择运算
a
∣
b
a|b
a∣b
添加两个状态(选择运算开始状态和结束状态),在开始状态引两个路径通过 ε \varepsilon ε分别到两个单输入符号的NFA,同时两个NFA都通过 ε \varepsilon ε到结束状态。
- 闭包运算
添加两个状态(闭包运算开始状态和结束状态),四条线:闭包运算开始状态到单元开始状态;单元结束状态到闭包运算结束状态;闭包运算开始状态到闭包运算结束状态;单元结束状态到单元开始状态。
( a ∣ b ) ∗ (a|b)* (a∣b)∗
( a b ) ∗ (ab)* (ab)∗
a ∗ a* a∗
组合
在组合时,每一个小单元的NFA的开始状态不变,结束状态和下一个单元的开始状态合并。
(
a
∣
b
)
∗
a
b
(a|b)*ab
(a∣b)∗ab
NFA转DFA(Deterministic Finite Automata)
两个概念
ε
\varepsilon
ε-
c
l
o
s
u
r
e
(
{
1
,
2
,
.
.
.
,
n
}
)
closure(\{1,2,...,n\})
closure({1,2,...,n}):状态集{1,2,…,n}的
ε
\varepsilon
ε闭包。
上式的含义为求1,2,…,n状态仅通过零个或多个
ε
\varepsilon
ε可以到达的所有状态组成的集合。
m
o
v
e
(
A
,
a
)
move(A,a)
move(A,a):状态转换集。
A中的所有状态通过a可以到达的所有状态组成的集合。
以 ( a ∣ b ) ∗ a b (a|b)*ab (a∣b)∗ab为例
- 标记A集合
A集合为开始状态(即0状态)的 ε \varepsilon ε闭包。
如img-7中,0状态通过 ε \varepsilon ε可以到达1状态,7状态;1状态通过 ε \varepsilon ε又可以到达2状态和4状态;再加上本身:故A={0, 1, 2, 4, 7}。 - 找出所有的输入字母
如 ( a ∣ b ) ∗ a b (a|b)*ab (a∣b)∗ab中,所有的输入字母为{a, b} - 根据输入字母寻找A集合的
ε
\varepsilon
ε闭包
如img-7中,A集合中遇到a能发生状态转变的只有2和7,转换到状态3和8,所以 m o v e ( A , a ) move(A,a) move(A,a)={3,8};
然后求 ε \varepsilon ε- c l o s u r e ( m o v e A , a ) closure(move{A,a}) closure(moveA,a),即 ε \varepsilon ε- c l o s u r e ( { 3 , 8 } ) closure(\{3,8\}) closure({3,8}),可以得到结果为{3, 8, 6, 1, 2, 4, 7}=B。
m o v e ( A , b ) move(A,b) move(A,b)={5},然后求 ε \varepsilon ε- c l o s u r e ( { 5 } ) closure(\{5\}) closure({5})={5, 6, 1, 2, 4, 7}=C。 - 根据输入字母寻找所有新产生的集合的
ε
\varepsilon
ε闭包
ε \varepsilon ε- c l o s u r e ( m o v e B , a ) closure(move{B,a}) closure(moveB,a)={1,2,3,4,6,7,8}=B
ε \varepsilon ε- c l o s u r e ( m o v e B , a ) closure(move{B,a}) closure(moveB,a)={1,2,4,5,6,7,9}=D
ε \varepsilon ε- c l o s u r e ( m o v e C , a ) closure(move{C,a}) closure(moveC,a)={1,2,3,4,6,7,8}=B
ε \varepsilon ε- c l o s u r e ( m o v e C , a ) closure(move{C,a}) closure(moveC,a)={1,2,4,5,6,7}=C
ε \varepsilon ε- c l o s u r e ( m o v e D , a ) closure(move{D,a}) closure(moveD,a)={1,2,3,4,6,7,8}=B
ε \varepsilon ε- c l o s u r e ( m o v e D , a ) closure(move{D,a}) closure(moveD,a)={1,2,4,5,6,7}=C
包含NFA结束状态的集合为DFA结束状态,在例子中D状态为结束状态;A状态为开始状态。 - 根据以上的计算结果画出DFA
DFA的化简
- 加入死状态
如果一个DFA的转换函数不是全函数,那么必须加入一个死状态 S d S_d Sd,死状态只有输入而没有输出。例如一个状态S对a没有转换,即move(S,a)= ∅ \varnothing ∅,则 ε \varepsilon ε- c l o s u r e ( m o v e ( S , a ) ) closure(move(S,a)) closure(move(S,a))= S d S_d Sd。 - 把状态集分为接受状态集和非接受状态集
接受状态集指包含NFA结束状态的集合;非接受状态集指不包含NFA结束状态的状态集。
例如,在例子中,可以把状态机划分为{A,B,C}和{D}。 - 合并不可区分状态
对上一个步骤中的每一个集合的进行划分。如果集合中只有一个元素,那就不必再划分,如{D};如果集合中有多个元素,则寻找哪一个元素经过所有输入字母的转换后可以产生非本集合的元素,则将其分离成一个新的集合,如果两个状态通过所有的输入字母都转换到该集合的相同元素,那么它们不必再分。 - 对于上一个步骤中产生的新划分,重复上一步骤,直至不可再分。
- 如果结果中有死状态,则去除死状态,把所有到死状态的转换都改为无定义。
栗子
其实可以把划分的过程看成是一个集合内部排异的过程。
栗子?:
首先根据接受和非接受划分为集合{A,B,C}和{D,E,F,G,H,I}
对于集合{A,B,C},A说我可以到B和C,C说我可以到B和C,B说我可以到B和D。A和C听了就不高兴了,我们两个不论怎么变都是到我们这个小集体里,你咋还跑出去了呢,我俩不和你好了。于是就分成了{A,C}和{B}。A和C又开始继续交流,但是他俩通过变换都跑到了{A,C}的外边,一起叛变,而且对于每一个输入符号,两人都是到同一个元素,只有这样,两人还是朋友,嗯,{A,C}成为一个集合。
对于集合{D,E,F,G,H,I},兄弟六人怎么变都还是在这兄弟六人内部,于是六个人是一个团结的集体。
所以,原来的9个状态,经过划分之后,就变成了3个状态。
栗子??:
再给一个栗子自己体会吧
化简之后: