我有一个问题,我必须将2D数组中的所有X
更改为0
s,并且我必须计算最小步数(其中一步包括更改整个行或列)需要这样做。例如,在像
[[X, X, X], [X, 0, 0], [X, 0, 0]]
此处所需的最小步骤数为2.
我想到了一种蛮力的方法(我在那里逐行检查并逐列检查,然后比较它们以检查哪个步骤最少)但这会给我一个3的答案,这不是期望的输出。
最佳解决方法是什么?
关于如何处理这个问题的任何帮助或线索,将不胜感激,谢谢!
答案 0 :(得分:3)
考虑每行和每列都有顶点的图。
如果M [i,j]中矩阵中有X,则在顶点r_i和c_j之间存在边缘。
你的问题可以说是试图选择一组顶点(即选择行和列),这样每个边(即每个X)都会触及集合中的至少一个顶点。
这称为minimum vertex cover problem。
一般来说,顶点覆盖是NP完全的,但在这种情况下,图是二分的。
您可以使用max-flow算法求解二分最小顶点覆盖,以计算行和列之间的最大匹配。 (有关详细信息,请参阅Konig's theorem。)
在Python中:
import networkx as nx
M=[ [1,1,1],
[1,0,0],
[1,0,0] ]
G = nx.DiGraph()
for i,row in enumerate(M):
for j,c in enumerate(row):
if c:
G.add_edge('row'+str(i),'col'+str(j), capacity=1.0)
for i in range(len(M)):
G.add_edge('x','row'+str(i), capacity=1.0)
for j in range(len(M[0])):
G.add_edge('col'+str(j), 'y', capacity=1.0)
print nx.max_flow(G, 'x', 'y')