有人能比我简洁地向SO社区描述NFA到DFA的转换算法更亮吗? (最好是500字以内。)我见过的图表和讲座只会让我以为我曾经认识的东西感到困惑。我最有信心从状态图生成初始NFA转换表,但之后,我丢失了epsilons和子集中的DFA。
1)在转换(delta)表中,哪一列代表新的DFA状态?它是生成状态的第一列吗?
2)在下面我的例子的第{2,3}行中,{2,3}在状态图方面对NFA的意义是什么? (对不起,我必须在图片中思考。)我认为这将是DFA中“输入0的回送”吗?
3)从表格到DFA或识别结果DFA的接受状态时有任何简单的“经验法则”吗?
有限自治
delta | 0 | 1 |
=======+=======+========+
{1} |{1} |{2} |
{2} |{3} |{2,3} |
{3} |{2} |{2,4} |
{2,3} |{2,3} |{2,3,4} |
{2,4} |{3,4} |{2,3,4} |
{2,3,4}|{2,3,4}|{2,3,4} |
{3,4} |{2,4} |{2,4} |
编辑:以下是dot format中的上表,欢呼Regexident。
digraph dfa {
rankdir = LR;
size = "8,5"
/* node [shape = doublecircle]; "1";*/
node [shape = circle];
"1" -> "1" [ label = "0" ];
"1" -> "2" [ label = "1" ];
"2" -> "3" [ label = "0" ];
"2" -> "2_3" [ label = "1" ];
"3" -> "2" [ label = "0" ];
"3" -> "2_4" [ label = "1" ];
"2_3" -> "2_3" [ label = "0" ];
"2_3" -> "2_3_4" [ label = "1" ];
"2_4" -> "2_3" [ label = "0" ];
"2_4" -> "2_3_4" [ label = "1" ];
"2_3_4" -> "2_3_4" [ label = "0" ];
"2_3_4" -> "2_3_4" [ label = "1" ];
"3_4" -> "2_4" [ label = "0" ];
"3_4" -> "2_4" [ label = "1" ];
}
这里呈现的形式:
注意:该表缺乏有关州接受度的任何信息,因此图表也是如此。
答案 0 :(得分:12)
当您从NFA构建DFA时,您基本上可以找到NFA可以在一段时间内的那些状态集(如模拟NFA)。首先,从开始状态开始,然后找到可以通过epsilon过渡到达的所有状态。这组状态形成了生成的DFA的开始状态。然后,您将跟踪此状态集的传出转换。这些可能导致另一个NFA状态,因为您发现状态可以通过epsilon输入再次到达,并且您将获得另一组NFA状态,这将是新的DFA状态。您完成此过程直到完成。
关键是,生成的DFA状态将成为兼容的旧NFA状态的集合(关于epsilon转换)。这些集合也可能重叠,即没有错误。现在我可以回答你的问题:
1)第一列代表新的DFA状态。它显示了形成给定DFA状态的NFA状态集。
2)你的假设是正确的,它意味着在0输入时环回到状态{2,3}。
3)可以从此表中轻松构建DFA表,只需用字母命名状态即可。任何包含至少一个NFA接受状态的DFA状态也将成为DFA中的接受状态。
我希望我足够清楚。
答案 1 :(得分:4)
核心理念可能是要了解DFA是一种叠加在NFA上的机器。虽然NFA在节点数量方面或者与问题的关系方面更简单,但它的规则非常微妙和复杂(它进入正确的状态,无论哪个可能是)。就它包含的节点而言,dfa要复杂得多,但是规则非常简单,因为任何给定的输入都只有一个输出状态。
转型非常明确。 DFA中的每个州都是NFA中州的子集。 DFA的开始状态是仅包含NFA的开始状态的集合,DFA的接受状态是其所有状态,其具有NFA的接受状态作为元素。
DFA中的过渡是唯一棘手的一方。 NFA是非确定性的,因为它给定输入的输出状态是一组状态,但是DFA将相应NFA状态的集合作为其自己的状态,表示自动机可能 union 。
就实际实施而言,DFA的州人口基本上是NFA州的权力。 IE,2 ^(n)表示n个NFA状态。实际上它通常要小得多,但是没有通用的方法来预测它的大小,所以一些实用的NFA到DFA实现会在到达时动态生成DFA状态并缓存它们。一旦创建了一定数量的状态,就丢弃最近最少使用的状态,从而限制高速缓存的大小。
答案 2 :(得分:0)
假设输入NFA是(S,Q,q0,T,F),其中S是输入符号集,Q是状态集,q0是开始状态,T是过渡集,而F是一组接受状态。每个过渡都是一个三元组(q,s,r),其中q和r是状态,而s是长度为0或1的字符串。
对于任何有限字符串s,令D(s)为所有路径的集合,该状态可以从q0沿其路径一起过渡,其标签串联在一起成为s。
该算法需要做的是构造一个确定性自动机,其状态是Q的子集,这样对于任何字符串s,DFA都将处于状态D(s)。
如果是这种情况,则任何包含NFA接受状态的DFA状态都应为DFA的接受状态。
考虑空字符串,epsilon; D(“”)将是q0的ε闭包,即,仅在标有空字符串的转换之后,您才能从q0到达所有状态。我们称其为Set Q0。 (在您的示例中,D(“”)= {1}。)现在我们“探索”该状态,这意味着:对于每个输入符号a,您都可以弄清楚该符号在离开状态后的过渡位置。这样一来,您会发现DFA中需要包含更多状态。 (在您的示例中S = {0,1},因此这些状态将为D(“ 0”)= {1}和D(“ 1”)= {2}。但是D(“ 0”)与D {“”);所以它不是新的。因此,现在唯一被发现但尚未探索的状态就是D(“ 1”)。)继续探索状态,直到没有更多的状态被发现但尚未被探索为止。