给定一个bidimensionnal数组,如:
-----------------------
| | 1 | 2 | 3 | 4 | 5 |
|-------------------|---|
| 1 | X | X | O | O | X |
|-------------------|---|
| 2 | O | O | O | X | X |
|-------------------|---|
| 3 | X | X | O | X | X |
|-------------------|---|
| 4 | X | X | O | X | X |
-----------------------
我必须找到当前包含O
的最大单元格集,每行最多一个单元格,每列最多一个。
例如,在上一个示例中,最佳答案是3,时间为:
似乎我必须在O(CR)
中找到一个算法(其中C
是列数,R
是行数。
我的第一个想法是根据儿子的数字按升序对行进行排序。这是算法的样子:
For i From 0 To R
For j From 0 To N
If compatible(i, j)
add(a[j], i)
Sort a according to a[j].size
result = 0
For i From 0 To N
For j From 0 to a[i].size
if used[a[i][j]] = false
used[a[i][j]] = true
result = result + 1
break
Print result
尽管我没有找到任何反例,但我不知道它是否总能给出最佳答案。
这个算法是否正确?有没有更好的解决方案?
答案 0 :(得分:1)
关于Billiska的建议,我在Python中发现了一个很好的“Hopcroft-Karp”算法实现:
http://code.activestate.com/recipes/123641-hopcroft-karp-bipartite-matching/
这个算法是解决最大二分匹配问题的几个算法之一,使用该代码完全“原样”这里是我如何解决你的帖子中的示例问题(在Python中):
from collections import defaultdict
X=0; O=1;
patterns = [ [ X , X , O , O , X ],
[ O , O , O , X , X ],
[ X , X , O , X , X ],
[ X , X , O , X , X ]]
G = defaultdict(list)
for i, x in enumerate(patterns):
for j, y in enumerate(patterns):
if( patterns[i][j] ):
G['Row '+str(i)].append('Col '+str(j))
solution = bipartiteMatch(G) ### function defined in provided link
print len(solution[0]), solution[0]