理解Hopcroft DFA最小化算法

news2024/11/22 18:19:04

问题引入

在构造编译器的Scanner时,常见的解决方法是使用自动机技术。从文法构造出的DFA的状态数过多会影响编译器的性能。DFA中有一些状态本质上是等价的,我们需要一种自动化算法用于最小化DFA。

算法介绍

常见的DFA最小化算法有三种,分别是Moore算法、Hopcroft算法和Brzozowski算法。
很多教材,包括我们学校使用的教材(龙书)中给出的方法都是Moore算法。

Hopcroft算法

话不多说,先上伪代码:
在这里插入图片描述

符号解释

先解释一下这里使用的一些数据结构

Partition

当前等价类集合。最早是两个等价类,分别是输入DFA中的接收状态集合和非接收状态集合。

NextP

在一次迭代之后更新之后的等价类集合。NextP的功能是暂存变化的等价类,这能起到一个同步更新划分的作用。

Worklist

这个比较有意思。它维护的是一个“可能会导致当前等价类需要进一步划分”的等价类列表。(请记住这个定义)举个例子,考虑等价类{A, B}和{C, D}。DFA中有边A->C和B->D,这时{C, D}就导致了{A, B}需要进一步划分成{A}、{B}。在每一轮迭代中,会从Worklist中选出一个等价类s,然后考察每个当前等价类(Partition)中的集合p,看s是否会导致p需要进一步划分。

细节解释

现在来分步看这段伪代码。
首先初始化了三个核心数据结构,这步比较好看懂。D即为DFA的状态集,DA即为DFA的接收状态集。

紧接着开始迭代。迭代的结束条件是Worklist不为空,迭代条件的设置也很有意思,Worklist是“可能会导致当前等价类需要进一步划分”的等价类列表,当这样的等价类不存在,那么自然就意味着当前等价类已经不需要进一步划分了,那么自然最小化的目标达成,算法结束。

在迭代的循环体内,首先从Worklist中挑出一个集合s,然后生成了一个状态集合Image。这里应该是叫“原像”。Image包含的状态就是能经过c字符变迁到s集合中任意一个状态的状态。
举个例子,s集合中有一个状态A,DFA中有边D->A@c,那么D就是Image中的一个状态。

紧接着,开始考察当前等价类(Partition)中的每一个等价类q,看它是否会因状态s而需要进一步划分。考察方式是计算q和Image的交集和差集,如果均不为空,那么代表发生了这样的情况:q中只有一部分状态经过c变迁会到达s集合中的状态(交集不为空),而另一部分则会到达其他状态(差集不为空),这与等价类的定义:等价类的任一对状态对某个输入字符c下的行为应该相同,即变迁到同一个等价类不符。因此我们把p划分为交集和差集,然后更新Parttion和NextP。

Q:为什么要从Partition中移除q呢?
A:这是因为每一轮迭代都会考虑所有字符。每个等价类对于不同的字符可能有不同的划分方式,为了避免冲突,一轮迭代中q被一个字符划分后,就移除,下一轮迭代再加进来,以考虑其他字符对它的划分。

Q:为什么对Worklist的更新因q是否在Worklist中而不同?
A:前面提到过,Worklist维护的是一个“可能会导致当前等价类需要进一步划分”的等价类列表。
1.如果某个q不在Worklist中了,就代表对所有的等价类,对所有的输入字符,都不会因为q而需要进一步划分。进一步地讲,就是说对于任意一个等价类,对于里面所有的状态在任意一个字符下,变迁得到的状态要么全在q中要么全不在q中。然而这时候q被划分了,这对其他等价类是可能有影响的,见下图:

假设q被分割成了q1和q2某个等价类s在任意一个输入字符下变迁得到的状态集合,在q中的分布可能出现以下四种情况:
如果出现了2、3、4情况,那么这个等价类s就不会因为q而需要进一步划分。
如果出现了第一种情况,那么这个等价类s会因为q而需要进一步划分!读者可以自行想象,这时候不管是把q1加进Worklist还是把q2加进Worklist,都会让s被同样地划分!
那么自然就加比较小的。

2.如果这个q还在Worklist中,那么自然要把q1和q2都加进来。这是直觉上就在这里插入图片描述
能理解的事情。

代码实现

坑,待填

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/479747.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

栈和队列的转换

在之前的博客当中我们已经学习了栈和队列。在本次的博客当中我们就来学习一下怎么将栈和队列进行相互转换。 栈和队列的相互转换其实是两道OJ题。如果在leetcode上面刷过题的小伙伴们可能早就见过这两种数据结构的相互转换。下面我们就来分别讲解一下这两道OJ题目的编写思路。 …

为生信写的Python简明教程 | 视频2

开源生信 Python教程 生信专用简明 Python 文字和视频教程 源码在:https://github.com/Tong-Chen/Bioinfo_course_python 目录 背景介绍 编程开篇为什么学习Python如何安装Python如何运行Python命令和脚本使用什么编辑器写Python脚本Python程序事例Python基本语法 数…

改进YOLOv8 | 即插即用篇 | CVPR2023最新注意力 | 《BiFormer:视觉变换器与双层路由注意力》

作为视觉变换器的核心构建模块,注意力是一种强大的工具,可以捕捉长程依赖关系。然而,这种强大的功能付出了代价:计算负担和内存占用巨大,因为需要在所有空间位置上计算成对的令牌交互。一系列的研究尝试通过引入手工制作和与内容无关的稀疏性来缓解这个问题,例如将注意力…

【技术分享】防止根据IP查域名,防止源站IP泄露

有的人设置了禁止 IP 访问网站,但是别人用 https://ip 的形式,会跳到你服务器所绑定的一个域名网站上 直接通过 https://IP, 访问网站,会出现“您的连接不是私密连接”,然后点高级,会出现“继续前往 IP”,…

81. read readline readlines 读取文件的三种方法

81. read readline readlines 读取文件的三种方法 文章目录 81. read readline readlines 读取文件的三种方法1. 读取文件的三种方法2. read方法3. readline方法4. readlines方法5. 代码总结5.1 read方法读取全部内容5.2 readline方法读取一行,返回字符串5.3 readli…

stable diffusion的使用

文章目录 1 文生图1.1 mountains and trees and gree1.2 three dogs1.3 cats1.4 three lovely cats1.5 beautiful girl1.6 机器猫1.7 卡通图像生成 1 文生图 1.1 mountains and trees and gree 1.2 three dogs 1.3 cats 1.4 three lovely cats 1.5 beautiful girl stable diff…

CRN Camera Radar Net for Accurate, Robust, Efficient 3D Perception

这是发表在ICLR2023 workshop on Scene Representations for Autonomous Driving上的文章,目前在nuScenes的cameraRadar的3D目标检测赛道上刷到了第一,非常值得一看 一、创新点和贡献 采用了一种两阶段的融合思路: 采用radar-assistant-vie…

【AI工具】bing chat 使用--三种模式+撰写功能

bing chat:三种模式撰写功能 以下为点击复制后粘贴的内容 Bing Chat提供三种对话模式可选择:创造力、平衡和精确。更多创造力(Creative):Bing Chat回答的内容将带有更多语气和情绪,更像一个真实的人类与用户对话。更多…

如何实现倾斜摄影三维模型数据裁剪和轻量化一体化处理?

如何实现倾斜摄影三维模型数据裁剪和轻量化一体化处理? 随着数字地球和数字城市的发展,倾斜摄影三维模型成为了重要的数据形式。然而,由于数据量大,处理难度大等问题,如何实现倾斜摄影三维模型数据裁剪和轻量化一体化处…

ChatGPT提示词工程(二):Iterative迭代

目录 一、说明二、安装环境三、Iterative第一次写Prompt第二次写Prompt第三次写Prompt第四次写Prompt第五次写Prompt 四、总结 一、说明 这是吴恩达 《ChatGPT Prompt Engineering for Developers》 的课程笔记系列。 本文是第三讲的内容:Iterative 课程主讲&#…

RabbitMQ 发布订阅模式,routing路由模式,topic模式

发布订阅模式 一个消息可以由多个消费者消费同一个消息 消费者1和2同时消费了该消息 举例 public static void main(String[] args) throws IOException, TimeoutException {//1 创建连接工厂ConnectionFactory connectionFactorynew ConnectionFactory();//2 设置rabbitmq …

机器学习与深度学习——通过knn算法分类鸢尾花数据集iris求出错误率并进行可视化

什么是knn算法? KNN算法是一种基于实例的机器学习算法,其全称为K-最近邻算法(K-Nearest Neighbors Algorithm)。它是一种简单但非常有效的分类和回归算法。 该算法的基本思想是:对于一个新的输入样本,通过…

Preftest测试

Preftest测试 Perftest 是一组基于uverbs编写的测试程序,是RDMA性能相关的micro-benchmark。可用于软硬件调优以及功能测试。 Perfest支持的测试 源码位置 linux-rdma/perftest: Infiniband Verbs Performance Tests (github.com) 安装 直接安装preftest sudo …

Flink作业任务的9种状态简单介绍

​ 当创建一个Flink任务后,该任务可能会经历多种状态。目前Flink给任务共定义了9种状态,包括:Created,Running,Finished,Cancelling,Canceled,Restarting,Failing&#x…

类加载器和双亲委派模型面试总结

类的生命周期和类加载的过程 在了解类加载器之前,我们先来了解一下一个类的生命周期和类加载的过程。 一个类完整的生命周期包括 加载、验证、准备、解析、初始化、使用和卸载,一共7个阶段。 类加载过程包括,加载、连接和初始化&#xff0…

腾讯云镜YunJing——Agent定时任务脚本分析

缘起 如果你有台腾讯云主机,会发现默认有个叫 YunJing 的进程。 把它kill掉后,发现一段时间又出现了 这是为什么捏? 分析定时任务配置文件 通过crontab定时任务目录, 会发现有个叫yunjing的配置文件。 */30 * * * * root /usr/local/qc…

PCIe物理层详细总结-PCIE专题知识(一)

目录 一、简介二、PCIe物理层结构及功能2.1 PCIe端对端连接方式2.2 PCIe组成2.2.1 逻辑层(Logic)1 发送逻辑2 接收逻辑 2.2.2 电气层(Electrical)1 物理层-电气(Physical Layer Electrical)2 数据传送----差分方式 2.2.3 PLP介绍 三、其他相关链接1、PCI总线及发展历程总结 一、…

ChatGPT 和 Elasticsearch:OpenAI 遇见私有数据(一)

作者:Jeff Vestal 结合 Elasticsearch 的搜索相关性和 OpenAI 的 ChatGPT 的问答功能来查询你的数据。 在此博客中,你将了解如何使用 Elasticsearch 将 ChatGPT 连接到专有数据存储,并为你的数据构建问答功能。 ChatGPT 和 Elasticsearch&…

【react从入门到精通】React JSX详解

文章目录 前言React技能树什么是JSXJSX的基本语法规则1.JSX必须有一个顶层元素2.JSX标签必须有一个结束标记,或者是自闭合的3.JSX中可以使用JavaScript表达式4.JSX中的样式和HTML中的样式有所不同5.JSX中的class属性必须写成className6.JSX中的style属性必须使用对象…

JavaWeb-HTML常用标签了解(一)

这里写目录标题 注释标签标题标签段落标签换行标签格式化标签图片标签超链接标签外部链接与内部链接 注释标签 <!-- 有注释 -->无注释ctrl / 快捷键可以快速进行注释/取消注释. 注意 注释不能传达负能量!!! 标题标签 有六个, 从 h1 - h6. 数字越大, 则字体越小. <h…