广告:我的博客
每个NFA都有一个等价的DFA
证明思路(NFA转DFA的方法)
我们要证明NFA和DFA等价,因为DFA是NFA的一般化,所以NFA一定可以模拟DFA,因此我们需要做的是用DFA模拟NFA。因为NFA在当前状态读到一个字符后可以有多条路可以走,所以模拟该NFA的DFA将有 2k 2 k 个状态,每个状态都是NFA状态集的幂集的一个元素。具体操作在证明过程中。
证明
假设我们有一台NFA N=(Q,∑,δ,q0,F) N = ( Q , ∑ , δ , q 0 , F ) 识别语言 A A ,现在我们要构造一台DFA 识别语言 A A 。在完整构造之前,我们先假设 N N 没有。之后再考虑 epsilon−move e p s i l o n − m o v e 的情况。
- Q\'=P(Q) Q \' = P ( Q ) ,这个条件是理解这个构造的关键,如果理解了1和下面的3,那基本整个构造就理解了。如果不能理解,那可以先放下,先看后面具体的例子。
- 注意 M M 和中的字符表是一样的。
-
δ′(R,a)={ q∈Q∣ q∈δ(r,a), r∈R }
δ
′
(
R
,
a
)
=
{
q
∈
Q
∣
q
∈
δ
(
r
,
a
)
,
r
∈
R
}
,其中
R∈Q\'
R
∈
Q
\'
。我们知道,
R
R
是的一个状态,它也是
N
N
的一些状态的集合。当在状态
R
R
遇到字符时,那么我们要记录
N
N
中处于集合中的所有元素时,
N
N
向哪个状态转移。所以上述转移函数也可以写为
- q′0=q0 q 0 ′ = q 0 。
- F′={ R∈Q′∣ R包含N的一个接受状态} F ′ = { R ∈ Q ′ ∣ R 包 含 N 的 一 个 接 受 状 态 } 。这个条件表示如果 N N 有一条路走到接受状态,那么就接受该字符串。
现在我们开始考虑
ϵ−move
ϵ
−
m
o
v
e
:
想法依旧是上述想法:模拟(stimulate)。但是为了方面表示,我们需要引入额外的记号。对于
M
M
的一个状态,我们记
E(R)
E
(
R
)
为
R
R
的元素通过可以到达的状态和
R
R
本身的并集。也就是
推论
一个语言是正则的当且仅当有某个NFA可以识别它。
NFA转DFA例子
由图可知,
N2
N
2
有3个状态,所以要构造的等价DFA
D
D
的状态集为。确定了状态集之后,接下来我们要确定开始状态和接受状态集合。因为
N4
N
4
的开始状态为1,所以
D
D
的开始状态为,又有一个
ϵ−move
ϵ
−
m
o
v
e
由状态1到状态3,所以
E({ 1 })={ 1,3 }
E
(
{
1
}
)
=
{
1
,
3
}
。又
N2
N
2
的接受集合只有一个元素1,所以
N2
N
2
的状态集的幂集中包含1的集合都是
D
D
的接受状态,由此,的接受集合为
{ { 1 },{ 1,2 },{ 1,3 },{ 1,2,3 }
{
{
1
}
,
{
1
,
2
}
,
{
1
,
3
}
,
{
1
,
2
,
3
}
。最后我们确定转移函数(因为字符表是一样的,因此不需要理会),在这里,我们只分析几个状态的转移,其他的是一样的照葫芦画瓢。在
D
D
中:
1. 状态: 状态
{ 2 }
{
2
}
读到字符a向状态
{ 2,3 }
{
2
,
3
}
转移,这是因为在
N2
N
2
中,状态2读到字符a向状态2或3转移,并且状态2或3都没有箭头从
ϵ
ϵ
出发;状态
{ 2 }
{
2
}
读到字符b向状态
{ 3 }
{
3
}
转移,这是因为在
N2
N
2
中,状态2读到字符b只能向状态3转移,并且状态3没有箭头从
ϵ
ϵ
出发。
2. 状态
{ 1 }
{
1
}
: 状态
{ 1 }
{
1
}
读到字符a后向状态
∅
∅
转移,这是因为在
N2
N
2
中,状态1没有箭头读到字符a后向其他状态转移;状态
{ 1 }
{
1
}
读到字符b后向状态
{ 2 }
{
2
}
转移,相信到此原因已经不用解释了。
3. 状态
{ 3 }
{
3
}
: 状态
{ 3 }
{
3
}
读到字符a后向
{ 1,3 }
{
1
,
3
}
转移,这是因为在
N2
N
2
中,状态3在读到字符a后向状态1转移,并且在状态1有一个
ϵ
ϵ
箭头从状态1指向状态3;状态
{ 3 }
{
3
}
读到字符b后向
∅
∅
转移。
4. 状态
{ 1,2 }
{
1
,
2
}
: 状态
{ 1,2 }
{
1
,
2
}
读到字符a后向状态
{ 2,3 }
{
2
,
3
}
转移,这是因为在
N2
N
2
中,状态1读到字符a后,没有转移的状态,状态2读到a后向状态2或3转移,并且没有额外的
ϵ
ϵ
转移;状态
{ 1,2 }
{
1
,
2
}
读到字符b后向状态
{ 2,3 }
{
2
,
3
}
转移,此处原因不再过多解释。继续模拟其余4个状态(总共
23=8
2
3
=
8
个状态),将得到以下DFA:
但是上图并不是最简的DFA图,我们可以入度为0的节点(在DFA图中,节点即是状态,入度为0即没有箭头指向该节点)去掉,因为不可能有节点去到那个节点(开始节点入度至少为1),所以这类节点是对DFA没有贡献的。在上图中,状态
{ 1 }
{
1
}
和状态
{ 1,2 }
{
1
,
2
}
均属于没有贡献的状态,所以可以去掉它们,得到下图:
下篇文章将用NFA证明正则操作(并,连接,闭包)的封闭性。