DFA 最小化 Brzozowski 算法
我正在尝试实现 Brzozowski 算法来最小化我的 DFA 以下是相同的算法。
DFA = d(r(d(r(NFA))))
其中,r()
是 NFA 的反转,D()
将 NFA 转换为 DFA。
但我不明白r()
的含义是什么,在google上搜索也没有提供太多信息。
谁能解释一下NFA的r()
是什么。
任何其他可用的简单算法或 C++ 实现请让我知道链接。
I am trying to implement Brzozowski's algorithm for minimizing my DFA
Following is the algorithm for the same.
DFA = d(r(d(r(NFA))))
where r()
is reversal of NFA and D()
converts NFA to DFA.
But I do not understand what is the meaning of r()
searching on google also does not gives much information.
Can anybody please explain what is r()
of NFA.
Any other simple algorithm or C++ implementation available please let me know the link.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
Brzozowski 的算法
Brzozowski 的算法更清晰地写为:
其中
subset
表示子集构造(也称为 动力装置构造)。子集构造通过模拟 NFA 中每个等效状态集(由于 epsilon 转换)的所有转换来构建 DFA。反转 NFA 涉及以下步骤:
步骤 2-4 有效地交换了接受状态和起始状态的角色。
Brzozowski 的算法示例
以下是基于针对编译器的 Udacity 测验 最小化 DFA 的示例当然(步骤与 NFA 作为初始输入相同)。
初始 DFA:
此 DFA 接受类似
{"", "a", "aa", "aaa", "aaabba", "ba", "bab", "ababa", "ababb"}
并拒绝像{"b", "ab", "aab", "aabb", "bb", "bbb"}
这样的字符串。换句话说,它拒绝具有"b"
的字符串,除非它们也具有"ba"
子字符串。很明显,s1
-s3
和s2
-s4
是多余的。第 1 步:
反向 (DFA)
:步骤 2:
subset(reverse(DFA))
:运行子集构造以构建 DFA 表州表示每个唯一 epsilon 闭包的可能转换(
^
表示开始状态,$
表示接受状态): net/bC85S.png" rel="nofollow noreferrer">
步骤3:
reverse(subset(reverse(DFA)))
:反转DFA。消除公共前缀后,另一遍可以消除公共后缀。
步骤 4:
subset(reverse(subset(reverse(DFA))))
:再次运行子集构造以最小化国家期货协会。
参考文献:
Cooper 和 Torczon 的《工程编译器》,第二版。第 49 页描述了子集构造,第 75 页描述了 Brzozowski 算法。
Udacity 的编译器:理论与实践课程,第 3 课。
上图的 Graphviz 代码:
Brzozowski's algorithm
Brzozowski's algorithm is clearer written as:
where
subset
denotes subset construction (also known as powerset construction). Subset construction builds a DFA by simulating all transitions for each equivalent set of states (due to epsilon transitions) in the NFA.Reversing an NFA involves these steps:
Steps 2-4 effectively swaps the roles of accepting and starting states.
Brzozowski's algorithm example
Here's an example of minimizing a DFA based on a Udacity quiz for a compilers course (the steps are the same with an NFA as initial input).
Initial DFA:
This DFA accepts strings like
{"", "a", "aa", "aaa", "aaabba", "ba", "bab", "ababa", "ababb"}
and rejects strings like{"b", "ab", "aab", "aabb", "bb", "bbb"}
. In other words, it rejects strings that have a"b"
unless they also have a"ba"
substring. It's pretty obvious thats1
-s3
ands2
-s4
are redundant.Step 1:
reverse(DFA)
:Step 2:
subset(reverse(DFA))
:Run subset construction to build a table of DFA states to represent possible transitions from each unique epsilon closure (
^
denotes a start state,$
denotes an accepting state):Step 3:
reverse(subset(reverse(DFA)))
:Reverse the DFA. After eliminating common prefixes, another pass enables elimination of common suffixes.
Step 4:
subset(reverse(subset(reverse(DFA))))
:Run subset construction one more time to minimize the NFA.
References:
Engineering a Compiler by Cooper and Torczon, 2nd edition. Subset construction is described on page 49 and Brzozowski's algorithm is on page 75.
Udacity's Compilers: Theory and Practice course, lesson 3.
Graphviz code for above diagrams:
这是 OpenFst 的实现。
在这篇论文中,有一个图表(第15页)显示了以下结果:应用相反的操作。
帮助理解 FSM 操作的一种更简单的方法是使用 OpenFst 等库来创建和操作机器,然后使用 Graphviz 将结果可视化。
This is the implementation from OpenFst.
In this paper is a diagram (page 15) that show results of applying the reverse operation.
An easier way to help understand FSM operations is to use a library like OpenFst to create and manipulable the machines and then visualize the results using Graphviz.
在reverse.c的代码中(找到
这里,但现在已不存在)您会发现注释/* Create reversed Edges */
。所以我想说 r() 正在反转所有边的方向(另外还要确保反转的自动机具有明确定义的开始状态)。In the code for reverse.c (found
here, but now defunct) you'll find a comment/* Create reversed edges */
. So I'd say thatr()
is reversing the direction of all edges (plus making sure that the reversed automaton has a well defined start state).