Pregunta

Estoy buscando crear una matriz 2D de enteros con direccionamiento simétrico (es decir, la matriz [2,3] y la matriz [3,2] devolverán el mismo valor) en Python. Los enteros tendrán sumas y restas, y se usarán para comparaciones lógicas. Mi idea inicial era crear los objetos enteros por adelantado e intentar llenar una lista de listas con algún equivalente de punteros de Python. Sin embargo, no estoy seguro de cómo hacerlo. ¿Cuál es la mejor manera de implementar esto? ¿Debería utilizar listas u otra estructura de datos?

¿Fue útil?

Solución

Una forma más simple y limpia es usar un diccionario con tuplas ordenadas como claves. Las tuplas corresponden con su índice de matriz. Anule __getitem__ y __setitem__ para acceder al diccionario por tuplas ordenadas; Aquí hay una clase de ejemplo:

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)

Y luego úsalo así:

>>> 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)

Otros consejos

Golub y Van Loan's '' Matrix Computations '' el libro describe un esquema de direccionamiento factible:

Usted empaqueta los datos en un vector y accede de la siguiente manera, suponiendo que i > = j:

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

Probablemente sea mejor usar una matriz numpy cuadrada completa. Sí, desperdicia la mitad de la memoria almacenando valores redundantes, pero rodar su propia matriz simétrica en Python desperdiciará aún más memoria y CPU al almacenar y procesar los enteros como objetos de Python.

Solo necesita almacenar el triángulo inferior de la matriz. Típicamente esto se hace con una lista n (n + 1) / 2 de longitud. Deberá sobrecargar el método __getitem__ para interpretar el significado de la entrada.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top