非確定型有限自動機(NFA)

子集構造法(the subset construction)

要怎麼把一台會猜測的機器,變成一台永不猜測的機器?訣竅是「確定地」追蹤:NFA 在讀完目前為止的輸入後,「可能」所處的所有狀態之集合。那個集合是一個單一、定義明確的東西,而且更新方式可預測。子集構造法就是把每一個這樣的集合,變成一台全新 DFA 的一個狀態的配方——名稱由此而來:一個 DFA 狀態「就是」一組 NFA 狀態。

以下是這個機制的白話步驟。先讓 DFA 的起始狀態等於 NFA 起始狀態的 ε-封閉(一開始免費可達的狀態集合)。對一個 DFA 狀態 S(一組 NFA 狀態)與一個輸入符號 a,新的 DFA 轉移走到集合 T = 對 S 中所有 q 取 δ(q, a) 之聯集後,再取其 ε-封閉——也就是:把 S 中任一成員讀 a 能去的地方全部收集起來,再對 ε-移動取封閉。一個 DFA 狀態 S 是接受狀態,恰好當 S 含有 NFA 至少一個接受狀態時成立。只建造你從起始實際抵達的那些集合,你就得到一台辨識同一語言的 DFA。

這個構造法是 NFA 與 DFA 等價的引擎,它一次解釋了理論的每一部分:分岔變成「集合可能變大」,死路變成「那個狀態就是不在集合裡」,ε-移動則靠對每個集合取 ε-封閉來處理。代價是大小:新的 DFA 原則上可能對 NFA 狀態的每一個子集各有一個狀態,最多 2^n 個——這就是指數爆炸。實務上多數子集都不可達、根本不會被建出來,所以確定化後的 DFA 通常遠小於最壞情況。

把「以 ab 結尾」的 NFA 確定化(狀態 q0、q1、q2;q2 為接受)。起始 = {q0}。讀 a:{q0,q1};從 {q0} 讀 b:{q0}。從 {q0,q1} 讀 b:{q0,q2}(接受,因含 q2);讀 a:{q0,q1}。從 {q0,q2} 讀 a:{q0,q1};讀 b:{q0}。可達的子集 {q0}、{q0,q1}、{q0,q2} 就是 DFA 的三個狀態——遠少於原則上可能的 8 個子集。

每個 DFA 狀態都是一個可達的 NFA 狀態「集合」;只有可達的子集才會被建出來。

只建造從起始集合可達的子集,而非全部 2^n 個。2^n 是最壞情況,不是一般結果。

又称
powerset constructiondeterminization子集建構法冪集構造法確定化