DFA極小化演算法,矩陣掃瞄實現,編譯原理

2022-09-13 08:48:07 字數 2580 閱讀 8121

看了一下網上的方法基本上是使用「集合的分割」實現的極小化,剛好我們老師使用的是矩陣掃瞄,因此自己乾脆使用j**a來實現。我直接封裝了乙個dfa的類,目前只寫了「矩陣掃瞄」的極小化,有時間的話自己也會把「集合分割」的演算法加上。下面就拿網上找到的例子做乙個使用矩陣掃瞄的基本步驟。

關鍵步驟:

去除無用狀態

合併等價狀態

例子:第一步:

畫乙個矩陣,可以是下面這樣的。因為(a,c)和(c,a)一樣,也就是說這是乙個對角陣,所以只需要使用下三角(上三角)即可:

第二步去除對角線,以-1作為去除的標記

第三步終態和非終態是不能合併的,因此需要把終態和非終態去掉。由dfa知道,非終態集為,終態集為,在下三角中把(e,a),(e,b),(e,c),(e,d)去掉。這一步我使用1做為標記,因為在j**a裡面int型預設為0,所以這樣做可以避免初始化的時候賦值。

注意:在程式中除了對角線使用-1,其餘我都使用1和0作為標記,1表示不可合併,0為可合併。

下面是去掉後的結果:

第四步開始做下三角的掃瞄,只需要掃瞄空白(程式中標記為0)的地方即可,當然在程式中迴圈掃瞄的時候,還是需要遍歷下三角的。

第一遍:

b,af(b,a) = b f(a,a) = b (解釋:這既是跳轉函式,b輸入a跳到b狀態,a輸入a也跳轉到b狀態。因為b和b是同乙個狀態,所以保留b,a)

f(b,b) = d f(a,b) = c (d,c狀態未知,保留)

c,af(c,a) = b f(a,a) = b

f(c,b) = c f(a,b) = c

c,bf(c,a) = b f(b,a) = b

f(c,b) = c f(b,b) = d

d,af(d,a) = b f(a,a) = b

f(d,b) = e f(a,b) = c (解釋:(e,c)已經被標記上1,所以(d,a)也要被標記為1)

d,bf(d,a) = b f(b,a) = b

f(d,b) = e f(b,b) = d (同(d,a))

d,cf(d,a) = b f(c,a) = b

f(d,b) = e f(c,b) = c

第一遍掃瞄後的結果如下:

注意:因為在上一次的基礎上,下三角的狀態已經發生了變化,所以需要進行第二次掃瞄。如果第二次又發生變化,那麼就需要第三次掃瞄。直至狀態不在改變,這時候就是最小化的最終結果。

第二遍:

b,af(b,a) = b f(a,a) = b

f(b,b) = d f(a,b) = c (因為(d,c) == 1,所以(b,a) = 1)

c,af(c,a) = b f(a,a) = b

f(c,b) = c f(a,b) = c

c,bf(c,a) = b f(b,a) = b

f(c,b) = c f(b,b) = d

本次掃瞄結果:

下三角狀態發生改變,進行第三遍掃瞄:

第三遍:

c,af(c,a) = b f(a,a) = b

f(c,b) = c f(a,b) = c

這一遍後,下三角的狀態沒有發生改變,不需要在進行第四遍掃瞄。這說明掃瞄已經結束了,而最終結果便是上一次掃瞄的結果:

從圖中可以看出,(c,a)處留空,說明a,c是可合併的狀態,其他狀態不可以合併

**結果:**可合併的狀態為

需要說明的是,掃瞄的步驟中,我每一步的跳轉都寫出來了,這只是為了更好的理解和闡述,同時說明了在程式中實現的過程。但是在實際的手動掃瞄時,很多重複的步驟是可以省略的。

/**

* 採用矩陣掃瞄法

* @return 成功:下三角矩陣,失敗:null

*/public

int[

]matrixscan()

//去掉終態

for(

int i =

1; i < matrix.length; i++)}

else}}

// 最後的掃瞄

// 區域性內部類

class

scanmatrix

// 注意max和min不應該相等

// 既不能是對角線上的1

if(matrix[max]

[min]==1

&& max != min)}}

}}}}

}new

scanmatrix()

.scan()

;return matrix;

}

測試資料:

a:0,b:0,c:0,d:0,e:1

a,bb,c,b,d,b,c,b,e,b,c

結果:

點選跳轉

執行結果肯定是和分析的結果一樣,但是在編寫的時候難免會有疏漏的地方,敬請指正!

Hopcroft最小化演算法化簡DFA

我們將乙個正規表示式通過myt演算法轉化成了乙個不確定有限自動機 nfa 又千辛萬苦用子集構造演算法整合掉多餘的狀態,生成了乙個確定有限自動機 dfa 然後發現狀態還是太多了,並不是最精簡的 狀態最少的。為了讓計算機更快地執行,只好我們再出馬給他整乙個演算法,來化簡dfa,直到狀態數最少。這個演算法...

面試演算法題 尋找矩陣的極小值

給定乙個 n n 的矩陣,矩陣中包含 n n 個 互不相同 的整數。定義極小值 如果乙個數的值比與它相鄰的所有數字的值都小,則這個數值就被稱為極小值。乙個數的相鄰數字是指其上下左右四個方向相鄰的四個數字,另外注意,處於邊界或角落的數的相鄰數字可能少於四個。要求在 o nlogn 的時間複雜度之內找出...

NMF演算法 非負矩陣分解演算法 python實現

nmf演算法 非負矩陣分解演算法。目標 將乙個大矩陣分解成兩個稍小的矩陣 利用矩陣的乘法 要求 待分解矩陣不能有負值。因為負值對於資料是無效的。假定有乙個元資料矩陣v,目標是將其分解成兩個非負矩陣w和h相乘的形式。v w h 這邊需要注意一些維度也就是角標,我就會直接寫了 其中,w稱為權重係數矩陣,...