为每列查找具有不同值的子集

Find a subset with distinct values for each column

给定一个简单的 table 像这样:

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

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

例如,如果 N = 3,答案将是

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

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

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

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

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

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

我会这样开始:

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

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

Is there a simple algorithm to conclude on such a question?

答案是严格的"yes";您可以对 K 行的所有(R 选择 K)个子集执行 brute-force search,其中 R 是整个 table 中的行数。该算法非常简单,可以用 Python.

这样的语言在几行中实现

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

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

然后,在每列中具有不同值的任何一组 K 行给出原始图中没有任何边连接的 K 个顶点。也就是说,如果你能在多项式时间内回答yes/no是否存在这样的K行集合,那么你也能在多项式时间内回答最大独立集问题的判定形式。后者是 NP 完全的,因此你的问题是 NP 难的。