编译原理 --- NFA(非确定有限自动机)和DFA(确定有限自动机)之间的转换以及DFA的化简

2023-11-04

第一部分 --- 证明NFA能够转换为DFA

 

1.So是NFA的初态集合,F是NFA的终态集合

2.通过上面的第一个转换,我们就使得NFA具有了和DFA一样的唯一初态

3.通过上面的第二个转换 --- 不断引入中间状态,直到将字拆分为字符 --- 此时我们就成功的将NFA中输入以字作为判断依据的方式转换为了DFA中以字符作为判断条件的方式

 

 

 

1.以 I 状态集中的某一个状态作为起点,经过一条标志为a的弧后能够到达的所有的状态组成的集合就是 J 集合(PS:除了只经过一条标志为a的弧外,也可以是经过多条标志为空的弧以及一条标志为a的弧,这两种方式是等价的!)

将上面求得的J集合做空集闭包(医婆塞洛 - closure())后得到的新状态集合就是Ia状态集合

1.如果计算出的是空集的话,我们也要求这个空集的空集闭包,并求得到的I状态的Ia和Ib (结果都是空集)

2.这个计算一定能够停止下来,因为这个状态机是有限状态机,子集数是有限的,一定能够计算完并停下来

3.第一次输入的的状态集中的 X 状态是我们在调整NFA时的第一步中插入的唯一初态 X

计算步骤:

1.将只有X状态的状态集进行闭包运算,并求取求得的 I 集合的 Ia和Ib(上面这个状态图中只有a和b,所以只有Ia和Ib,如果有更多的字符话就添加更多的列)

2.计算完后首先看第一列的所有集合包不包含Ia集合,不包含的话直接将Ia集合作为新的I结合放到第一列的下一行继续求其Ia和Ib,求完后重复第2步 ; 如果包含Ia的话就往后检视Ib,处理步骤一样 , 如果在处理完Ib后(处理完最后一个字符后)上一行还有集合没有进行检视的话就返回没被检视的集合,继续按顺序检视。

 既不是初态也不是终态的状态集就是状态图中的中间态

1.根据NFA求出对应的状态转换矩阵,然后将这个状态转换矩阵化简,并根据化简后的状态转换矩阵画出状态图,这个状态图就是和NFA等价的DFA的状态图。

1.在实现一个确定有限自动机时,我们使用的数据结构是二维数组,如果确定有限自动机涉及到的状态越少(字符是固定的),我们创建的二维数组越小

那么问题来了 --- 给定一个确定有限自动机A,我们能否找到一个涉及到的状态数比A少,但是又和A等价的确定有限自动机B呢?

这就是DFA的化简问题


第二部分 --- DFA的化简问题

之所以能够对有限自动机进行化简是因为在其状态图中,存在一些状态识别字的能力是一样的,遇到这种情况时我们可以只保留其中一个状态,这就是有限自动机的化简

1.如果两个状态之间是等价关系的话,那么我们可以将这两个状态合并为一个状态

2.两个状态等价:从一个状态A出发识别出某个字后并在某个终态,如果从状态B出发能够识别出一样的字后也是在终态停止的话(可以停在不同的终态),则称这两个状态等价

上面这一题的答案是B

1.对于状态等价而言,必须是任意给定一个字,从两个状态出发识别出这个字后都在终态停止才叫两个状态等价

2.而对于状态可区分,则是存在一个字,当一个状态出发识别出这个字后停止,而另一个状态在识别出后仍为停止,则称这两个状态可区分

1.将所有等价的状态划分到一个集合中,就这样不停的划分知道整个状态集的所有状态都属于某个集合为止

2.然后选择每个集合中的一个代表状态组成新的状态集,其它的状态都删除掉,此时得到的状态集就是化简后的自动机具有的状态集了

 

1.这一题的答案是 B ,选出B的依据就是选项下面的那两个原则:终态在识别了一波塞洛(空字符)后依然回到终态,而非终态在识别了一波塞洛(空字符)后依然回到非终态,符合状态可区分定义

2. 关于终态,来到终态后我们就会将识别到的字进行输出

终态加 * 的作用就是将识别到的字回退一个字符后再返回

我们也可以从终态出发去识别字,但是一般从终态出发都会会到终态本身,比如

上面这个终态3在识别到字符A后就会回到它本身并将字符a输出 

1. 这个Ia集合的本质其实就是I集合中的所有状态在识别了a字符后能够到达的所有状态组成的集合

1.现行Π中的两个不同子集这句话就表明了这两个状态子集是可区分的,也就是说存在一个字符使得一个状态子集中的元素识别后到达终态,而另一个状态子集中的元素无法到达终态

2.在上面这个推理的基础上我们可以直接省略中间状态t1和t2,转换为s1在读入aα后到达终态,而s2在读入aα后无法到达终态,此时就可以证明存在一个字使得s1和s2能够被区分(是的,除了存在字符以为,还可以是存在一个字)

 

2.如果得到的Ia是包含在现行Π中的某一个子集中的话,就不会出现可区分的情况,只会有状态等价的情况

3.如果得到的Ia不包含在现行Π中的某一个集合的话,我们开始对Ia进行拆解,首先Ia中的每一个状态元素一定属于现行Π中的某一个集合,属于相同集合的状态元素划分为一组,设总共划分了n组

4.划分了n组之后我们再去I集合中进行状态划分,首相将能够通过识别a到达3中划分的第一组的状态元素划分为1组,然后是通过识别a能到达第二组的划分为一组....,直到n组都分完之后 i 集合就完成了划分

1.第一步是划分为终态和非终态

2.第二步求第一个子集的Ia,接着将Ia进行划分,划分后对I进行划分,增加现有Π的子集

3.增加之后再对新的集合求Ia,Ib....,求完一个集合后再求下一个集合,不停的求下去直到现有Π中的子集不能够再增加为止

 

1.化简后第三个子集中有多个状态,此时我们需要在这个子集中取一个代表,我们要做的操作就是选一个状态作为代表,然后将子集中剩下的所有状态发出的弧由代表状态发出,接收的弧由代表状态接收(代表状态自身接收和发出的弧不发生改变)

2.做完第一步操作之后再将除代表状态外的所有状态都删除掉,这样就完成了子集的取代表操作

DFA到DFA这个操作是在对DFA进行化简

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

编译原理 --- NFA(非确定有限自动机)和DFA(确定有限自动机)之间的转换以及DFA的化简 的相关文章

  • G1 GC 单个、非常长的年轻 GC 发生且 ParallelGCThreads=1

    I set ParallelGCThreads 1并使用G1 GC 所有其他JVM设置为默认设置 我跑PageRank在 Spark 1 5 1 上 有两个 EC2 节点 每个节点有 100 GB 堆 我的堆使用情况图如下 红色区域 年轻代
  • JVM 内存类型

    我正在做一个监控项目 我们有监控软件正在运行并从服务器重新收集指标 一切工作正常 但我们需要一些有关 JVM 内存使用情况详细信息 我们有一些具有不同内存类型的列 我们需要知道这些是什么 Heap Non Heap Usage Peak C
  • 增加堆大小后无法启动 Glassfish

    我想增加 Glassfish 的堆大小 为此 我知道我可以达到 4GB java Xmx4000M version java version 1 6 0 26 Java TM SE Runtime Environment build 1 6
  • 如果只有完全限定名称,如何获取 java 类的二进制名称?

    反射类和方法以及类加载器等需要使用所谓的 二进制 类名称 问题是 如果只有完全限定名称 即在源代码中使用的名称 如何获得二进制名称 例如 package frege public static class RT public static
  • 显示JVM中当前运行的所有线程组和线程

    所以我的任务是显示所有线程组以及当前在 JVM 中运行的属于这些组的所有线程 输出时应首先显示线程组 然后在下面显示该组中的所有线程 这是针对所有线程组完成的 目前 我的代码将仅显示每个线程组 然后显示每个线程 但我不确定如何达到我所描述的
  • Jprofile可以连接到docker中运行的JVM

    我是 JProfiler 的新手 我最近遇到了一个问题 我的Java应用程序在docker中运行 这意味着JVM在docker中运行 但我的jprofile安装在主机上 我知道 jprofiler 必须连接到 JVM 那么 jprofile
  • JVM HotSpot 上的 Java 异常计数器

    我想知道是否可以在不更改应用程序代码的情况下记录 JVM 级别上发生的每个异常 我所说的每个异常是指捕获和未捕获的异常 我想稍后分析这些日志并按异常类型 类 对它们进行分组 并简单地按类型对异常进行计数 我正在使用热点 也许有更明智的理由这
  • 热点 JVM 字节码解释器是跟踪 JIT 吗?

    这个问题几乎说明了一切 我一直在寻找答案 甚至通过 VM 规范 但我没有明确说明 No 不过 还有一些其他 JVM 具有跟踪 JIT HotPath http HotPath GoogleCode Com and Maxine http L
  • Java 中的引用变量里面有什么?

    我们知道对象引用变量保存表示访问对象的方式的位 它不保存对象本身 但保存诸如指针或地址之类的东西 我正在阅读 Head First Java 第 2 版 一书 书中写道 第 3 章第 54 页 在 Java 中我们并不真正知道什么是 在引用
  • Oracle 的商业 Hotspot JVM 相对于 OpenJDK 有哪些性能优势?

    正如这个问题中所描述的 OpenJDK 与 Java HotspotVM https stackoverflow com q 44335605 1593077 Oracle 的商业 Hotspot JVM 本质上是 OpenJDK 加上一些
  • 启用JConsole远程监控是否会影响生产中的系统性能?

    Oracle Sun 说只要不在生产环境中本地运行就可以吗 http download oracle com javase 1 5 0 docs guide management jconsole html http download or
  • Java 接口合成方法生成,同时缩小返回类型

    我有 2 个接口和 2 个返回类型 interface interfaceA Publisher
  • Intellij Idea 使用什么 JVM 来启动?

    我是 Eclipse 用户 最近决定尝试 Intellij Idea 我的操作系统是 Ubuntu 12 使用 Eclipse 时 可以通过在 eclipse ini 中指定来轻松选择用于启动 Eclipse 的 JVM http wiki
  • 可以混合使用 JVM 语言吗?即:Groovy 和 Clojure

    我知道你可以轻松地混合groovy java clojure java 无论什么JvmLang java 这是否也意味着我也可以让 clojure 和 groovy 代码进行交互 如果我使用 Grails 或 jRoR 我也可以在该环境中使
  • 监控 Java 应用程序上的锁争用

    我正在尝试创建一个小基准 在 Groovy 中 以显示几个同步方法上的高线程争用 当监控自愿上下文切换时 应该会出现高争用 在 Linux 中 这可以通过 pidstat 来实现 程序如下 class Res private int n s
  • 当目标是属性时,@Throws 不起作用

    在看的同时这个问题 https stackoverflow com q 47737288 7366707 我注意到申请 Throws to a get or setuse site 没有影响 此外 唯一有效的目标 for Throws ar
  • 如何在Java中计算对象的数字年龄[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我想知道Java中对象的年龄 当我们使用new关键字时 Java中用户定义的对象被创建 但是什么时候它会被销毁 是跨越JVM的perm
  • 在进行堆转储后,如何在发生 OutOfMemoryError 时重新启动 JVM?

    我知道关于 XX HeapDumpOnOutOfMemoryError https stackoverflow com q 542979 260805JVM 参数 我也知道 XX OnOutOfMemoryError cmd args cm
  • 使用 javac 和 javax.tools.JavaCompiler 有什么区别?

    Maven 编译器插件文档states http maven apache org plugins maven compiler plugin 编译器插件用于编译项目的源代码 从 3 0 开始 默认编译器是 javax tools Java
  • 抛出 Java 异常时是否会生成堆栈跟踪?

    这是假设我们不调用 printstacktrace 方法 只是抛出和捕获 我们正在考虑这样做是为了解决一些性能瓶颈 不 堆栈跟踪是在构造异常对象时生成的 而不是在抛出异常对象时生成的 Throwable 构造函数调用 fillInStack

随机推荐

  • Python中pip,pip3,虚拟环境(venv)三者的关系,如何在pycharm中使用虚拟环境,以及安装依赖包所遇到的问题。

    目录 一 是什么是pip pip3 与虚拟环境 venv 二 三者之间的联系 三 在pycharm中设置虚拟环境 四 安装python依赖包的快捷方式 五 注意事项 六 感谢观看 点个赞或者关注吧 一 是什么是pip pip3 与虚拟环境
  • Spring系列之深入理解java注解及spring对注解的增强(预备知识)

    最近有个朋友去阿里面试 被面试官来了个灵魂拷问 注解是干什么的 一个注解可以使用多次么 如何使用 Inherited是做什么的 Target中的 TYPE PARAMETER和TYPE USER 用在什么地方 泛型中如何使用注解 注解定义可
  • Flutter实战三:列表及弹框小Demo的实现

    文章目录 1 程序入口 2 路由页面创建 3 主页面创建 4 主界面Home页 5 按钮点击事件 6 列表界面 7 最终效果预览 学习Flutter将近2周了 正好朋友有个Flutter的需求 帮忙做个Demo 感觉最近已经有点入门了 答应
  • 运维常见面试题

    1 NAT和PAT的区别 IP地址耗尽促成了CIDR的开发 但是CIDR开发的主要目的是为了有效的使用现有的INTERNET地址 而 同时根据RFC1631 IPNETWORKADDRESSTRANSLATOR 开发的NAT却可以在多重的I
  • [Codeforces] number theory (R1600) Part.10

    Codeforces number theory R1600 Part 10 题单 https codeforces com problemset page 1 tags number theory 2C1201 1600 1423K Lo
  • 在多个文件夹里寻找相同的csv,再合并到一个csv文件

    在这种情况下 你可以使用 Python 的 os 模块来遍历文件夹 再使用 pandas 库来读取 csv 文件并合并它们 下面是一个示例代码 import os import pandasas pd 存储所有 csv 文件的列表 csv
  • 使用异步I/O(AIO) 大大提高应用程序的性能

    Linux 中最常用的输入 输出 I O 模型是同步 I O 在这个模型中 当请求发出之后 应用程序就会阻塞 直到请求满足为止 这是很好的一种解决方案 因为同步I O调用应用程序在等待 I O 请求完成时不需要使用任何中央处理单元 CPU
  • SpringBoot整合 ActiveMQ快速入门 实现点对点推送

    ActiveMQ是一个高性能的消息服务 它已经实现JMS接口 Java消息服务 Java Message Service Java平台中关于面向消息中间件的接口 所以我们可以直接在 Java 中使用 使用场景 多项目解耦合 分布式事务 流量
  • 宝塔:MySQL无法启动解决方案/www/server/mysql/bin/mysqld: Shutdown complete

    宝塔 MySQL无法启动解决方案 www server mysql bin mysqld Shutdown complete MySQL版本5 5 故障现象 MySQL无法启动 报错信息如下 190228 9 19 43 ERROR Can
  • pyltp安装

    我们在做依存句法分析时候会用到这个包 直接pip install conda install可能会报错 今天就讲讲这块 需要的小伙伴跟着我操作哦 1 首先我们要搞清楚自己python的版本是多少 打开这个 输入python可以查找版本号 这
  • sqlserver分页存储过程

    分页存储过程 if OBJECT ID proc page P is not null drop proc proc page go create proc proc page tabName varchar 2000 fieldStr v
  • 媲美postman?这款国产测试工具你知道吗

    没有测试数据的用例就像一盘散沙 跑两步就跑不动了 没有测试数据 所谓的功能测试和性能测试全都是无米之炊 但我发现一个蛮诡异的事情 就是行业内很少会有人去强调测试数据的重要性 甚至市面上都没有人在做测试数据这门生意 至今测试er造测试数据还是
  • Python协程学习--爬取一本网络小说

    协程爬取 最近在学习Python爬虫 同时在公司同事的引导下接触到协程 开始学习使用协程编写异步爬虫 Python协程系列学习参考 https blog csdn net qq 27825451 article details 862182
  • Elasticsearch快速入门之狂薅官网系列之Aggregations-聚合(3)

    本文为翻译官网 Aggregations 部分但有一定改动之后的文章 官网地址 https www elastic co guide en elasticsearch reference 7 3 search aggregations ht
  • Android 5,kotlin循环for

    Unless required by applicable law or agreed to in writing software distributed under the License is distributed on an AS
  • LZW编解码算法原理及分析

    文章目录 数据压缩实验 三 一 LZW概述 二 LZW编解码原理 1 LZW编码 1 算法原理 2 算法流程 2 LZW解码 1 算法原理 2 算法流程 3 实验过程 1 数据结构分析 2 主函数 3 主要功能模块 4 实验结果 总结与分析
  • #ifndef 和#pragma once

    作用 为了避免同一个文件被include多次 C C 中有两种方式 一种是 ifndef方式 一种是 pragma once方式 在能够支持这两种方式的编译器上 二者并没有太大的区别 但是两者仍然还是有一些细微的区别 方式一 ifndef
  • 代码审计——BruteForce

    Low级别 源码 1 首先通过isset 函数判断是否接收到了GET型的Login的值 接收到了代表用户提交了数据 isset 函数 在实际开发中 isset 通常用于快速检查某个变量是否存在或为空 并且可以帮助避免一些未定义变量引起的错误
  • Vscode-Latex 报错 I found no \bibdata command

    问题描述 原本使用的是 bib文件引用文献 后来觉得不方便 不如写在文末 改用 bibitem 然后使用pdflatex gt bibtex gt pdflatex 2进行编译 接着报错 I found no bibdata command
  • 编译原理 --- NFA(非确定有限自动机)和DFA(确定有限自动机)之间的转换以及DFA的化简

    第一部分 证明NFA能够转换为DFA 1 So是NFA的初态集合 F是NFA的终态集合 2 通过上面的第一个转换 我们就使得NFA具有了和DFA一样的唯一初态 3 通过上面的第二个转换 不断引入中间状态 直到将字拆分为字符 此时我们就成功的