編譯原理中DFA最小化


關於編譯原理最小化的操作,專業術語請移步至:http://www.360doc.com/content/18/0601/21/11962419_758841916.shtml

這里只是記錄一下個人的理解,以備復習使用

 

DFA最小化的操作步驟:

1.將DFA未最小化前的狀態划分為:終態和非終態

終態就是包含了NFA終點結點的狀態集合,如下圖的NFA,狀態10為NFA的終點,所以在DFA的狀態集合中,包含了10這個狀態的集合就是DFA的終態,那么,不包含的就是非終態了

值得一提的是,在DFA划分非終態和終態時,有可能得到的非終態是空集(仔細想想,此時意味着所有的DFA的狀態集合都包含了NFA的終點(如下圖的10)),反之,終態不可能為空集,因為NFA的終點一定會包含在某個DFA的狀態集合中。

子集構造的過程如下:(關於子集構造的描述也可以移步至:http://www.360doc.com/content/18/0601/21/11962419_758841916.shtml

得到的DFA圖如下:(雙重圈表示終態,單層表示非終態,對照上面所說的,是不是包含了10的都是被歸類為終態集合?)

 

 

但是,上面划分的終態和非終態只是一個初步的划分,可能在終態(或者非終態)集合內還可以繼續划分出多個狀態集合

首先看定義:
在DFA中,兩個狀態等價的條件是:
一致性條件:狀態s和t必須同時為終態或者非終態 (什么意思?就是意味着終態和非終態里的狀態集合不可能再被划分為相同的狀態了,所以第一步划分終態和非終態可以理解為粗略的划分)
蔓延性條件:對於所有輸入符號,狀態s和狀態t必須轉換到等價的狀態里 。(這該怎么理解呢?請看第二個表)

比如我想知道第二個表中的狀態集合[2,3,4,5,7,10]和狀態集合[6,9,4,7,10,5] (也即是第二第三行的初始狀態集合)是不是屬於同一個狀態,這個蔓延性條件就是說[2,3,4,5,7,10]經過letter和digit轉換得到的[6,9,4,7,10,5] 和 [8,9,4,7,5,10] 與 [6,9,4,7,10,5]經過letter和digit轉換得到的[6,9,4,7,10,5] 和 [8,9,4,7,5,10]  是不是同屬於同一個狀態。(此時可以看出它們都屬於終態)。

 

emmm,感覺我自己表述不清,自己多看書和上面給出的那個連接,應該不難理解的。

 

接下來說一下我自己划分狀態集合的操作。

首先划分成終態和非終態,然后繼續在終態和非終態的內部看每個狀態之間是否屬於同一個狀態………………

還是以此圖為例:

在圖中可以看出終態集合為list = [ [2,3,4,5,7,10],[4,5,6,7,9,10],[4,5,7,8,9,10]] 一共三個集合,要繼續看這三個集合是否可以進一步細划

我的想法是遞歸操作,首先將上面的狀態集合的第一個子集取出來,並找出其相應的狀態(放入一個state1的List中),接着遍歷其他的子集,看是否和state1中的集合的狀態相同,是的話就放進state1這個List中,不是的話就放進state2這個狀態集合中。最后遍歷結束的結果是將[ [2,3,4,5,7,10],[4,5,6,7,9,10],[4,5,7,8,9,10]]這個集合划分成兩類,第一類state1是與第一個集合list[0] 狀態相同的 ,第二類state2是與第一個集合list[0] 狀態相不同的。

接下來,可以判斷state2是不是空,如果是空的話,就意味着list中的所有子集的狀態都是相同的,即state1,如果state2長度為1,也不用繼續判斷了,直接將list划分為state1和state2兩類了。

如果,state2的長度大於1,那么就得繼續對state2進行划分,操作步驟和上面划分list的一致,因此可以使用遞歸操作。

 

對於非終態,如果需要划分,操作和上面的一樣,最后遞歸划分結束后,得到的是dfa所有的狀態。

 

當然,這只是初步的想法,不知道可不可以,我覺上述想法的難點可能在,當狀態划分越來越多的時候,判斷兩個狀態是否屬於同一個狀態的工作可能會越來越麻煩?

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM