使用最小行列切换将NxN二进制矩阵转换为零矩阵

时间:2015-09-02 15:08:12

标签: algorithm matrix

与此问题类似:Transforming a NxN binary matrix to a zero matrix using minimum row and column toggles,但我们只有一个操作,即选择一个坐标(i,j),并切换两个操作,而不是两个操作(切换行或切换列)。包含(i,j)的行和列。

例如,切换矩阵

的(0,0)
|1 1 1|
|1 1 1|
|1 1 1|

将产生

|0 0 0|
|0 1 1|
|0 1 1|

我尝试了一种递归方法,在这种方法中,我尝试切换之前没有切换过的每个元素(i,j),并递归地将切换的矩阵传递给函数。我找到了最小的切换次数,并返回该结果+ 1.但是,该解决方案不能很好地适应矩阵的大小(特别是当大小> 10时)。

def toggle_matrix(matrix, row, col):
    new_matrix = [list(r) for r in matrix]
    for i in xrange(len(matrix)):
        new_matrix[i][col] ^= 1
        new_matrix[row][i] ^= 1
    new_matrix[row][col] ^= 1

    return tuple(tuple(r) for r in new_matrix)


def answer_recur(matrix, touched, cache):
    if all(c == 0 for r in matrix for c in r):
        return 0
    if matrix in cache:
        return cache[matrix]
    min_touches = float('inf')

    for row in xrange(len(matrix)):
        for col in xrange(len(matrix)):
            elem = (row, col)
            if elem in touched:
                continue
            min_touches = min(min_touches, answer_recur(toggle_matrix(matrix, row, col), touched | set([elem]), cache))
    cache[matrix] = min_touches + 1
    return min_touches + 1

def answer(matrix):
    matrix = tuple(tuple(r) for r in matrix)
    result = answer_recur(matrix, set(), {})
    if result == float('inf'):
        return -1
    return result

解决这个问题的更好的算法是什么,可以根据矩阵的大小进行扩展?

0 个答案:

没有答案