編譯原理,確定有窮自動機DFA最小化

輸入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=2
m=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)


樣例測試:

輸出最小化後的字母表和劃分的集合:

發佈了47 篇原創文章 · 獲贊 54 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章