Ejemplos 1
Matriz traspuesta
ALGORÍTMICA Y COMPLEJIDAD
Grados en Ing. Informática y Matemáticas
Universidad de Cantabria
Camilo Palazuelos Calderón
Definimos la función Trasponer
, que devuelve la traspuesta de la matriz cuadrada $\mathbf{A}$ que recibe como parámetro en forma de array bidimensional $A[0..\ell - 1, 0..\ell - 1]$.
def Trasponer(A):
return [[A[j][i] for j in range(len(A))] for i in range(len(A))]
Probamos la función con la matriz $\mathbf{A} = \begin{pmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9 \end{pmatrix}$. Trasponer(
$A[0..2, 0..2]$)
debería devolver $\begin{pmatrix} 1 & 4 & 7 \\ 2 & 5 & 8 \\ 3 & 6 & 9 \end{pmatrix}$.
A = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(f'Trasponer({A}) = {Trasponer(A)}')
Trasponer([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) = [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
Para evaluar el coste temporal empírico de Trasponer
, creamos un array bidimensional $B[0..m - 1, 0..m - 1]$ de ceros y unos con $m$ suficientemente grande (por ejemplo, $m = 10^4$). Iterativamente, traspondremos las primeras $n$ filas y $n$ columnas de $B[0..m - 1, 0..m - 1]$ y añadiremos el coste temporal empírico de Trasponer(
$B[0..n - 1, 0..n - 1]$)
a una lista $T$.
m = 10000
B = [[i % 2 for _ in range(m)] for i in range(m)]
T = [0]
Modificamos Trasponer
para acceder a fragmentos de posiciones consecutivas de $B[0..m - 1, 0..m - 1]$ y evitar así crear arrays de entrada en cada iteración. Para ello, añadimos un parámetro $n$ a la cabecera de la función tal que $n \le m$.
def Trasponer2(A, n):
return [[A[j][i] for j in range(n)] for i in range(n)]
Trasponer2(B, 5)
[[0, 1, 0, 1, 0], [0, 1, 0, 1, 0], [0, 1, 0, 1, 0], [0, 1, 0, 1, 0], [0, 1, 0, 1, 0]]
Evaluamos el coste temporal empírico de Trasponer2
con matrices cuadradas de orden $n$ desde $1 \cdot 10^3$ hasta $10 \cdot 10^3$ (de $10^3$ en $10^3$).
import time
for n in range(m // 10, m + 1, m // 10):
t = time.time()
Trasponer2(B, n)
T.append(time.time() - t)
#print(f'Iteración {n // (m // 10)} de 10')
Dibujamos una gráfica con el tiempo de ejecución $T(n)$ de Trasponer2
en función del orden $n$ de las matrices cuadradas de entrada.
import matplotlib.pyplot as plt
import numpy as np
with plt.style.context('ggplot'):
plt.plot(np.array(T), label = '$T(n) \in O(n^2)$')
plt.xticks(
[ x for x in range(0, 11, 2)],
[f'${x} \cdot 10^3$' for x in range(0, 11, 2)])
plt.xlabel( '$n$', fontsize = 12)
plt.ylabel('$T(n)$ en s', fontsize = 12)
plt.title('Complejidad temporal')
plt.legend()
plt.show()