Hash 为有限状态自动机所接受的语言寻找好的哈希函数

Hash 为有限状态自动机所接受的语言寻找好的哈希函数,hash,hashcode,regular-language,state-machine,formal-languages,Hash,Hashcode,Regular Language,State Machine,Formal Languages,我正在用Java开发一个项目(但我认为它不依赖于语言),在这个项目中,我在二进制字母表上生成小型(最多4个状态)非确定性有限状态自动机,我必须快速检查生成的自动机是否与之前的自动机等价。因此,我必须使用一些好的散列函数,以避免与太多的自动机相比较 我的第一个想法是对转换进行DFS,找到所有接受的字,直到最大长度为5,然后将接受的字集映射到64位长(最大长度为5的二进制字的数量)。但它似乎在NFA上产生了太多的4态碰撞。增加长度会导致哈希代码的计算速度太慢,无法实际使用 另一种方法是使用一组单词并

我正在用Java开发一个项目(但我认为它不依赖于语言),在这个项目中,我在二进制字母表上生成小型(最多4个状态)非确定性有限状态自动机,我必须快速检查生成的自动机是否与之前的自动机等价。因此,我必须使用一些好的散列函数,以避免与太多的自动机相比较

我的第一个想法是对转换进行DFS,找到所有接受的字,直到最大长度为5,然后将接受的字集映射到64位长(最大长度为5的二进制字的数量)。但它似乎在NFA上产生了太多的4态碰撞。增加长度会导致哈希代码的计算速度太慢,无法实际使用

另一种方法是使用一组单词并测试自动机接受哪一个单词,但我认为找到正确的单词并不是那么简单

您是否知道如何改进哈希函数以避免过多的冲突而不会显著降低速度


提前感谢

我在进一步思考(感谢@justhalf和@templatetypedef),我有一个想法-任何NFA(或更准确地说,它接受的语言)的内射函数到整数-让我们有一个NFA。让我们构造最小DFA A_min,用完整的delta函数接受相同的语言。作为Myhill-Nerode定理的一个结果,除了同构之外,这个自动机应该是明确的。从初始状态开始执行BFS,根据字母表中某些固定的字符顺序(例如前0、后1)优先考虑边缘(过渡)。并根据访问顺序对各州重新编号。现在我们有了一个规范的最小DFA,我们可以将状态的关联矩阵映射到一个整数,并附加最终状态的枚举(或者更好地创建一个元组,以避免冲突)。然后,该整数可用于确定两个NFA的等效性。你认为可以吗?或者有其他想法吗

您是否可以使用子集构造将NFA转换为DFA,然后将DFA最小化为规范DFA?是的,这是可能的。去终端化是一个相当便宜的操作。现在,我使用Brozowski算法来最小化dfa,这似乎很慢,但我希望Hopcroft会更快——我将实现它。你认为它会有助于计算散列吗?@RafaelK:你可以使用最小化的DFA作为散列,通过精确比较状态和转换。为什么使用散列或最小化?您可以使用Hopcroft&Motwani&Ullman《自动机理论、语言和计算导论》(第3版,Addison-Wesley 2007)第4.4.1节中讨论的可区分对矩阵直接比较两个DFA。无论如何,为了最小化,你都需要构造矩阵,但你不必进一步比较自动机的等价性。@同上:是的,但我正在生成数十亿个矩阵-我需要最小化与前面的比较的数量。因此,我需要一些好的散列函数或其他东西,以尽可能排除许多非等价自动机。如果这样做有效,优点应该是,散列和相互比较一些长整数比散列和直接测试等价自动机更简单和有效。如果NFA最多有4个状态,那么DFA最多有2^4=16。您需要48位(每个状态三位)来表示状态转换表和最终状态表。这非常适合现代64位处理器的寄存器。也就是说,不是很长的整数。我不明白,在编码转换时,每个状态只需要3位。我的计算是,如果我有一个有16个状态的DFA,我需要每个状态4位来编码状态的数量,0,4位来编码状态的数量,1,这意味着每个状态8位(总共128位),这适合于两个64位整数。为了对最终状态列表进行编码,我需要16位,这正好适合一个短整数。