词法分析(6)---DFA的化简

 

通过NFA转化而成的DFA不一定是最简的,也就是说,有多余的状态可以被删除,对于每一个正规定义,我们一定可以得到一个唯一的最简的DFA

我们回顾一下Move函数,DFA的move函数:

move : (state, symbol) -> S

注意,这里(state, symbol)表示的是一个集合,这里规范的数学表达应该是:

move : { (state, symbol) | 所有属于DFA的state和symbol } -> S 或者

move : S × Σ -> S

假如一个DFA的move函数不是全函数,那么必须引入死状态。假如某个DFA的move函数是全函数,那么每个状态在所有input symbol下都有出边,比如:

 

这个DFA每个状态都可以接受所有的input symbol,这里是a,b。而下面的DFA:

 

先不要看红色部分,那么这个DFA的状态c,d,它们无法通过input symbol b 进入下一个状态,我们可以加上红色的部分,把这个move函数,转化成为一个全函数,并且,经过转化操作之后,新的DFA与原DFA等价。这个红色部分标识的状态,被叫做死状态

死状态:

假如出现DFA的move函数不是全函数,我们可以引入一个死状态S(仅仅引入一个方可),这个状态包括所有input symbol对自身的转换,所有的其他状态假如不接受某个input symbol a,那么,我们建立这个状态到S且input symbol为 a 的边。

状态的区别:

假如一个状态s,通过input string w,可以转换到某个状态,而某个状态t,通过w,转化到了一个与s通过w转化到的状态不同的状态,那么我们就可以通过w来区别状态s,t,如果这样的w不存在,那么s,t这2个状态是无法区别的。

每个接受状态都可以通过ε和非接受状态进行区别。

化简算法,极小化DFA的思想:

极小化DFA算法,它把状态分成一些不相交的子集,每一个子集中的所有状态都是不可区别的,而不同子集中的每个状态两两都是可区别的,最后我们把每个子集中的所有状态合成一个状态。

1) 划分状态集

首先把所有状态划分成为2个集合,一个集合是接受状态的集合,一个集合是非接受状态的集合,他们通过ε来区别。然后看每个集合中的状态时候还可以区别,例如一个集合通过input symbol a,转换后得到的状态落入当前划分的不同集合,那么说明通过input symbol a,是可以区别这个集合中的状态的(这里要强调的是,对于一个而不是多个input symbol,假如转换到的状态落入不同的划分中那么这些状态就是可以区别的)。我们假定有一个状态集合{s1,s2},s1通过a到达状态集合t1,s2通过a到达状态集合t2,t1,t2分别是当前划分的状态集合,那么,集合{s1,s2}就可以分成2个集合{s1},{s2}

2) 构造最简的DFA

我们可以重复1)的步骤,最后得到一些子集合,我们从每个子集合中取一个状态,通过它们可以得到最简的DFA,但具体需要按一定规则去构建

极小化DFA状态数的算法:

Input : 一个DFA M,它的状态集是S,输入符号集合Σ,move : S × Σ -> S,开始状态为s0,接受状态的集合为F

Output : 一个DFA N,它和DFA M等价,并为最简

Method :

1) 初始化: 假如move函数不是全函数,那么加入死状态,构造划分X:把S分成2个子集合,包括接受状态集合F和非接受状态集合S-F(F集合的补集)

2) Xnew是一个划分

for( X 中的每个集合G ){

    G中状态每次通过Σ中的symbol转化到的状态如果属于X的不同子集,那么把集合G分成子集,每个symbol都可能划分G,划分之后,使用下一个symbol进行操作,一直到遍历完所有的input symbol

    更新Xnew,用G的划分代替G

}

3) 如果Xnew == X,那么定义 Xfinal = X,执行4),否则进行赋值操作 X = Xnew,进行2)

4) Xfinal中每个子集合中选择一个状态来代表这个状态集合,包含s0的状态集合,就是表示开始状态的集合。通过DFA M来构造DFA N,规则是这样的:假如某状态p通过某input symbol a,通过DFA M的move函数转到另外一个状态q,我们就用q所在的集合的代表状态来表示q,并把这个转换过程的边,input symbol,集合的代表状态,加入DFA N中。我们需要遍历DFA M,然后按规则构建DFA N。化简的DFA中,可能有多个接受状态。

5) 如果N中有死状态(终态不是死状态),去掉它,有开始状态无法到达的状态,也去掉它。注意,在DFA N中有可能出现死状态,也就是通过所有的input symbol都回到自己的状态,前面说过,添加一个死状态得到的新的DFA与原DFA等价,那么我们这里也自然可以删除它。

在真正的实现上面算法的时候,是灵活的,因为出于时间复杂度的考虑,可能并不需要完全照搬上面的算法,把握主要的思想是很重要的。

1) 每个input symbol都可能划分一次集合

2) 每个集合都中的状态被看成是不可区别的,即使在计算过程中某些集合中的状态是可以区别的

3) 一定要确保每个集合都无法在分

 

 
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 实验内容 每一个正规集都可以由一个状态数最少的DFA所识别,这个DFA是唯一的(不考虑同构的情况)。任意给定的一个DFA,根据以下算法设计一个C程序,将该DFA 化简为与之等价的最简DFA。 2. 实验设计分析 2.1 实验设计思路 根据实验指导书和书本上的相关知识,实现算法。 2.2 实验算法 (1)构造具有两个组的状态集合的初始划分I:接受状态组 F 和非接受状态组 Non-F。 (2)对I采用下面所述的过程来构造新的划分I-new. For I 中每个组G do Begin 当且仅当对任意输入符号a,状态s和读入a后转换到I的同一组中; /*最坏情况下,一个状态就可能成为一个组*/ 用所有新形成的小组集代替I-new中的G; end (3)如果I-new=I,令I-final=I,再执行第(4)步,否则令I=I=new,重复步骤(2)。 (4)在划分I-final的每个状态组中选一个状态作为该组的代表。这些代表构成了化简后的DFA M'状态。令s是一个代表状态,而且假设:在DFA M中,输入为a时有从s到t转换。令t所在组的代表是r,那么在M’中有一个从s到r的转换,标记为a。令包含s0的状态组的代表是M’的开始状态,并令M’的接受状态是那些属于F的状态所在组的代表。注意,I-final的每个组或者仅含F中的状态,或者不含F中的状态。 (5)如果M’含有死状态(即一个对所有输入符号都有刀自身的转换的非接受状态d),则从M’中去掉它;删除从开始状态不可到达的状态;取消从任何其他状态到死状态的转换。 。。。。。。
1. 实验内容 每一个正规集都可以由一个状态数最少的DFA所识别,这个DFA是唯一的(不考虑同构的情况)。任意给定的一个DFA,根据以下算法设计一个C程序,将该DFA 化简为与之等价的最简DFA。 2. 实验设计分析 2.1 实验设计思路 根据实验指导书和书本上的相关知识,实现算法。 2.2 实验算法 (1)构造具有两个组的状态集合的初始划分I:接受状态组 F 和非接受状态组 Non-F。 (2)对I采用下面所述的过程来构造新的划分I-new. For I 中每个组G do Begin 当且仅当对任意输入符号a,状态s和读入a后转换到I的同一组中; /*最坏情况下,一个状态就可能成为一个组*/ 用所有新形成的小组集代替I-new中的G; end (3)如果I-new=I,令I-final=I,再执行第(4)步,否则令I=I=new,重复步骤(2)。 (4)在划分I-final的每个状态组中选一个状态作为该组的代表。这些代表构成了化简后的DFA M'状态。令s是一个代表状态,而且假设:在DFA M中,输入为a时有从s到t转换。令t所在组的代表是r,那么在M’中有一个从s到r的转换,标记为a。令包含s0的状态组的代表是M’的开始状态,并令M’的接受状态是那些属于F的状态所在组的代表。注意,I-final的每个组或者仅含F中的状态,或者不含F中的状态。 (5)如果M’含有死状态(即一个对所有输入符号都有刀自身的转换的非接受状态d),则从M’中去掉它;删除从开始状态不可到达的状态;取消从任何其他状态到死状态的转换。 。。。。。。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值