Matrices Dispersas

Anuncio
Matrices Dispersas
Un ejemplo de aplicación de POO en
Python.
Introducción a la Computación
Clase 24
Patricia Borensztejn
Diccionarios y Tuplas
• Refrescamos diccionarios porque los vamos a
usar para representar matrices dispersas.
Tupla
• La tupla es una secuencia heterogénea de
elementos, accesible a través de un índice.
• Las tuplas se diferencian de las listas porque
las tuplas no son objetos dinámicos, por lo
tanto son INMUTABLES, como las cadenas y
como los escalares.
• Se declaran usando como separador una coma
Tuplas y Listas
• Las tuplas se acceden mediante un índice.
• Pero:
>>> t = ("a", "b", "mpilgrim", "z", "example")
>>> t ('a', 'b', 'mpilgrim', 'z', 'example')
>>> t[0]
'a'
>>> t[-1]
'example'
>>> t[1:3]
('b', 'mpilgrim')
– No se pueden modificar
– No existen métodos o funciones para trabajar con
ellas
– Entonces… para que sirven?
Diccionarios
• También llamados matrices asociativas,
relacionan una clave y un valor.
• Por ejemplo:
d = {“Nueve Reinas “: “Fabián Bielinsky”,
“Kill Bill”: “Tarantino”,
“Amélie”: “Jean-Pierre Jeunet”}
• El primer valor es la clave, y el segundo es el
valor.
• Como clave podemos utilizar cualquier valor
inmutable: números, cadenas, booleanos, tuplas
(para eso sirven!)
Diccionarios
• El acceso a los valores almacenados no se
realiza a través de un índice como en el caso
de las listas o las tuplas, sino por medio de su
clave.
• Asi:
d [“Nueve Reinas “] # devuelve “Fabián Bielinsky”,
• Se pueden asignar valores a los valores.
• NO se pueden obtener claves usando los
valores.
Algunos métodos del tipo Diccionario
dict.clear()
elimina todos los elementos del
diccionario dict
dict.get(clave,[default])
devuelve el valor de la clave o lo que
definamos por defecto si la clave no se
encuentra en el diccionario
dict.has_key(clave)
devuelve 1 si la clave se encuentra en el
diccionario. En cualquier otro caso
devuelve 0.
dict.items()
devuelve una lista de pares de tuplas
clave-valor.
dict.keys()
devuelve una lista de claves
dict.values()
devuelve la lista de valores
dict.update(dict2)
añade los pares clave-valor del diccionario
dict2 al diccionario dict
Matriz Dispersa
• Podemos almacenarla con un diccionario cuya
clave sea una tupla=(i,j)
valores
clave: tuplas
Matriz Dispersa
• Problema: si accedemos a un elemento nulo,
como no existe la clave, tenemos un error.
>>> matriz = {(0,3):1,(2,1):1,(4,3):3}
>>> matriz[0,3]
1
>>> matriz[0,0]
Traceback (most recent call last):
File "<pyshell#2>", line 1
matriz[0,0]
KeyError: (0, 0)
>>>
Matriz Dispersa
• Cuidarnos de no acceder elementos nulos….
Clase MatrizDispersa
• Queremos implementar una clase que herede
todos los métodos del tipo diccionario.
• Entonces definimos así:
class sparse(dict):
"""
Formato del Diccionario: { (i,j): value, ... }
donde (i,j) son los índices de la matriz
"""
pass
• No tiene __init__. La usamos.
>>> A=sparse()
>>> A={(0,0):1,(2,4):7}
>>> print A
{(0, 0): 1, (2, 4): 7}
Clase Matriz Dispersa
• Agregamos un método para imprimir la matriz
dispersa
class sparse(dict):
def out(self):
print '# (i, j) -- value'
for k in self.keys():
print k, self[k]
Imprimir
• Fíjense que como la implementación es con
diccionario, no hay orden.
a = sparse({(0,0):2.0, (0,1):1.0, (1,0):1.0, (1,1):2.0, (1,2):1.0, (2,1):1.0, (2,2):2.0})
print "a=", a
a.out()
>>>
a= {(0, 1): 1.0, (1, 2): 1.0, (0, 0): 2.0, (2, 2): 2.0, (1, 0): 1.0, (1, 1): 2.0, (2, 1): 1.0}
# (i, j) -- value
(0, 1) 1.0
(1, 2) 1.0
(0, 0) 2.0
(2, 2) 2.0
(1, 0) 1.0
(1, 1) 2.0
(2, 1) 1.0
Imprimir en orden
• Agregamos un método para imprimir la matriz
dispersa, pero manteniendo el orden
class sparse(dict):
def out(self):
print '# (i, j) -- value'
for k in self.keys():
print k, self[k]
def out2(self):
print '# (i, j) -- value'
indice=self.keys()
indice.sort()
for k in indice:
print k, self[k]
Imprimir en orden
a = sparse({(0,0):2.0, (0,1):1.0, (1,0):1.0, (1,1):2.0, (1,2):1.0, (2,1):1.0, (2,2):2.0})
print "a=", a
a.out2()
a= {(0, 1): 1.0, (1, 2): 1.0, (0, 0): 2.0, (2, 2): 2.0, (1, 0): 1.0, (1, 1): 2.0, (2, 1): 1.0}
# (i, j) -- value
(0, 0) 2.0
(0, 1) 1.0
(1, 0) 1.0
(1, 1) 2.0
(1, 2) 1.0
(2, 1) 1.0
(2, 2) 2.0
Imprimir
• Ahora me interesa imprimir la matriz
completa.
class sparse(dict):
def size(self):
" returns # of rows and columns "
nrow = 0
ncol = 0
for key in self.keys():
nrow = max([nrow, key[0]+1])
ncol = max([ncol, key[1]+1])
return (nrow, ncol)
def imprime_completa(self):
nrow,ncol=self.size()
for i in range (0,nrow):
for j in range (0,ncol):
print str(self.get((i,j),0.0)),
print "\n"
Imprimir Matriz Dispersa
a= {(0, 1): 1.0, (1, 2): 1.0, (0, 0): 2.0, (2, 2): 2.0, (1, 0): 1.0, (1, 1): 2.0, (2, 1): 1.0}
# (i, j) -- value
(0, 0) 2.0
(0, 1) 1.0
(1, 0) 1.0
(1, 1) 2.0
(1, 2) 1.0
(2, 1) 1.0
(2, 2) 2.0
2.0 1.0 0.0
1.0 2.0 1.0
0.0 1.0 2.0
Vamos a sumar y restar matrices
dispersas
def __add__(self, other):
res = sparse(self.copy())
for ij in other:
res[ij] = self.get(ij,0.) + other[ij]
return res
def __sub__(self, other):
res = sparse(self.copy())
for ij in other:
res[ij] = self.get(ij,0.) - other[ij]
return res
Ejercicio
• Multiplicar matrices dispersas.
• Para multiplicar dos matrices dispersas, a y b,
el número de filas de a debe ser igual al
número de columnas de b. Esa condición debe
comprobarse, y en caso de que no se cumpla,
se debe generar un mensaje de error.
Descargar