编译原理,确定有穷自动机DFA最小化

来源:互联网 发布:纵队 知乎 编辑:程序博客网 时间:2024/05/16 17:04

输入DFA五元组,将其最小化。

实验算法:

1,  对于DFA的字母表M,把M划分成终态集和非终态集,令P=M

2,  对于P中的一个集合I,寻找I每一个元素K,找到K从边a对应的节点,加入集合I1,若I1P中某个集合的子集,跳至步骤3,若不是,步骤4.

3,  寻找P中下一个集合,执行步骤2,若所有集合均是子集,则步骤5.

4,  I1划分成P中某几个集合子集的形式,将I1划分后的集合加入P,并删除I。执行步骤3

5,  用P中的每一集合的第一个元素代替集合,形成新的DFA。

代码实现:

 

1、  依次按照定义,输入五元组G={MESfB},其中M是字母表,E是终态集,S是初态,f是函数,B是边集。

2、  对于字母表M,用最小化算法进行递归,直至结束。

3、  输出五元组。

编程环境:windows 86-64bite,python 3.5

 

源代码:

m=list(input('请输入字母表'))z=list(input('请输入终态集合'))b=list(input('请输入边集'))s=input('请输入初态')print('请输入f,以0结束')dfa=[]while True:    i=list(input())    if i==['0']:        break;    dfa.append(i)m1=[]for i in m:    m1=m1+[i]z1=[]for i in z:    z1=z1+[i]n=2m=set(m)z=set(z)m=m.difference(z)m=list(m)z=list(z)p=[]m=sorted(m)z=sorted(z)p.append(m)p.append(z)work=[]while True:    over=0    for ppp in range(5):        for kk in range(0,n):            c=b[kk]            for i in p:                            for  zb in i:                    for j in range(14):                        if zb==dfa[j][0]:                            if c==dfa[j][1]:                                work=work+[dfa[j][2]];                l=len(p)                                gg=set()                g=[];                for j in range(len(work)):                    for pii in range(l):                        if {work[j]}.issubset(set(p[pii])):                            work[j]=pii                su=0                                              for l in range(len(work)-1):                    if work[l]==work[l+1]:                        su=su+1                if su==len(work)-1:                    work=[]                    continue                if len(work)==1:                    work=[]                    continue                else:                    x1=[]                    l1=len(i)                    x1=x1+[i[0]]                    mengyan=0                    i.pop(0)                    conter=1                    for ii in range(1,l1):                        if work[0]==work[ii]:                            x1=x1+[i[ii-conter]]                            i.pop(ii-conter)                            conter=conter+1                            mengyan=mengyan+1                    p.append(x1);                    work=[]                    over=1    if over==0:        break;for i in p:    if len(i)>1:        for j in dfa:            for k in i:                if k==j[0]:                     j[0]=i[0]print(dfa)dfa1=[]for i in dfa:    if i not in dfa1:        dfa1.append(i)print('最终集合划分为: ',p)for i in p:    if len(i)>1:        while len(i)!=1:            i.pop();    print('字母表为:           ',m1)z2=[]for i in p:    if i[0] in z1:        z2=z2+[i[0]]print('终态集合为:        ',z2)print('初态为:               ',s)print('边集:                  ',b)print('f:                          ',dfa1)


样例测试:

输出最小化后的字母表和划分的集合:

0 0
原创粉丝点击