DFA确定化和最小化

从正规式开始

一、先将正规式转换成NFA

通过下面的对应法则将正规式转换成NFA

img

例如:

img

二、再将NFA转成DFA(子集法)

运用子集法的3个概念:
(1 )状态集的ε-闭包: 状态集I中的任何状态s经任意条ε弧而能到达的所有状态的集合,定义为状态集I的ε -闭包,表示为 ε − c l o s u r e ( ) ε -closure() εclosure()

(2)状态集的a弧转换: 状态集I中的任何状态s经过一条a弧而能到达的所有状态的集合,定义为状态集1的a弧转换,表示为move(l,a)。

(3)状态集的a弧转换的闭包a: l g = ε − c l o s u r e ( m o v e ( l , a ) ) lg= ε-closure(move(l,a)) lg=εclosure(move(l,a))

上面的正规式转换成NFA:

img

先从初态0开始求:

【因为每个状态通过一条ε弧到达自己本身,所以求得ε的闭包包含自己】

(1)求0的ε的闭包:经过任意条ε所能到达的状态,集合为{0,1,3,4,5,6,7,9}

(2)求0的a弧转换:1经过a弧到达2,4经过a弧到达4,其余没有经过一条a弧到达某个状态,所以集合为{2,4}
(3)求a弧转换的闭包:{2,4}分别经过任意条ε所能到达的状态,集合为{2,4,6,7,9}

(4)求0的b弧转换:5经过b到5,7经过b到8,,其余没有经过一条b弧到达某个状态,所以集合为{5,8}

(5)求b弧转换的闭包:{5,8}分别经过任意条ε所能到达的状态,集合为{5,6,7,8,9}
0的ε-闭包:{0,1,3,4,5,6,7,9}
0的a弧转换:{2,4}
0的a弧转换的ε-闭包:{2,4,6,7,9}
0的b弧转换:{5,8}
0的b弧转换的ε-闭包:{5,6,7,8,9}
现在列一个表格:
(1)表格的列数为输入字符的个数+1,此题为a,b两个输入字符,所以为3列。
(2)第一列第一行填写初态的ε-闭包(此题0的ε-闭包),第二列第一行填写初态的a弧转换的ε-闭包(此题0的a弧转换的ε-闭包),第三列第一行填写初态的b弧转换的ε-闭包(此题0的b弧转换的ε-闭包)…以此类推。
(3)第一列的第二行以下填入上一行第二列以后的没有出现过的状态集。(此题第一行第二列第三列都没有出现在第一列中,将他们填入第一列)

I I a I_a Ia I b I_b Ib
{0,1,3,4,5,6,7,9}{2,4,6,7,9}{5,6,7,8,9}
{2,4,6,7,9}
{5,6,7,8,9}

下图为填好的表:
【新的终态的判断方法就是包含原来终态的集合就为终态,例如此题原来终态为9,所以包含9的集合就为终态,[双圈代表终态];
新的初态就是包含原来初态的集合就为初态,例如此题原来初态为0,所以包含0的集合就为初态】

img

为表里的状态集重新标上号:

img

可以得到下面的图:

img

这个图是还不是最小化的DFA,还需要DFA最小化。但下面DFA最小化重新举例。

三、将DFA最小化

先了解几个概念:

1.多余状态:对于一个状态 S i S_i Si,若从开始状态出发,不可能到达改状态Si,则Si为多余(无用)状态。

2.死状态:对于一个状态Si,对于任意输入符号a,若转到它本身后,不可能从它到达终止状态,则称Si为死状态。

1,2都称为无关状态

3.等价状态:若Si为自动机的一个状态,我们把从Si出发能导出的所有符号串的集合记为L(Si)。
设有两个状态Si和Sj,若有 L ( S i ) = L ( S j ) L(Si)=L(Sj) LSi=LSj,则称Si和Sj是等价状态。

4.可区别状态:自动机中两个状态Si和Sj,如果它们不等价,则称它们可区别。

5.两个状态(Si和Sj)等价的判断条件:

(1)状态Si和Sj必须同时为终止状态或同时为非终止状态。即终止状态和非终止状态是可区别的。

(2)状态Si和Sj对于任意输入符a∈Σ,必须转到等价的状态里,否则Si和Sj是可区别的。

DFA的化简算法:对于DFA M=(S,Σ,f,S0,Z)
(1)首先将DFA的状态集进行初始化,分成Π=(Z,S-Z);
(2) 用下面的过程对Π构造新的划分Π new
for (Π中每个组G) do //每个组都是一个状态集
begin
把G划分成小组,G中的任意两个状态Si和Sj在同一组中,当且仅当对于Σ中任意输入符号a ,Si和Sj的a转换是到同一组中,move(Si,a) ∈Gi ,move(Sj,a) ∈Gi。这样,只要Si和Sj的a转换是到不同的组中,则说明Si和Sj是可区别的,可进行划分。在Π new中用刚完成的对G的划分代替原来的G。
end ; Π := Π new;
(3)重复执行(2),直到Π中每个状态集不能再划分(Π new= Π)为止;
(4)合并等价状态 ,在每个G中,取任意状态作为代表,删去其它状态;
(5)删去无关状态,从其它状态到无关状态的转换都成为无定义。
举例:

img

①首次划分: Π0=({2,3,4,5},{0,1})

②在G={2,3,4,5}中:f(2,a)=1,f(4,a)=0(转向终态集{0,1});f(3,a)=3,f(5,a)=5(转向非终态集{2,3,4,5}),故{2,4}和{3,5}是可区别的,得Π1=({2,4},{3,5},{0,1});

③在G={2,4}中,f(2,a)=1,f(4,a)=0(转向终态子集),而f(2,b)=3,f(4,b)=5(转向非终态子集{3,5}),所以不可区别,不再进行划分;

④考察G={3,5},f(3,a)=3,f(5,a)=5(转向非终态子集{3,5}),f(3,b)=2,f(5,b)=4(转向非终态子集{2,4}), 所以不可区别,不再进行划分;

⑤考察G={0,1},f(0,a)=f(1,a)=1(转向终态集{0,1}); f(0,b)=2,f(1,b)=4(转向非终态子集{2,4}),所以不可区别,不再进行划分;

⑦进一步进行考察,可以发现每个子集都不能再划分了;

⑧消去等价状态:{0,1}用0表示,{2,4}用2表示,{3,5}用3表示,如右图所示

⑨去掉无关状态,因DFA M’中没有无关状态,所以下图即为最后结果。

img

  • 73
    点赞
  • 285
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
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’中去掉它;删除从开始状态不可到达的状态;取消从任何其他状态到死状态的转换。 。。。。。。
当然,我可以为你提供一些关于用Python编写DFA最小化代码的建议。 首先,你需要确定你的DFA的状态转换表。状态转换表是一个二维数组,其中每一行代表DFA的一个状态,每一列代表DFA的一个输入符号。对于每个状态和符号组合,状态转换表中的相应单元格应包含一个新状态,该新状态是在DFA中从当前状态开始输入给定符号后转移到的状态。 一旦你有了状态转换表,你就可以开始实现DFA最小化算法。最小化DFA的基本思想是将等效状态合并为一个新状态。等效状态指的是,在DFA中具有相同输入和输入后的状态转换路径的状态。因此,最小化算法的主要目标是找到所有等效状态,并将它们合并为一个新状态,从而生成一个比输入DFA更小的等效DFA。 下面是一些实现该算法的步骤: 1. 构建一个等价类表,其中从初始状态开始,每个状态都分配到一个等价类。 2. 对于每个等价类,检查它是否可以分成更小的等价类。这是通过检查它们的转换矩阵中的输出来完成的。如果存在不相等的输出,则状态将分成更小的等价类。 3. 重复步骤2,直到不能再将任何等价类分成更小的等价类为止。 下面是一些Python代码示例,帮助你实现上述步骤: # Step 1: build an equivalence class table def build_equivalence_class_table(dfa): equivalence_class_table = [] for i in range(dfa.num_states): equivalence_class_table.append([i]) return equivalence_class_table # Step 2: partition equivalent states into smaller sets def partition_equivalent_states(dfa, equivalence_class_table): partitions_made = True while partitions_made: partitions_made = False new_equivalence_class_table = [] for equivalence_class in equivalence_class_table: partitioned_states = split_equivalence_class(dfa, equivalence_class) if len(partitioned_states) > 1: partitions_made = True for partition in partitioned_states: new_equivalence_class_table.append(partition) equivalence_class_table = new_equivalence_class_table return equivalence_class_table # Split an equivalence class into smaller partitions based on output def split_equivalence_class(dfa, equivalence_class): partitions = [] partition_dict = {} for state in equivalence_class: output = dfa.state_dictionary[state].output if output in partition_dict: partition_dict[output].append(state) else: partition_dict[output] = [state] for output in partition_dict: partitions.append(partition_dict[output]) return partitions # Step 3: Minimize the DFA def minimize_dfa(dfa): equivalence_class_table = build_equivalence_class_table(dfa) equivalence_class_table = partition_equivalent_states(dfa, equivalence_class_table) minimized_state_dictionary = {} for i in range(len(equivalence_class_table)): new_state = State(len(minimized_state_dictionary)) minimized_state_dictionary[new_state.id] = new_state equivalence_class = equivalence_class_table[i] representative_state = equivalence_class[0] new_state.output = dfa.state_dictionary[representative_state].output new_state.accepted = dfa.state_dictionary[representative_state].accepted for input_symbol in dfa.input_symbols: next_state = dfa.get_next_state(representative_state, input_symbol) for j in range(len(equivalence_class_table)): if next_state in equivalence_class_table[j]: new_state.set_transition(input_symbol, minimized_state_dictionary[j].id) break minimized_dfa = DFA(minimized_state_dictionary) return minimized_dfa 以上是一个简单的Python实现,以帮助您开始编写DFA最小化代码。需要注意的是,该算法复杂度较高,对于大型DFA可能需要较长的处理时间。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值