algorithm - 函数式语言中的等价类和联合/查找

标签 algorithm data-structures functional-programming union-find equivalence-classes

对于自动机算法,我需要一个函数式语言中的快速 Union-Find 数据结构。由于需要形式化证明数据结构的正确性,所以我更喜欢简单的结构。

我想做的是计算集合 S w.r.t 中元素的等价类。关系 R ⊆ S × S。我最终想要得到的是一些函数 f: S → SS 的任何元素映射到其 R< 的(规范)代表-等价类。通过“规范”,我的意思是我不关心它是哪个代表,只要它对于一个等价类的所有元素都是相同的,即我想要 f x = f y ⟺ (x,y) ∈ R 保持。

函数式语言中最好的数据结构和算法是什么?我应该补充一点,我确实需要“正常”的功能代码,即没有可变性/状态转换器 monad。

编辑:与此同时,我想出了这个算法:

m := empty map
for each s ∈ S do
  if m s = None then
    for each t in {t | (s,t) ∈ R}
      m := m[t ↦ s]

这将创建一个映射,将 S 的任何元素映射到其等价类的代表,其中代表是 S 迭代到达的第一个元素.我认为这实际上具有线性时间(如果 map 操作是恒定的)。但是,我仍然对其他解决方案感兴趣,因为我不知道这在实践中的效率如何。

(我的关系在内部表示为“S → (S Set) option”,因此在 {t | (s,t) ∈ R} 上迭代 - 这是对该结构的廉价操作。)

最佳答案

据我所知(快速搜索并没有让我失望),没有已知的纯功能等同于传统的 disjoint-set datastructure它具有相当的渐近性能(摊销逆阿克曼函数)。 (传统的数据结构不是纯函数的,因为它需要破坏性更新来执行路径压缩)

如果您对功能纯度不死心,您可以只使用破坏性更新,并实现常规数据结构。

如果不关心匹配渐近性能,可以用persistent associative map代替常规数据结构的随机访问数组。 ,以额外的 O(log N) 性能因素为代价,并且需要验证其正确性。

如果您出于验证目的而希望尽可能简单,并且对上述任何一项都没有死心,您可以使用可更新数组放弃按等级联合优化。 IIRC 这会产生 O(log N) 摊销的最坏情况性能,但实际上可能会提高实际执行速度(因为不再需要存储或管理等级)。

关于algorithm - 函数式语言中的等价类和联合/查找,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15691696/

相关文章:

c++ - 划分4D笛卡尔网格进行并行处理

c - BST - 递归插入

javascript - 使用 Reduce 将每个数组元素的值加倍

scala - 如何将 ADT 列表分成其变体?

php - php中的数组列表

javascript - 如何在函数式编程中访问两个参数

java - 删除自定义对象的 ArrayList 中的重复项

java - 如何将显示方法添加到仅显示列表中第一个和最后 10 个项目的 Java 链表实现?

C#,将时间从 float 表示形式转换为字符串表示形式

javascript - 如何在 Javascript 中获取真实的 map 和布景?