我正在编写一个Cuda应用程序,该应用程序应该计算我的集合S的两个元素的函数。但是该对的顺序没有任何区别,因此:f(a,b)
= f(b,a)
出于这个原因,我想生成最大大小为K的所有S子集,而不重复这些集合之间的元素对。
换句话说,给定任何两个子集,我不希望它们的交集大于一个元素。 (这样我可以避免多次计算这两个元素的功能)
示例:
鉴于S={1,2,3,4,5,6,7,8,9}
和K=3
,输出应该是这样的:
{ {1,2,3}, {1,4,5}, {1,6,7}, {1,8,9}, {2,4,6}, {2,5,7}, {2,8}, {2,7,9}, {3,4,7},
{3,5,8}, {3,6,9}, {4,5,9} }
但输出应该不是这样的:
{ {1,2,3}, {1,4,5}, {1,6,7}, {1,8,9}, {2,4,6}, {2,5,7}, {2,6,8}, {2,7,9}, {3,4,7},
{3,5,8}, {3,6,9}, {4,5,9} }
因为{2,4,6}
和{2,6,8}
的交集是{2,6}
。
答案 0 :(得分:0)
我将发布一个非答案,希望它能帮助我们确定问题:我在下面回答的问题是
给定一个集合S,生成所有子集的最大基数集 S使得每个子集小于大小K并且不包含两个子集 <基数的交点> 1
如果我们确定你想要的子集大小(k = 3而不是k <= 3),这很容易以非有效的方式进行:
有些问题来自
对于 2)我认为答案是否定的:
观察:对于小N,简单地生成对比生成大小为K的子集更好。生成大小> 2的子集仅消除一对,生成k的子集消除k选择2对。选择大小K只有在
时才会更好n/(k choose 2) = k/(k!/(k-2)!2!) = 2n/(k*(k-1)) > (n*n-1)/2 = (n choose 2)
1/(k*(k-1)) > (n-1)/4n
只有足够大的N才是真的:
1/(k*(k-1)) > 1/4
(k*(k-1)) > 4, k>=3
3) 我认为答案是肯定的
子集的数量在C(n,k)/C(k,2)
处最大化,我们可以使用公式计算它以找到最佳k。如果有剩余的对,我们可以简单地将它们添加到列表中,就像k = 2
答案 1 :(得分:0)
>>> from itertools import combinations, chain
>>> s = {1,2,3,4,5,6,7,8,9}
>>> k = 3
>>> seen = set()
>>> subset_sizes = reversed(range(2,k+1)) # [3,2] for this example. Reversed since you favor the sets with larger values of K
>>> for item in chain.from_iterable(combinations(s,i) for i in subset_sizes):
pairs = set(combinations(item,2))
if not pairs.intersection(seen):
seen.update(pairs)
print item
(1, 2, 3)
(1, 4, 5)
(1, 6, 7)
(1, 8, 9)
(2, 4, 6)
(2, 5, 7)
(3, 4, 7)
(3, 5, 6)
(2, 8)
(2, 9)
(3, 8)
(3, 9)
(4, 8)
(4, 9)
(5, 8)
(5, 9)
(6, 8)
(6, 9)
(7, 8)
(7, 9)
答案 2 :(得分:0)
你可以这样做:
P := {1, 2, 3, 4, 5, 6}; setpartition(P, 3);
{{{1, 2, 3}, {4, 5, 6}}, {{1, 2, 4}, {3, 5, 6}},
{{1, 2, 5}, {3, 4, 6}}, {{1, 2, 6}, {3, 4, 5}},
{{1, 3, 4}, {2, 5, 6}}, {{1, 3, 5}, {2, 4, 6}},
{{1, 3, 6}, {2, 4, 5}}, {{1, 4, 5}, {2, 3, 6}},
{{1, 4, 6}, {2, 3, 5}}, {{1, 5, 6}, {2, 3, 4}}}