Questo è un problema combinatorio molto difficile. Infatti lo Subgraph Isomorphism Problem può essere ridotto al tuo problema (nel caso in cui la matrice A
abbia solo 0-1 voci, il tuo problema è esattamente un problema di isomorfismo del sottografo). Questo problema è noto per essere NP-completo.
Ecco una soluzione di backtracking ricorsivo che fa un po 'meglio di brute-forzando tutte le possibili soluzioni. Si noti che questo richiede ancora tempo esponenziale nel caso peggiore. Tuttavia, se si presuppone che esista una soluzione e che non vi siano ambiguità (ad esempio che tutte le voci in B
siano distinte), questa trova la soluzione in tempo lineare.
def locate_columns(a, b, offset=0):
"""Locate `a` as a sublist of `b`.
Yields all possible lists of `len(a)` indices such that `a` can be read
from `b` at those indices.
"""
if not a:
yield []
else:
positions = (offset + i for (i, e) in enumerate(b[offset:])
if e == a[0])
for position in positions:
for tail_cols in locate_columns(a[1:], b, position + 1):
yield [position] + tail_cols
def locate_submatrix(a, b, offset=0, cols=None):
"""Locate `a` as a submatrix of `b`.
Yields all possible pairs of (row_indices, column_indices) such that
`a` is the projection of `b` on those indices.
"""
if not a:
yield [], cols
else:
for j, row in enumerate(b[offset:]):
if cols:
if all(e == f for e, f in zip(a[0], [row[c] for c in cols])):
for r, c in locate_submatrix(a[1:], b, offset + j + 1, cols):
yield [offset + j] + r, c
else:
for cols in locate_columns(a[0], row):
for r, c in locate_submatrix(a[1:], b, offset + j + 1, cols):
yield [offset + j] + r, c
B = [[1,2,3,4,5], [6,7,8,9,10], [11,12,13,14,15], [16,17,18,19,20]]
A = [[6,8], [16,18]]
for loc in locate_submatrix(A, B):
print loc
Questo stamperà:
([1, 3], [0, 2])
'' [[6,8,9], [16,18,19]] 'una sotto-matrice valida? (In altre parole, stai forse cercando un elenco di indici su ciascun asse, o solo una sezione start/stop/step?) – abarnert
Inoltre, dovremmo assumere che tu possa capire l'ovvia soluzione di forza bruta, quindi non vale la pena menzionarla (almeno senza una tesi che non sia possibile nulla di più efficiente)? – abarnert
Si assume che righe/colonne possano essere ripetute nella matrice 'A'? Presumi che le righe e le colonne compaiano nello stesso ordine in 'B' e in' A'? – Thibaut