Se me ocurrió un algoritmo de fuerza bruta.
El algoritmo se basa en conjeturas 2:
(por lo que puede no funcionar para todas las matrices - Voy a verificar más tarde)
- El mínimo (número de palancas acodadas) solución contendrá una específica fila o columna solo una vez.
- En cualquier orden que apliquemos los pasos para convertir la matriz, obtenemos el mismo resultado.
El algoritmo:
digamos que tenemos la matriz m = [[1,0], [0,1]].
m: 1 0
0 1
Generamos una lista de todos los números de fila y columna,
así: ['r0', 'r1', 'c0', 'c1']
Ahora que la fuerza bruta, también conocido como examinar, cada posibles combinaciones de pasos.
Por ejemplo,
empezamos con una solución de 1-paso,
ksubsets = [['r0'], ['r1'], ['c0'], ['c1']]
si ningún elemento es una solución luego proceder con una solución de 2 pasos,
ksubsets = [['r0', 'r1'], ['r0', 'c0'], ['r0', 'c1'], ['r1', 'c0'], ['r1', 'c1'], ['c0', 'c1']]
etc ...
Un El elemento ksubsets (combo) es una lista de pasos de alternar para aplicar en una matriz.
implementación de Python (probado en la versión 2.5)
# Recursive definition (+ is the join of sets)
# S = {a1, a2, a3, ..., aN}
#
# ksubsets(S, k) = {
# {{a1}+ksubsets({a2,...,aN}, k-1)} +
# {{a2}+ksubsets({a3,...,aN}, k-1)} +
# {{a3}+ksubsets({a4,...,aN}, k-1)} +
# ... }
# example: ksubsets([1,2,3], 2) = [[1, 2], [1, 3], [2, 3]]
def ksubsets(s, k):
if k == 1: return [[e] for e in s]
ksubs = []
ss = s[:]
for e in s:
if len(ss) < k: break
ss.remove(e)
for x in ksubsets(ss,k-1):
l = [e]
l.extend(x)
ksubs.append(l)
return ksubs
def toggle_row(m, r):
for i in range(len(m[r])):
m[r][i] = m[r][i]^1
def toggle_col(m, i):
for row in m:
row[i] = row[i]^1
def toggle_matrix(m, combos):
# example of combos, ['r0', 'r1', 'c3', 'c4']
# 'r0' toggle row 0, 'c3' toggle column 3, etc.
import copy
k = copy.deepcopy(m)
for combo in combos:
if combo[0] == 'r':
toggle_row(k, int(combo[1:]))
else:
toggle_col(k, int(combo[1:]))
return k
def conversion_steps(sM, tM):
# Brute force algorithm.
# Returns the minimum list of steps to convert sM into tM.
rows = len(sM)
cols = len(sM[0])
combos = ['r'+str(i) for i in range(rows)] + \
['c'+str(i) for i in range(cols)]
for n in range(0, rows + cols -1):
for combo in ksubsets(combos, n +1):
if toggle_matrix(sM, combo) == tM:
return combo
return []
Ejemplo:
m: 0 0 0
0 0 0
0 0 0
k: 1 1 0
1 1 0
0 0 1
>>> m = [[0,0,0],[0,0,0],[0,0,0]]
>>> k = [[1,1,0],[1,1,0],[0,0,1]]
>>> conversion_steps(m, k)
['r0', 'r1', 'c2']
>>>
De tus comentarios a continuación, creo que deberías editar tu pregunta, y cambiar 'jth row' a 'jth column'. –
oops..si tienes razón ... gracias – user160618
@unknown (yahoo), 1) ¿te importa la eficiencia ?, 2) ¿quieres etiquetarlo como un desafío de código? –