【问题标题】:Find a subset with distinct values for each column查找每列具有不同值的子集
【发布时间】:2020-05-26 18:17:42
【问题描述】:

给定一个像这样的简单表格:

+---------+---------+---------+
| Column1 | Column2 | Column3 |
+---------+---------+---------+
| A       | J       | Q       |
| A       | K       | S       |
| B       | M       | R       |
| B       | N       | S       |
| B       | J       | Q       |
| C       | K       | R       |
| D       | J       | R       |
| D       | J       | Q       |
| E       | L       | Q       |
+---------+---------+---------+

是否可以确定该表中是否存在 N 行的子集,使得对于每一列,所有 N 值都是不同的?

例如,当 N = 3 时,答案将是

+---------+---------+---------+
| Column1 | Column2 | Column3 |
+---------+---------+---------+
| A       | J       | Q       |
| B       | N       | S       |
| C       | K       | R       |
+---------+---------+---------+

有没有一个简单的算法可以对这样的问题得出结论?

【问题讨论】:

  • 如果您使用的是 SQL,则可以使用 distinct 关键字来达到此目的。 w3schools.com/sql/sql_distinct.asp - 此外,如果您使用的是 Java 之类的东西,则可以使用集合之类的东西来实现此目的。因此,如果您再次添加相同的条目,它将忽略它。
  • @JGFMK 不,不一样。如果至少一列不同,JGFMK 将认为两行不同。但是在这里,所需的子集必须在每列中独立地具有不同的值。
  • 我不明白这个问题。您如何首先提出 B N S,而不是 B M R。对我来说似乎是随机选择,没有模式。
  • @JGFMK 如果你使用B M R那么你不能选择第三行,因为Q和R在第3列用完了,B在第1列用完了。
  • @JGFMK 问题是“判断该表中是否存在N行的子集,使得每一列的所有N个值都是不同的”。 N = 3 的答案是“真”。这是一个决策问题,而不是优化问题,输出不必是实际的三行集合;该问题仅显示这三行来解释为什么该示例的答案是“正确的”。

标签: algorithm subset distinct-values


【解决方案1】:

有没有简单的算法可以对这样的问题得出结论?

对此的回答绝对是“是”;您可以对 K 行的所有(R 选择 K)子集执行 brute-force search,其中 R 是整个表中的行数。该算法非常简单,可以用 Python 等语言用几行代码实现。

但我认为这不是您要寻找的答案;我想你想知道是否有一个简单的算法需要少于指数时间。答案几乎肯定不是。这个问题是 NP-hard,通过从 maximum independent set problem 减少,所以没有已知的算法可以在多项式时间内给出正确的答案,而且很可能没有这样的算法是可能的。

归约如下:给定一个图,构造一个表,每个顶点一行。对于图中的每条边,在表格中添加一列;在此列中,在边缘连接的两行中写入相同的字母,然后在该列的其​​余每一行中写入不同的其他字母。结果表有 V 行和 E 列,因此它的大小是原始图大小的多项式,并且它是在多项式时间内构造的。

然后,在每列中具有不同值的任何 K 行的集合都会在原始图中给出未由任何边连接的 K 个顶点。这意味着如果你能在多项式时间内回答是否存在这样的K行集合,那么你也可以在多项式时间内回答最大独立集问题的决策形式。后者是 NP 完全的,因此您的问题是 NP 困难的。

【讨论】:

    【解决方案2】:

    简单的解决方案就是搜索(回溯)。

    但是每个解决CSP (Constraint satisfaction problem)的工具/库都可以找到解决方案。

    【讨论】:

      【解决方案3】:

      由于您明确要求算法来解决这个问题:

      如果我正确理解了问题(您在这里使用 N 两次,第一次用于行,第二次用于值,这有点令人困惑),您想在给定的值中找到 N 行具有所有不同的值表。

      我会这样开始:

      1. 如果您已经找到了一个值(例如哈希图),请创建一个数据结构进行查找
      2. 创建一个数据结构来存储符合匹配条件的结果行(所有值不同)
      3. 迭代输入表行,直到达到所需的子集大小或到达表的末尾
      4. 从第一行开始
      5. 在迭代一行时,检查每个值,如果它在您的结构中(在 1. 中创建),如果是 -> 中止,否则将该值添加到查找结构中。检查所有行值后,该行就可以了,可以添加到您的结果集中。
      6. 迭代下一行(如果存在)

      但正如评论中指出的那样,这种算法是一种贪婪的算法,并不总是能找到可能的解决方案

      【讨论】:

      • 这是贪心算法;你确定它正确地解决了问题吗?考虑两列三行的情况,(A, 1)(B, 1)(A, 2),您的算法找到大小为 1 的解,但大小为 2 的解是可能的。
      • 你是对的,这种贪婪的方法不会找到所有的解决方案。
      猜你喜欢
      • 1970-01-01
      • 2016-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-07
      相关资源
      最近更新 更多