我有一条记录,将图形描述为一组节点和边:
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) -- ?
}
由于我永远不会删除边,我想使用联合查找结构(添加边时可以轻松更新)来跟踪连接的组件,因为我想映射连接的组件,所以它会很有用也将它们作为一组集合。当然,我想获得一个节点的组件。
我找到了等价库,之所以选择它是因为我看不到如何使用union-find创建集合,而持久等价需要知道值范围。
现在我可以创建关系,并使用以下方法返回集合集:
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
非常幼稚,应该可以直接从内部数据结构中获取所有等价类。
而且,更重要的是:如何将等价关系存储在我的数据结构中?