从矩阵的每一行和每一列中挑选出一个值

时间:2019-05-18 09:04:22

标签: algorithm matrix

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

给出一个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

很显然,您首先必须选择在每一行或每一列上都是奇数的零。我不确定在几行和几列上是否有相等数量的零。我该如何选择最佳值,以便不遗漏任何行或列?

2 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:0)

  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 << / p>      

_ _ ^ _ _

迭代2:

  

0 4 6 0 2

     

0 8 9 5 0

     

4 0 9 8 5 << / p>      

0 8 0 1 3

     

8 6 0 1 3 << / p>      

_ ^ ^ _ _

迭代3:

  

0 4 6 0 2

     

0 8 9 5 0 << / p>      

4 0 9 8 5 << / p>      

0 8 0 1 3

     

8 6 0 1 3 << / p>      

_ ^ ^ _ ^

迭代4:

  

0 4 6 0 2 << / p>      

0 8 9 5 0 << / p>      

4 0 9 8 5 << / p>      

0 8 0 1 3

     

8 6 0 1 3 << / p>      

_ ^ ^ ^ ^

迭代5:

  

0 4 6 0 2 << / p>      

0 8 9 5 0 << / p>      

4 0 9 8 5 << / p>      

0 8 0 1 3 << / p>      

8 6 0 1 3 << / p>      

^ ^ ^ ^ ^