【问题标题】:Algorithm to find common subsets寻找公共子集的算法
【发布时间】:2010-10-16 05:26:28
【问题描述】:

我有 NSi 组数字,每个组的大小不同。让 m1, m2, ... mn 为各个集合的大小(mi = | Si |),M是最大集合的大小。我必须找到其中至少有两个数字的公共子集。示例:

Set  Items
1    10,80,22
2    72, 10, 80, 26,50
3    80,
4    10, 22
5    22, 72, 10, 80, 26,50

所以结果会是这样的

Items                Found in sets
10, 22               1, 4
10, 80               1, 2, 5
10, 80, 22           1, 5
10, 72, 80, 26, 50   2, 5

那么如何自动解决这个问题以及相应解决方案的预期复杂性是多少?我需要它尽可能快。

【问题讨论】:

  • N 和 M 可能有多大?
  • N 可以是任何数字,但假设 n = 100 并且 m 最多 15 个项目
  • 你的意思是在你的例子中,M 被认为是 6? (大约是一行中的最大项目数(即,在一个数组中))
  • m 可以有最大值吗?那么m维度真的可以是一个常数......即使它是15 * 15,它也是225并且在考虑O()时被认为是一个常数
  • Ehm,您需要尽快进行讨论吗?

标签: algorithm


【解决方案1】:

由于最初的问题要求尽可能快地进行讨论,以下是如何缩短讨论时间。

首先,讨论输出是否与您的输入成指数关系。假设您有 2 个元素和 N 个集合。假设每个元素属于每个集合;它将需要 N 行作为您的输入。那么,你应该打印多少行呢?

我认为您将打印 2N-N-1 行,如下所示:

1,2     1,2
1,2     1,3
.....
1,2     1,N
1,2     2,1
.....
1,2     1,2,3
.....
1,2     1,2,3,...N

由于您将花费 O(2N) 时间打印,因此您可以选择此页面上的任何建议来计算此信息 - 无论如何,您已经被指数捕获。

这个论点会让你的讨论很快。

【讨论】:

  • 很好,更不用说所有 I/O 的常数因子可能比计算步骤更高
  • 这很幽默,但我很确定 Ali 希望 算法 快,而不是 讨论。 :-)
  • @pax,好吧,我不知道 Ali 想如何快速创建具有指数下限的算法。所以我认为这是关于讨论的。
  • 感谢 Pavel Shved。我知道这个解决方案,但系统会进入昏迷状态(它会休眠数年)。对您的算法表示感谢
【解决方案2】:

你可以这样做 -

  1. 创建一个哈希表并作为键插入您的每个项目和值作为它们所属的集合。 Eg: 10:[0,1,3,4] 80:[0,1,2,4] 22:[0,3,4] 72:[1,4] 26:[1,4] 50:[1,4]

  2. 在此之后,对于哈希表中的每 2 个元素,找到键值的交集。这里 (10, 80) 的交集给出 [0,3,4]。对 (10,22)(10,72) 执行此操作...你有你的结果。

  3. 复杂性 - 将 M 项插入哈希表 - O(M) 搜索哈希表中的每个键 - O(1) 键值的交集运算 - O(m^2) [这个可以优化]

总的来说,我会说这是 O(m^2) 算法。但是,如果每个“Set”中“Items”的大小不是很大,那么您不会注意到对性能的影响。

【讨论】:

    【解决方案3】:

    您被要求对所有集合进行成对交集,然后收集所有大小 >= 2 的结果。

    有 O(N^2) 对。对每个进行交集都是 O(M)。组装所有结果,按集合内容对它们进行排序以计算出重复项为 N^2 Log N^2(最坏的情况是每对的交集不同,因此可能有 O(N^2) 个结果集)

    所以我认为复杂度是 O((N^2 + N log N) * M)

    但是很可能某处有错误。

    保罗

    【讨论】:

      【解决方案4】:

      我能想到的一个解决方案:

      使用哈希表,生成该“行”中数字的“一对数字”的所有组合,即O(M * M)时间。

      然后将它们用作哈希键,映射到主数组索引。

      For each row of those N elements,
        do the step above... and if the hash already maps to a number, then it is a match,
          then return the pair, or else just put those in the hash
      

      是 O(N * M * M)

      更新:如果,正如你在评论中所说,M 最大可以是 15,那么 O(N * M * M) 真的和 O(N) 一样。


      如果您最初的问题是查找所有对,那么

      For each row of those N elements,
        do the step first mentioned... and if the hash already maps to a number, 
          then it is a match and just print out the pair if this pair is not printed yet
        and in any event, put the mapping into the hash
      
      to tell whether a pair has been printed, created another hash, such as
        printed_or_not[i,j] = true or false, 
          and make sure to check printed_or_not[i,j] or printed_or_not[j, i]
          because not need to print again if just different order
      

      【讨论】:

        【解决方案5】:

        我有一些建议。当您循环循环以计算该集合中的数字时,您应该对集合中的所有项目进行排序。您应该添加条件以检查数字是否大于您的搜索值并使用中断; for 循环结束。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2010-12-27
          • 1970-01-01
          • 1970-01-01
          • 2016-10-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多