问题
I have
toggle = [[1, 1, 1, 1, 0, 0, 1, 0, 0],
[0, 1, 1, 0, 1, 1, 0, 0, 0],
[0, 0, 1, 1, 0, 0, 0, 1, 0],
[0, 0, 0, 1, 1, 0, 1, 1, 0],
[0, 0, 0, 0, 1, 1, 0, 1, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0]]
puzzle = [0, 0, 0, 0, 1, 0, 0, 0, 0]
toggle
is a matrix I already transformed to [row echelon form] with Gaussian elimination. This is in GF(2) space, which means that -1 = 1
and 1 + 1 = 0
.
I already have a working backSubstitute()
method:
def backSubstitute(toggle, puzzle):
# toggle (matrix) and puzzle (vector) in reduced row echelon form
# Initialize result vector
result = [0] * len(puzzle)
pivot = -1
# Iterate from the bottom up
for row in xrange(len(puzzle) - 1, -1, -1):
# Find pivot
for col in xrange(len(puzzle)):
if toggle[row][col]:
pivot = col
break
if pivot == -1:
if puzzle[row]:
raise RuntimeError("Puzzle has no solution")
else:
# iterate across the rest of the row, XORing the values
# together with the puzzle value and then store the result.
result[row] = puzzle[row]
for col in xrange(pivot + 1, len(puzzle)):
result[row] ^= toggle[row][col] and result[col]
return result
It that returns one specific valid solution ([0, 0, 1, 1, 1, 0, 0, 0, 0]
), but I know there are three different solutions:
[0, 1, 0, 0, 1, 0, 1, 0, 0]
[0, 0, 1, 1, 1, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 1]
I'm only interested in the solution with the least number of 1
s, so for this example the desired solution is [0, 0, 0, 0, 0, 0, 0, 0, 1]
.
This needs to be done in pure python (although solutions in other languages would certainly help me too) without third-party libraries, so no numpy or sage.
Working example
For anyone interested in the rationale behind this problem, it's a "lights out" variant solver inspired by this excellent resource.
来源:https://stackoverflow.com/questions/27379340/find-all-solutions-of-row-reduced-echelon-matrix-in-pure-python