【问题标题】:NFA to DFA questionNFA 到 DFA 问题
【发布时间】:2011-01-02 13:47:27
【问题描述】:

首先,这不是要求算法将 NFA 转换为 DFA 的问题。

已知(并证明)一个 NFA 的等效 DFA 最多有 2n 个状态,尽管大多数时候它的状态数与 NFA 或多或少相同.

我如何预测 NFA 等效 DFA 将具有的状态数的估计值?哪种特定类型的 NFA 需要等效的 DFA 才能具有 2n 个状态?

我提出这个问题的原因是能够“发明”一些 NFA,这些 NFA 在不考虑最小化的情况下肯定会产生 2n - 1 个状态加上“死状态”。

【问题讨论】:

  • 我 5 年前上过这门课。举一个 NFA 的例子,好吗?
  • NFA 是一种状态机,对于给定的状态和给定的输入令牌,存在不止一种转换的可能性。因此,NFA 可能是您可以使用“a”从状态 1 到状态 2 或状态 3,或者具有自循环或 epsilon 转换(不需要输入令牌的转换)的状态。
  • 您的意思是如何在不实际生成 DFA 的情况下以编程方式预测 DFA 将具有的状态数?在我看来,任何预测状态数的算法本质上都等同于生成自动机本身的算法,因此预测状态数不会为您节省任何工作。但如果有人能以不同的方式告诉我,我会感到惊喜。我认为具有最大非确定性分支的 NFA 会产生最复杂的 DFA。

标签: computer-science finite-automata computation-theory


【解决方案1】:

进一步扩展 Jonathan Graehl 的出色回答。

A(N) 的每个状态0, 1, ..., N 添加一个标记为c 的自循环,即添加以下转换:
0 c-> 0
1 c-> 1
...
N c-> N

然后假设 c 从未触发,则 DFA 包含与 Jonathan 的 DFA 相同的 2^(N+1) 状态。但是,每当从状态{S,j,k,...,z} <> {S} 观察到c 时,我们就会到达状态{j,k,...,z}。因此,{S,0,...,N} 的所有子集都是可能的,除了空集并且 DFA 有2^(N+2)-1 状态,而A(N)N+2 状态。

【讨论】:

    【解决方案2】:

    作为 N 的函数,具有起始状态 S 和最终状态 N,这个 NFA A(N):

    S a-> S
    S b-> S
    S a-> 0 // NOTE: only "a" allows you to leave state S
    0 a-> 1
    0 b-> 1
    1 a-> 2
    1 b-> 2
    ...
    N-1 a-> N
    N-2 b-> N
    N
    

    很明显,它接受[ab]* 中倒数第N 个字母为a 的所有字符串。

    A(N) 的确定必须有效地记住前面的 N-1 个字母(你需要知道那个窗口中所有 a 的位置,这样当字符串意外结束时,你可以说是否有之前是a N 个字母)。

    我不确定这是否准确地达到了您想要的状态数,但至少在 2 倍以内 - {0,...,N} 的所有子集都是可能的,但您也总是在 S 中。这应该是 2^(N+1) 状态,但 A(N)N+2 状态。

    【讨论】:

      【解决方案3】:

      由于非确定性,状态数量激增,这是您问题的关键。

      如果您采用 NFA,其中每个转换都是唯一确定的,即确定性 NFA,那么它只不过是一个正常的 DFA。但是,一旦您有可能进行两次转换的状态,它就不同于 DFA。

      考虑转换算法,看看如果您有两个或多个具有相同标签的状态转换会发生什么。这就是您需要与状态集相对应的那些新状态的地方。

      所以问题归结为找出这些超集状态中有多少实际上是可以到达的。当然,您可以为此发明一种奇特的算法,但要获得正确的数字,只需运行正常的转换算法并删除无法到达的状态。

      对于具有 n 个状态的 NFA,其等效 DFA 具有 2^n 个状态,请考虑利用非确定性。第一个想法是将所有转换标记为相同,但是效果不太好。相反,请记住,您需要能够以某种方式到达所有状态子集,每个子​​集都带有一些标签。

      如果不计算起始状态,则可以进行以下构造:创建 n 个节点,并为 2^n 中的每个集合创建一个唯一标签,并在 NFA 中为每个节点添加一个带有此标签的转换该集。这为您提供了具有 n+1 个状态的 NFA(1 是起始状态),其中 DFA 需要 2^n+1 个状态。当然,一旦你想在最小化后有 2^n 个 DFA 状态,它就会变得更加棘手。

      【讨论】:

      • @Frank -- 是否有下限证明(链接?) -- 例如接受相同语言的最小 DFA 在 NFA 的 # 个州中呈指数增长的 NFA 家族?
      【解决方案4】:

      好的,从假设 n -> n 开始。 现在,对于从一个状态到 x 个其他状态的每个非确定性转换,将您的估计值乘以 x。这可能不准确,因为您可能会重复计算。但它应该给你一个上限。

      但是,唯一可靠的方法是构建相应的 DFA,然后计算状态(我认为)。

      最后,您可能可以简化一些 DFA(以及 NFA),但这是一个全新的故事......

      【讨论】:

      • 我不太相信这很有用。考虑具有状态 1、2 和 3 的 NFA,其中在令牌“a”上存在从 1 到 2 和 1 到 3 的转换。 2和3是最终的。由于合并,生成的 DFA 比 NFA 具有更少的状态和更少的转换。所以乘法似乎是朝着错误方向迈出的一步。
      • 我给了你一个粗略的上限,因为你可以设想一个 NFA,其中最坏的情况确实发生了。除此之外,您必须将 NFA 实际转换为 DFA,然后计算状态。这有点像说 - 我有一个包含 10 个 if 语句且没有递归或 for 循环的程序 - 有多少代码路径?好吧,可能只是一个代码路径,但是您必须针对最坏的情况进行射击,并且如果没有仔细检查,或者编译为汇编和计数跳转指令或您有什么,就无法确定有多少...
      • “n -> n”是什么意思?谢谢。
      • 糟糕的符号:“n 对应 /maps to n”。
      • 我想知道是否转换 NFA > R.E. > DFA 是可行的/有助于简化。回覆。 = 正则表达式
      猜你喜欢
      • 1970-01-01
      • 2010-11-23
      • 2019-10-18
      • 1970-01-01
      • 2014-10-23
      • 2011-08-16
      • 2013-01-28
      • 1970-01-01
      相关资源
      最近更新 更多