【问题标题】:Picking out exacly one value from each row and column of a matrix从矩阵的每一行和每一列中准确地挑选出一个值
【发布时间】:2019-05-18 09:04:21
【问题描述】:

这不完全是关于代码的问题,但我需要一些关于算法逻辑的帮助。

给定一个 NxN 矩阵,该矩阵的每一行和每一列都至少有一个零值,你将如何选择 N 个零以使每一行和每一列都有一个值?例如:

0 4 6 0 2
0 8 9 5 0
4 0 9 8 5
0 8 0 1 3
8 6 0 1 3

显然,您首先必须选择每一行或每一列上的单数零。我不确定在几行和几列上有相同数量的零的情况。我将如何选择最佳值以便不遗漏任何行或列?

【问题讨论】:

  • 使用带有回溯的递归。任何解决方案都可以。如果速度不够快,您将需要更快的算法。例如,按尽可能少的个零的顺序选择行是有意义的,这样您就可以从第 3 行开始,然后是第 5 行。

标签: algorithm matrix


【解决方案1】:

这就是找maximum cardinality matching in a bipartite graph的问题:行代表一组顶点u_1, u_2, ..., u_N,列代表另一组v_1, v_2, ..., v_N,并且有一个边 u_i -- v_j 每当矩阵位置 (i, j) 处有 0 时。

可以在 O(N^3) 时间内使用最大流算法(例如 Ford-Fulkerson)解决,或者在 O(N^2.5) 时间内使用更专业的 Hopcroft-Karp 算法来解决。事实上,这些算法解决了一个稍微更普遍的问题:它会找到一组可能最大的唯一(行、列)对,使得每对在矩阵中都有一个 0。 (在你的情况下,你碰巧知道有 N 个这样的对的解决方案:这显然是最好的。)

【讨论】:

    【解决方案2】:
    1. 选择零个数最少的行。

    2. 对于该行中的每个零,选择其列中零数量最少的那一列。

    3. 以某种方式标记该行和列(也许在存储所选零的索引后从其中删除所有 zeor?这取决于您)。

      标记的行和列在下一次迭代中被跳过。

    4. 重复直到遍历所有未标记的行和列,或者直到无法构建进一步的解决方案。

    所以对于示例问题,这就是解决方案的可视化方式(<^ 表示标记的行和列):

    0 4 6 0 2

    0 8 9 5 0

    4 0 9 8 5

    0 8 0 1 3

    8 6 0 1 3 // 零最少的行,最后一个被访问

    迭代 1:

    0 4 6 0 2

    0 8 9 5 0

    4 0 9 8 5

    0 8 0 1 3

    8 6 0 1 3

    _ _ ^ _ _

    迭代 2:

    0 4 6 0 2

    0 8 9 5 0

    4 0 9 8 5

    0 8 0 1 3

    8 6 0 1 3

    _ ^ ^ _ _

    迭代 3:

    0 4 6 0 2

    0 8 9 5 0

    4 0 9 8 5

    0 8 0 1 3

    8 6 0 1 3

    _ ^ ^ _ ^

    迭代 4:

    0 4 6 0 2

    0 8 9 5 0

    4 0 9 8 5

    0 8 0 1 3

    8 6 0 1 3

    _ ^ ^ ^ ^

    迭代 5:

    0 4 6 0 2

    0 8 9 5 0

    4 0 9 8 5

    0 8 0 1 3

    8 6 0 1 3

    ^ ^ ^ ^ ^

    【讨论】:

    • 这是一种合理的启发式方法,但我不确定它是否能保证您总能找到解决方案(如果有的话)。
    猜你喜欢
    • 2013-08-11
    • 2017-07-25
    • 1970-01-01
    • 1970-01-01
    • 2012-12-11
    • 1970-01-01
    • 1970-01-01
    • 2019-11-15
    • 1970-01-01
    相关资源
    最近更新 更多