[如果这映射到已知问题,请告诉我]
我有n套不同的尺码。集合中的每个元素都是唯一的。每个元素最多可以出现在两个不同的集合中。
我想对这些集合执行操作,但避免重复或丢失任何元素。 问题:找出应删除所有这些n集的内容,因为它们被其他集覆盖。
E.g。 [A,B,C]; [一个];并[b]。删除[a],[b],因为两者都被第一个覆盖。
E.g。 [A,B,C]; [一个];并[b]; [光盘]。删除[a,b,c],因为所有三个元素都被剩余的集合覆盖。 注意:此处[a],[b]单独无效答案,因为'c'正在重复。类似地,[a],[b],[c,d]无效答案,因为如果删除则会遗漏'd'。
答案 0 :(得分:3)
我认为这是Exact Cover problem。最后一个约束 - 每个元素最多在两个集合中 - 在我看来并不能从根本上改变问题(虽然我可能很容易对此错误)。维基百科网页包含各种算法方法的很好的总结。选择的算法似乎是Dancing Links。
答案 1 :(得分:3)
我认为这是一个2-sat problem的案例,可以使用基于method的Tarjan's algorithm在线性时间内解决。
现在,您可以使用标准的2-sat算法来解决这个问题,以确定是否可能无法实现这一目标,或者如果可能的话,可以进行令人满意的分配。
对于具有V组和N个元素的情况,您将具有V变量和最多2N个子句,因此Tarjan的算法将具有复杂度O(V + 2N)。
答案 2 :(得分:1)
由于集合中的元素可以出现在不超过两个集合中,因此集合之间存在相当简单的连接,可以显示为图形,下面显示了两个示例。一个示例使用红线表示边缘,另一个使用黑线表示边缘。
以上显示这些集合可以分为三组。
如果所有集合都在第1组或第3组中,会发生什么事情并不是很清楚。但似乎有一个相当简单的标准允许快速删除集合,而psudocode看起来像这样:
for each set in group2:
for each element that appears twice in that set:
if the other set that contains that element is in group1:
remove the other set
然后,元素数量的性能是线性的。
答案 3 :(得分:0)
我试图找到要包含而不是删除的集合。像这样的东西?
(1)元素列表及其所在集合的索引
(2)使用具有仅出现在其中的元素的集合的索引来填充答案列表
(3)梳理(1)中的地图,如果元素的集合索引不在答案列表中,则在答案中添加元素所在的最小集合的索引。
Haskell代码:
import Data.List (nub, minimumBy, intersect)
sets = [["a","b","c","e"],["a","b","d"],["a","c","e"]]
lengths = map length sets
--List elements and the indexes of sets they are in
mapped = foldr map [] (nub . concat $ sets) where
map a b = comb (a,[]) sets 0 : b
comb result [] _ = result
comb (a,list) (x:xs) index | elem a x = comb (a,index:list) xs (index + 1)
| otherwise = comb (a,list) xs (index + 1)
--List indexes of sets that have elements that appear only in them
haveUnique = map (head . snd)
. filter (\(element,list) -> null . drop 1 $ list)
$ mapped
--Comb the map and if an element's set-index is not in the answer list,
--add to the answer the index of the smallest set that element is in.
answer = foldr comb haveUnique mapped where
comb (a,list) b
| not . null . intersect list $ b = b
| otherwise =
minimumBy (\setIndexA setIndexB ->
compare (lengths!!setIndexA) (lengths!!setIndexB)) list : b
输出:
*Main> sets
[["a","b","c","e"],["a","b","d"],["a","c","e"]]
*Main> mapped
[("a",[2,1,0]),("b",[1,0]),("c",[2,0]),("e",[2,0]),("d",[1])]
*Main> haveUnique
[1]
*Main> answer
[2,1]