自动机 学习笔记
OI 中所说的「自动机」一般都指「确定有限状态自动机
前置知识
- 基础图论
自动机入门
首先理解一下自动机是用来干什么的:自动机是一个对信号序列进行判定的数学模型。
这句话涉及到的名词比较多,逐一解释一下
自动机的工作原理和地图很类似。假设你在你家,然后你从你家到学校,按顺序经过了很多路口。每个路口都有岔路,而你在所有这些路口的选择就构成了一个序列。
例如,你的选择序列是「家门 -> 右拐 -> 萍水西街 -> 尚园街 -> 古墩路 -> 地铁站 -> 下宁桥
而我们如果找到一个选择序列,就可以在地图上比划出这个选择序列能不能去学校。比如,如果一个选择序列是「家门 -> 右拐 -> 萍水西街 -> 尚园街 -> 古墩路 -> 地铁站 -> 钱江路 -> 四号线站台 -> 联庄
也就是说,我们通过这个地图和一组目的地,将信号序列分成了三类,一类是无法识别的信号序列(例如「家门 -> ???
既然自动机是一个数学模型,那么显然不可能是一张地图。对地图进行抽象之后,可以简化为一个有向图。因此,自动机的结构就是一张有向图。
而自动机的工作方式和流程图类似,不同的是:自动机的每一个结点都是一个判定结点;自动机的结点只是一个单纯的状态而非任务;自动机的边可以接受多种字符(不局限于 T 或 F
例如,完成「判断一个二进制数是不是偶数」的自动机如下:
从起始结点开始,从高到低接受这个数的二进制序列,然后看最终停在哪里。如果最终停在红圈结点,则是偶数,否则不是。
如果需要判定一个有限的信号序列和另外一个信号序列的关系(例如另一个信号序列是不是某个信号序列的子序列
需要注意的是,自动机只是一个 数学模型,而 不是算法,也 不是数据结构。实现同一个自动机的方法有很多种,可能会有不一样的时空复杂度。
形式化定义
一个 确定有限状态自动机(DFA) 由以下五部分构成:
- 字符集(
该自动机只能输入这些字符。) , - 状态集合(
如果把一个 DFA 看成一张有向图,那么 DFA 中的状态就相当于图上的顶点。) 。 - 起始状态(
) , ,是一个特殊的状态。起始状态一般用 表示,为了避免混淆,本文中使用 。 - 接受状态集合(
) , ,是一组特殊的状态。 - 转移函数(
) , 是一个接受两个参数返回一个值的函数,其中第一个参数和返回值都是一个状态,第二个参数是字符集中的一个字符。如果把一个 DFA 看成一张有向图,那么 DFA 中的转移函数就相当于顶点间的边,而每条边上都有一个字符。
DFA 的作用就是识别字符串,一个自动机
当一个 DFA 读入一个字符串时,从初始状态起按照转移函数一个一个字符地转移。如果读入完一个字符串的所有字符后位于一个接受状态,那么我们称这个 DFA 接受 这个字符串,反之我们称这个 DFA 不接受 这个字符串。
如果一个状态
我们扩展定义转移函数
如,一个接受且仅接受字符串 "a", "ab", "aac" 的 DFA:
OI 中常用的自动机
字典树
大部分 OIer 接触到的第一个自动机,接受且仅接受指定的字符串集合中的元素。
转移函数就是 Trie 上的边,接受状态是将每个字符串插入到 Trie 时到达的那个状态。
KMP 自动机
KMP 算法 可以视作自动机,基于字符串
转移函数:
AC 自动机
AC 自动机 接受且仅接受以指定的字符串集合中的某个元素为后缀的字符串。也就是 Trie + KMP。
后缀自动机
后缀自动机 接受且仅接受指定字符串的后缀。
广义后缀自动机
广义后缀自动机 接受且仅接受指定的字符串集合中的某个元素的后缀。也就是 Trie + SAM。
广义 SAM 与 SAM 的关系就是 AC 自动机与 KMP 自动机的关系
回文自动机
回文自动机 比较特殊,它不能非常方便地定义为自动机。
如果需要定义的话,它接受且仅接受某个字符串的所有回文子串的 中心及右半部分。
「中心及右边部分」在奇回文串中就是字面意思,在偶回文串中定义为一个特殊字符加上右边部分。这个定义看起来很奇怪,但它能让 PAM 真正成为一个自动机,而不仅是两棵树。
序列自动机
序列自动机 接受且仅接受指定字符串的子序列。
后缀链接
由于自动机和匹配有着密不可分的关系,而匹配的一个基本思想是「这个串不行,就试试它的后缀可不可以
一个状态会对应若干字符串,而这个状态的后缀链接,是在自动机上的、是这些字符串的公共真后缀的字符串中,最长的那一个。
一般来讲,后缀链接会形成一棵树,并且不同自动机的后缀链接树有着一些相同的性质,学习时可以加以注意。
扩展阅读
在计算复杂性领域中,自动机是一个经典的模型。并且,自动机与正则语言有着密不可分的关系。
如果对相关内容感兴趣的话,推荐阅读博客 计算复杂性(1)Warming Up: 自动机模型。