【问题标题】:Generate k most subsets unique pair of elements生成 k 个大多数子集唯一的元素对
【发布时间】:2012-05-09 03:03:24
【问题描述】:

我正在编写一个 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}

【问题讨论】:

  • 您能花点时间写下您的问题吗?它应该包含一个short, self-contained, correct, example;对问题所在的清晰描述以及对what you have tried 的描述。
  • 我认为您可能不小心遗漏了问题的某些部分。
  • 这可能是一个有趣的问题,我真的不明白为什么必须关闭它。在您更具体地确定您要查找的内容后重新发布。
  • 请勿转发;编辑问题。已经有重新开放的投票。
  • 继续编辑。问题:1)您谈论“对”,但您的示例涉及三胞胎(但只有一对)。你想要哪一个?两个都?单身人士也行? 2)您的示例不包含所有可能的组合,仅包含其中一些组合。你想要所有可能的组合吗?只有一些?我们如何决定哪些? 3) “我更喜欢二进制”是什么意思?

标签: python math parallel-processing combinatorics discrete-mathematics


【解决方案1】:

我将发布一个非答案,希望它可以帮助我们确定问题:我在下面回答的问题是

给定一个集合 S,生成所有子集的最大基数集 S 使得每个子集的大小都小于 K 并且没有两个子集包含 基数的交集 > 1

如果我们固定您想要的子集的大小(k=3 而不是 k

  1. 从 S 生成所有大小为 k 的子集
  2. 继续删除东西,直到没有交叉点出现

一些问题由此而来

  1. 有没有更有效的方法来做到这一点
  2. 修复 k 是否会改变此解决方案,始终采用最大尺寸的子集是否最佳
  3. 是否存在最优集合,以便我们可以选择大小 t

对于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

【讨论】:

  • @user1363214 在这里转发我的最后一条评论:我认为你的谓词中有一个非交换问题;要从您的原始问题中获取示例,您要应用什么规则来区分 {2,4,6} 和 {2,6,8}:您期望 {2,4,6}, {2 ,8},但你为什么不期待 {2,4}, {2,6,8} ? ...
  • 我认为我们在这里浪费了时间:我们只是没有从 OP 那里得到他需要在 S=1 的 1,2,3 1,2,4 1,2,5 之间进行选择, 2,3,4,5 和 K=3。 OP 显然缺乏他没有提供的总订单功能。
  • @Boud - 同意。我正在解决这个问题,就好像他不在乎,他只想要最大集,这仍然是一个有趣的问题。如果事实证明不相关,我会回答我的答案:)
【解决方案2】:
>>> 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)

【讨论】:

    【解决方案3】:

    你可以这样做:

        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}}}
    

    【讨论】:

      猜你喜欢
      • 2011-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多