Haskell 图结构中的并集查找

Haskell 图结构中的并集查找,haskell,union-find,Haskell,Union Find,我有一个记录,将图形描述为一组节点和边: data MyGraph a = MyGraph { nodes :: Set a, edges :: Set (a,a), components :: UnionFindM a -- ? } emptyGraph = MyGraph{ nodes = empty, edges = empty, components = emptyUnionFind singleton union --? } addEdge g (a,b) = g{

我有一个记录,将图形描述为一组节点和边:

data MyGraph a = MyGraph {
  nodes :: Set a,
  edges :: Set (a,a),
  components :: UnionFindM a -- ?
}
emptyGraph = MyGraph{
  nodes = empty, edges = empty,
  components = emptyUnionFind singleton union --?
}
addEdge g (a,b) = g{
  edges = (a,b) `insert` (edges g),
  components = (components g) >>= (equate a b) -- ?
}
因为我永远不会删除边,所以我希望使用联合查找结构(在添加边时可以轻松更新)跟踪连接的组件,因为我希望映射到连接的组件上,所以将它们作为一组集合也很有用。当然,我想得到一个节点的组件

我找到了这个库,之所以选择它,是因为我不知道如何创建集合,并且需要知道值的范围

现在,我可以创建关系,并使用以下命令返回集合集:

import Control.Monad(liftM)
import Data.Equivalence.Monad
import Data.Set(singleton, union, fromList)
f = runEquivM singleton union $ do
  equate "foo" "bar"
  equate "bar" "baz"
  (liftM fromList) $ mapM classDesc ["foo","bar","baz","one","two"]

>>> f
fromList [fromList ["bar","baz","foo"],fromList ["one"],fromList ["two"]]
但是:使用
fromList
非常简单,应该可以直接从内部数据结构获取所有等价类


更重要的是:如何在数据结构中存储等价关系?

一个选项是使用
data.equivalence.Persistent

data MyGraph a = MyGraph {
  nodes :: Set a,
  edges :: Set (a,a),
  components :: Equivalence a
}
emptyGraph :: Ix a => (a, a) -> MyGraph a
emptyGraph range = MyGraph{
  nodes = empty, edges = empty,
  components = emptyEquivalence range
}
addEdge :: Ix a => MyGraph a -> (a, a) -> MyGraph a
addEdge g (a,b) = g{
  edges = (a,b) `insert` (edges g),
  components = equate a b (components g)
}

我觉得在这里使用
Ix
有点烦人,但是如果它对您的目的有效,那么就使用它吧。让union find持久化是一个很棒的想法,它还包括一个在Coq中被证明是正确的实现。基本上,如果使用反向差分数组,则得到的持久数组具有线性数组的性能,但可以以对数慢化为代价以持久方式使用它们。因此,它们适合于以纯功能的方式实现union find中涉及大量必需副作用的内容。

感谢您的论文!忘了在我的问题中提到:我事先不知道图表的大小,这就是为什么它也不适合,因为它必须知道构造上的范围…