Domanda

Sto cercando di creare una matrice 2d di numeri interi con indirizzamento simmetrico (cioè matrice [2,3] e matrice [3,2] restituiranno lo stesso valore) in python. Gli interi avranno addizioni e sottrazioni fatte su di loro e saranno usati per confronti logici. La mia idea iniziale era quella di creare in anticipo gli oggetti interi e provare a riempire un elenco di liste con alcuni equivalenti di puntatori di Python. Non sono sicuro di come farlo, però. Qual è il modo migliore per implementarlo e dovrei usare elenchi o un'altra struttura di dati?

È stato utile?

Soluzione

Un modo più semplice e più pulito è usare un dizionario con tuple ordinate come chiavi. Le tuple corrispondono al tuo indice di matrice. Sostituisci __getitem__ e __setitem__ per accedere al dizionario in ordine di tuple; ecco un esempio di classe:

class Matrix(dict):
    def __getitem__(self, index):
        return super(Matrix, self).__getitem__(tuple(sorted(index)))
    def __setitem__(self, index, value):
        return super(Matrix, self).__setitem__(tuple(sorted(index)), value)

E poi usalo in questo modo:

>>> matrix = Matrix()
>>> matrix[2,3] = 1066
>>> print matrix
{(2, 3): 1066}
>>> matrix[2,3]
1066
>>> matrix[3,2]
1066
>>> matrix[1,1]
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "z.py", line 3, in __getitem__
    return super(Matrix, self).__getitem__(tuple(sorted(index)))
KeyError: (1, 1)

Altri suggerimenti

Golub e Van Loan's "Matrix Computations" il libro delinea uno schema di indirizzamento possibile:

Comprimi i dati in un vettore e accedi come segue, supponendo i > = j:

a_ij = A.vec((j-1)n - j(j-1)/2 + i)    

Probabilmente stai meglio usando una matrice numpy quadrata piena. Sì, spreca metà della memoria per l'archiviazione di valori ridondanti, ma il rotolamento della propria matrice simmetrica in Python sprecherà ancora più memoria e CPU archiviando ed elaborando gli interi come oggetti Python.

Devi solo memorizzare il triangolo inferiore della matrice. In genere questo viene fatto con un elenco di lunghezze n (n + 1) / 2. Dovrai sovraccaricare il metodo __getitem__ per interpretare il significato della voce.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top