Finding a "generalized diagonal" in a binary matrix
A "generalized diagonal" in a NXN matrix is a selection of N cells, such that:
- Exactly one cell is selected from each row and from each column
- Every selected cell contains a non-zero value
I am looking for an algorithm to find a generalized diagonal in O(n^3). It would seem to me that the following dynamic programming algorithm is "good enough", but I'm not sure how to analyze its comple开发者_JAVA百科xity.
Set<Set<Integer>> failedCache = new HashSet<Set<Integer>>();
List<Integer> find(int[][] matrix, Set<Integer> used, int row) {
int N = matrix.length;
if (failedCache.contains(used))
return null;
if (row == N) return new ArrayList<Integer>();
for (int col = 0; col < N; ++col) {
if (matrix[row][col] == 0)
continue;
if (used.contains(col))
continue;
Set<Integer> newUsed = new HashSet<Integer>(used);
newUsed.add(col);
List<Integer> answer = find(matrix, newUsed, row + 1);
if (answer != null) {
answer.add(col);
return answer;
}
}
failedCache.add(used);
return null;
}
The algorithm runs in worst-case exponential time because on the following matrix
11111
11111
11111
11111
00000
it will try about n! possible combinations.
For polynomial time solution, create a bipartite graph using the matrix, and find perfect matching.
For example, with matrix
011
101
001
you create the graph
A X
B Y
C Z
with edges A->Y, A->Z, B->X, B->Z, C->Z.
精彩评论