2

我有一个问题,我真的需要能够使用有限自动机作为关联容器的键。每个键实际上应该代表一个自动机的等价类,因此当我搜索时,我会找到一个等价的自动机(如果存在这样的键),即使该自动机在结构上并不相同。

一个明显的最后手段当然是使用线性搜索和对每个检查的键进行等价测试。我希望有可能做得比这更好。

我一直在考虑试图强加一个任意但一致的排序,并推导出一个有序的比较算法。第一原则涉及自动机表示的字符串集。评估每个自动机可能的第一个标记集,并根据这两个集合应用排序。如有必要,继续检查可能的第二个标记集、第三个标记集等。天真地这样做的明显问题是,在证明等价之前要检查无数个标记集。

我一直在考虑一些模糊的想法——首先最小化输入自动机并使用某种闭包算法,或者转换回常规语法,一些涉及生成树的想法。我得出的结论是我需要放弃标记集的词汇排序,但到目前为止我得出的最重要的结论是,这不是微不足道的,我可能最好继续阅读别人的解决方案。

我从 CiteSeerX 下载了一篇论文——子群和陪集的总排序——但我的抽象代数还不足以知道这是否相关。

我还想到可能有某种方法可以从自动机中导出散列,但我还没有考虑这么多。

谁能推荐一篇好论文来阅读?- 或者至少让我知道我下载的是否是红鲱鱼?

4

4 回答 4

2

我相信您可以从最小化自动机中获得规范形式。对于任何两个等价的自动机,它们的最小化形式是同构的(我相信这是从 Myhill-Nerode 定理得出的)。这种同构尊重边缘标签,当然还有节点类(开始、接受、不接受)。这比未标记的图同构更容易。

我认为,如果您从起始状态开始构建最小化自动机的生成树并按其标签对输出边进行排序,那么您将获得自动机的规范形式,然后可以对其进行散列。

编辑:非树边缘也应该考虑在内,但它们也可以通过它们的标签进行规范排序。

于 2009-12-08T10:42:18.063 回答
2

这是 1992 年的论文表格,他们在其中产生了规范的最小化自动机:非确定性有限自动机的最小化

一旦你有了规范的形式,你可以很容易地散列它,例如通过执行状态和转换的深度优先枚举,并散列一个通过编码状态编号获得的字符串(按它们第一次出现的顺序计数)状态和转换作为三元组

<from_state, symbol, to_state, is_accepting_final_state>

这应该可以解决问题。

于 2009-12-08T12:39:12.440 回答
1

当一个问题似乎无法克服时,解决方案通常是公开宣布您认为该问题有多难。然后,您会立即意识到问题是微不足道的,而您只是让自己看起来像个白痴-这基本上就是我现在的位置;-)

正如问题中所建议的,要对两个自动机进行词汇排序,我需要考虑两件事。两组可能的第一个标记,以及两组可能的所有其他尾部。尾部可以表示为有限自动机,并且可以从原始自动机推导出来。

所以比较算法是递归的 - 比较头部,如果不同你有你的结果,如果相同然后递归比较尾部。

问题是证明一般规则文法等价所需的无限序列。如果在比较过程中出现一对自动机,相当于您之前检查过的一对,则您已证明等价,您可以停止检查。这是有限自动机的本质,这必须在有限数量的步骤中发生。

问题是我仍然有相同形式的问题。为了找出我的终止标准,我需要将我的当前自动机对与迄今为止在比较期间发生的所有过去自动机对进行比较。这就是一直让我头疼的事情。

事实证明,那篇论文是相关的,但可能只带我到这一步。常规语言可以使用连接运算符形成一个组,而左陪集与我一直在考虑的 head:tail 事物有关。

我是白痴的原因是因为我一直在强加一个过于严格的终止条件,我应该知道这一点,因为 WRT 自动机算法的问题并不罕见。

我不需要在自动机对的第一次重复出现时停下来。我可以继续,直到我找到一个更容易检测到的重现——一个具有某种结构等价和逻辑等价的复现。只要我的衍生尾自动机算法是健全的(特别是如果我在每个步骤中最小化并进行其他清理),我就不会在比较过程中生成无限序列的等效但看起来不同的自动机对。结构变化的唯一来源是原始的两个自动机和尾自动机算法,它们都是有限的。

关键是,如果我比较了太多的词汇,这并不重要——我仍然会得到正确的结果,虽然我稍后会终止,但我仍然会在有限的时间内终止。

这应该意味着我可以使用对自动机结构敏感的散列或有序比较来使用不可靠的递归检测(允许一些假阴性)。这是一个比结构不敏感比较更简单的问题,我认为这是我需要的关键。

当然还有性能问题。基于此处涉及的问题,使用标准等价算法的线性搜索可能是一种更快的方法。当然,我希望这种比较是比现有算法效率更低的等价测试,因为它正在做更多的工作 - 非等价案例的词汇排序。真正的问题是基于关键字的搜索的整体效率,这可能需要一些令人头疼的分析。我希望非等效自动机倾向于快速比较(检测前几个步骤中的差异,如传统的字符串比较)这一事实将使这成为一种实用的方法。

此外,如果我达到怀疑等价的程度,我可以使用标准等价算法进行检查。如果该检查失败,我只需继续比较我离开的顺序,而无需检查重复出现的尾部语言 - 我知道我会在有限数量的步骤中找到差异。

于 2009-12-08T02:23:51.713 回答
1

如果您所能做的只是 == 或 !=,那么我认为您必须在添加另一个成员之前检查每个集合成员。这很慢。(编辑:我猜你已经知道了,鉴于你的问题的标题,即使你继续使用比较函数来直接比较两个有限自动机。)

我试图用系统发育树来做到这一点,但很快就会遇到性能问题。如果您想构建没有重复的大型集合,您需要一种转换为规范形式的方法。然后你可以检查一个散列,或者插入一个以字符串表示作为键的二叉树。

另一位确实想出了将树转换为规范代表的方法的研究人员使用帕特里夏树来存储独特的树以进行重复检查。

于 2009-12-08T04:29:11.187 回答