automata - 如何为特定范围的二进制数绘制 DFA?
问题描述
我需要学习如何设计一个接受特定范围内的二进制字符串的 DFA。
一个问题指出,IP 地址中的每个八位字节由 8 位组成,它们每个代表一个从 0 到 255 的正整数,包括 0 到 255。然后我被要求绘制一个 DFA 来接受 119 到 231 范围内所有八位字节的二进制表示,在字母表 {0, 1} 上。它可以是任何给定的范围,但是解决这样的问题的步骤是什么?
解决方案
您有两种主要的方法:
- 枚举每个字符串,然后使用 DFA 最小化算法找到大小合理的解决方案。这仅在语言有限时才有效,例如您的示例。
- 从语言的已知属性进行概括,并直接构建您的 DFA。有时从 NFA 开始在概念上更容易,然后您可以通过算法将其转换为 DFA。
对于您的示例,让我们尝试两种方法。对于任何一种方法,我们都想看看字符串是什么样子的。
(119)10 = (01110111)2
(120)10 = (01111000)2
...
(230)10 = (11100110)2
(231)10 = (11100111)2
使用方法 1,您从具有 9 个状态、8 个转换的线性 DFA 开始。
start -0-> q1 -1-> q2 -1-> q3 -1-> q4 -0-> q5 -1-> q6 -1-> q7 -1-> [q8]
(q8 is an accepting state)
这接受字符串01110111
。现在,添加我们需要接受的内容01111000
:
start -0-> q1 -1-> q2 -1-> q3 -1-> q4 -0-> q5 -1-> q6 -1-> q7 -1-> [q8]
|
1
V
r5 -0-> r6 -0-> r7 -0-> [r8]
此 DFA 接受01110111
和01111000
。你可以继续这样做,你最终会得到一个非常复杂的类似 hydra 的 DFA,它对语言中的每个单词都有不同的接受状态。然后,您可以运行 DFA 最小化算法来缩小它。
使用方法 2,考虑语言中单词的结构。如果可能,将它们分类为具有相似结构的组。例如,任何以10
长度 8 开头的字符串都将被接受(这些是 128 到 191 之间的数字)。所以你可以用一个更简单的 DFA 来匹配所有这些:
start -1-> q1 -0-> q2 -0,1-> q3 (etc until [q8]).
像这样找到一些相似性类别将有助于减少您必须考虑的分支数量。
推荐阅读
- android - Android Widget 主题更改
- android - Branch.io 安装后延迟深度链接丢失数据
- python - 没有 AuthMiddlewareStack 如何在 Django 频道中获取登录用户?
- java - 在 Junit5 中模拟或测试接口
- typescript - 从引用到类的变量访问静态属性
- php - PHP - 从两个数组中删除两个重复数组
- python - 为什么我的 List 在不应该运行时比 Queue 运行得更快?
- azure - 使用 Github Actions 从 Azure Key Vault 获取 SSH 密钥
- java - 为什么 ParallelStream 不会在递归中使用所有 commonPool 的线程?
- java - 如何使用 Recycler View 的长按位置获取 SQLite 列值?