数据关系的复杂合并
假设我有一组如下所示的关系:
relations :: [(A, B)]
instance Monoid A
instance Monoid B
我想将这组关系转换为一组新的 A 和 B 关系。
现在,棘手的事情来了:
- 相等的
A
应该对其B
进行mappend
编辑。 - 相等的
B
应该对其A
进行mappend
编辑。 - 重复直到所有
A
和B
都不同(或者不不同,取决于是否可以以非迭代方式完成)。
编辑:排序约束使问题变得微不足道,因此我将其删除。
人们可以假设 Ord
、Hashable
或您需要的任何其他内容是可用的。出于所有意图和目的,我们可以说 A
的行为完全类似于 HashSet
,而 B
的行为完全 就像 Vector
(或具有合理大小检查的其他类型)。
这意味着可以假设 let s = size (mappend ab); s>=尺寸a; s >= size b,并且 a, b :: B; mappend ab /= mappend ba <=>; a、b不为空; a> b => (映射ac)> b
等。
如何发生的示例(假设 是
Set.fromList [a, b]
)
[(<1>, [a]), (<4>, [d]), (<2>, [b]), (<5>, [e]), (<1>, [b]), (<2>, [a]), (<3>, [c])]
-- Merge `A`s for equal `B`s
[(<1,2>, [a]), (<4>, [d]), (<1,2> [b]), (<5>, [e]), (<3>, [c])]
-- Merge `B`s for equal `A`s
[(<1,2>, [a, b]), (<4>, [d]), (<5>, [e]), (<3>, [c])]
-- All values are distinct, so we're done.
此转换 这可以以尽可能有效的方式(时间、空间)完成吗?
Let's say that I have a set of relations that looks like this:
relations :: [(A, B)]
instance Monoid A
instance Monoid B
I want to transform this set of relations to a new set of relations of A
s and B
s.
Now, here comes the tricky stuff:
A
s that are equal should have theirB
smappend
ed.B
s that are equal should have theirA
smappend
ed.- Repeat until all
A
s andB
s are distinct (Or don't, depending on if this can be done non-iteratively somehow).
EDIT: The ordering constraint made the problem trivial, so I removed it.
One can assume that Ord
, Hashable
, or whatever else you need is available. For all intents and purposes, one could say that A
behaves exactly like HashSet
and B
behaves exactly like Vector
(or some other type with reasonable size checking).
This means that one can assume that let s = size (mappend a b); s >= size a; s >= size b
, and that a, b :: B; mappend a b /= mappend b a <=> a, b not mempty; a > b => (mappend a c) > b
, etc.
An example of how this transformation would happen (Pretend that <a, b>
is Set.fromList [a, b]
)
[(<1>, [a]), (<4>, [d]), (<2>, [b]), (<5>, [e]), (<1>, [b]), (<2>, [a]), (<3>, [c])]
-- Merge `A`s for equal `B`s
[(<1,2>, [a]), (<4>, [d]), (<1,2> [b]), (<5>, [e]), (<3>, [c])]
-- Merge `B`s for equal `A`s
[(<1,2>, [a, b]), (<4>, [d]), (<5>, [e]), (<3>, [c])]
-- All values are distinct, so we're done.
How can this be done in an as efficient manner as possible (time, space)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为一般情况不能比 O(n^2) 合并的直接方法更好,因此总算法可能是 O(n^3)。在不限制列表中元素的顺序和
mappend
结果的情况下,您必须匹配每对元素以查看它们是否应该合并,然后重复直到完成。I think the general case cannot be done any better than the straightforward way with an O(n^2) merge, so the total algorithm could be O(n^3). Without restrictions on the order of elements in the list and results of
mappend
, you have to match each pair of elements to see whether they should be merged, and repeat until done.