You are on page 1of 29

Las matemáticas como

medio para medir la


eficiencia de los
Algoritmos
Computacionales
¿Qué es un algoritmo?
 “(del árabe al-Khowârizmî, sobrenombre
del célebre matemático árabe Mohámed
ben Musa). Conjunto ordenado y finito de
operaciones que permite encontrar la
solución a un problema…”

 Un algoritmo, puede expresarse en


términos de un lenguaje de programación,
para obtener un programa que resuelve el
problema por medio de la computadora.
Cita...
 “No hay un incremento concebible en el poder de las
computadoras que pueda saturar la demanda científica: aún
pensando que una computadora posea un ciclo de tiempo
subnuclear (10-23 seg.) y densidades de almacenamiento
subnucleares (1039 bits/cm3), ésta no podría manejar la
mayoría de los problemas que son importantes en la
investigación científica básica y aplicada. Por lo tanto, existirá
siempre una fuerte presión para incrementar la eficiencia de
los programas, para poder incrementar también la cantidad de
información últil generada por un programa.”
Ken Wilson, Nóbel de Física 1982
Áreas de estudio
 ¿Cómo construir algoritmos?
 Técnicas de diseño
 ¿Cómo expresar algoritmos?
 Enfoques de los lenguajes de programación
 ¿Cómo validar algoritmos?
 Verificación formal
 ¿Cómo analizar algoritmos?
 Complejidad computacional, eficiencia, legibilidad,
usabilidad, etc...
Análisis de algoritmos
 Si se tuvieran 2 programas que hacen lo
mismo, ¿cómo se podrían comparar?

1. Eficiencia:
 Tiempo de ejecución
 Uso de espacios de memoria
2. Facilidad de lectura, mantenimiento,
rapidez para codificarlo.
Medición del tiempo de
ejecución
 El tiempo de ejecución depende de:
1. La entrada al programa:
Su tamaño
Sus características
2. La calidad del código generado para el
programa por el compilador .
3. La rapidez de las instrucciones de
máquina.
4. La complejidad de tiempo del
algoritmo.
¿Cómo medir?
 Cantidad de instrucciones básicas (o
elementales) que se ejecutan.
 Ejemplos de instrucciones básicas:
 asignación de escalares
 lectura o escritura de escalares
 saltos (goto’s) implícitos o explícitos.
 evaluación de condiciones
 llamada a funciones
 etc.
Ejemplo
cont = 1; 1
while (cont <= n) do { n+1
n
x = x + a[cont];
n
x = x + b[cont];
n
cont = cont + 1; n (goto implícito)
} 1 goto en falso.

TOTAL: 5n + 3
Ejemplo
z = 0; 1
for (int x=1; x<=n; x++) 1 asignación + (n+1) comparaciones
for (int y=1; y<=n; y++) (n+2)*n = n2 +2n
z = z + a[x,y]; n*n = n2
2n2 (incremento + goto implícito)
n (goto en falso for y)
2n (incremento + goto implícito)
1 (goto en falso for x)

TOTAL: 4n2 + 6n + 4
Consecuencia…

 Se requiere contar con una notación que permita


comparar la eficiencia entre los algoritmos…
 La NOTACIÓN ASINTÓTICA es la propuesta de notación
aceptada por la comunidad científica para describir el
comportamiento en eficiencia (o complejidad) de un
algoritmo.
 Describe en forma sintética el comportamiento de la
función que con la variable de entrada, determina el
número de operaciones que realiza el algoritmo.
NOTACIÓN ASINTÓTICA
 COMPLEJIDAD TEMPORAL (y ESPACIAL).
Tiempo (o espacio) requerido por un algoritmo,
expresado en base a una función que depende
del tamaño del problema.
 COMPLEJIDAD TEMPORAL ASINTÓTICA (y
ESPACIAL). Comportamiento límite conforme el
tamaño del problema se incrementa. Determina
el tamaño del problema que puede ser resuelto
por un algoritmo.
Definición
 Se dice que la función f(n) “es de orden g(n)”
[O(g(n))], si existen constantes positivas c y n0
tales que f(n) <= c g(n) cuando n >= n0
 Ejemplos:
 n+5 es O(n) pues n+5 <= 2n para toda n >= 5
 (n+1)2 es O(n2) pues (n+1)2 <= 4n2 para n>= 1
 (n+1)2 NO es O(n) pues para cualquier c > 1
no se cumple que (n+1)2 <= c*n
Ordenes más comunes de los
algoritmos
 O(1) Constante
 O(n) Lineal
 O(n2 ) Cuadrático
 O(n3 ) Cúbico
 O (nm ) Polinomial
 O(log(n)) Logarítmico
 O(nlog(n)) nlog (n)
 O(mn ) exponencial
 O(n!) factorial
Comportamiento
de las funciones
n2

n sqrt(n

n log n

n
log n
Otro método para calcular el orden
de un problema
 Consiste en aplicar reglas a los estatutos
estructurados:
1.Secuencia de instrucciones
2.Decisiones (ejemplo: if)
3.Ciclos (ejemplo: while)
4.Recursividad
Regla 1: Secuencia de
instrucciones

O(g1(n))

O(g2(n)) ≈ O( mayor(g1(n), g2(n), …, gm(n) )


Ejemplo:
O(g3(n))  Una secuencia de 3 ciclos:
 Ciclo 1 = O(n)
 Ciclo 2 = O(log n)
 Ciclo 3 = O(n2)
O(gm(n))  Tendrá como orden total…
 O(n2).
Regla 2: Decisiones

≈ O( mayor(g1(n), g2(n)) )
O(g1(n))
Ejemplo:
 Una decisión con:
O(g2(n))  Rama then = O(n log n)
 Rama else = O(log n)
 Tendrá como orden total…
 O(n log n).
Regla 3: Ciclos

≈ O( m * g(n) )
O(g(n))
Ejemplo:
 Un ciclo cuya instrucción:
Se repite
 Tiene un O(log n)
m veces
 Se repite n/2 veces
 Tendrá como orden total…
 O(½ n log n) = O(n log n).
Consideraciones especiales
 En decisiones y ciclos anidados:
 Analizar el código desde la instrucción más
interna hacia el más externa.
 Tip para los ciclos:
 ¿“Normalmente” cuál es el orden de la
instrucción interna?
 Si la variable de control se incrementa o
decrementa con un valor constante: Orden
LINEAL.
 Si la variable de control se multiplica o divide por
un valor constante: Orden LOGARÍTIMICO.
Ejemplo: Sort por intercambio

for (int i=1; i<n; i++)


for (int j=i+1; j<=n;j++)
if (a[ j ] < a[ i ]) → O( 1 )
intercambia(a[ i ], a[ j ]); → O( 1 )

Regla 2: Decisiones = mayor de las 2 ramas


Ejemplo: Sort por intercambio

for (int i=1; i<n; i++) Peor caso: se repite n-1 veces
for (int j=i+1; j<=n;j++)
if (a[ j ] < a[ i ]) → O( n )
→ O( 1 )
intercambia(a[ i ], a[ j ]);

Regla 3: Ciclos = # veces * orden de la instrucción interna


Ejemplo: Sort por intercambio

Se repite n-1 veces


for (int i=1; i<n; i++)
for (int j=i+1; j<=n;j++)
→ O( n2 )
if (a[ j ] < a[ i ]) → O( n )
intercambia(a[ i ], a[ j ]);

Regla 3: Ciclos = # veces * orden de la instrucción interna


Ejemplo: Multiplicación de
matrices
a11 a12 … a1n b11 b12 … b1m
a21 a22 … a2n
… … … …
X b21 b22 … b2m =
… … … …
am1 am2 … amn bn1 bn2 … bnm

c11 c12 … c1m c11 = a11*b11+a12 *b21 +…+ a1n *bn1


c12 = a11*b12+a12 *b22 +…+ a1n *bn2
c21 c22 … c2m …
c21 = a21*b11+a22 *b21 +…+ a2n *bn1
… … … … …
cm1 cm2 … cmm cmm = am1*b1m+am2 *b2m +…+ amn *bnm
n
cij =  aikbkj
k=1
Ejemplo: Multiplicación de
matrices

O( n3 ) ← for i = 1 to n do
O( n2 ) ← for j = 1 to n do
O( 1 ) ← C[i,j] = 0;
O( n ) ← for k = 1 to n do
O( 1 ) ← C[i,j] = C[i,j] + A[i,k]*B[k,j];
Regla 4: Recursividad

 La complejidad de tiempo se obtiene contando la cantidad


de veces que se hace la llamada recursiva.
 Casos que “normalmente” se dan:
 Orden LINEAL si sólo se tiene una llamada recursiva,
con incrementos o decrementos en el parámetro de
control.
 Orden LOGARITMICO si sólo se tiene una llamada
recursiva, con multiplicaciones o divisiones en el
parámetro de control.
 Si hay más de una llamada recursiva, el orden puede
tender a ser EXPONENCIAL.
Ejemplo: Fibonacci (Iterativo)
ant = 1; --> 1
act = 1; --> 1
while (n>2){ --> n-2 + 1
aux = ant + act; --> n-2
ant = act; --> n-2
act = aux; --> n-2 T(n) = 6n-7
n = n - 1; --> n-2
} --> n-2+1 Por lo tanto el orden
write (act); --> 1 del algoritmo es
O(n)
Ejemplo: Fibonacci (recursivo)

Function fibonacci (n:int): int;


if (n < 3) return 1;
else return fibonacci(n-1) + fibonacci(n-2);
 ¿Cómo obtener la complejidad de tiempo
del algoritmo?
 Cantidad de llamadas recursivas: 2 en
cada llamada.
 Algoritmo de orden: O(2n/2)
Análisis de Fibonacci
(recursivo)
f(5) ¿Cuántos términos
se requieren para
f(3) f(4)
calcular:
f(1) f(2) f(2) f(3)
f(5)? --> 9
f(1) f(2) f(4)? --> 5
f(3)? --> 3
Relación:
f(2)? --> 1
El término T(n) requiere --> 15
T(n-1)+T(n-2)+1 términos f(6)?
para calcularse.
Análisis de Fibonacci
 Si el término T(n) requiere T(n-1)+T(n-
2)+1 términos para calcularse…
 se puede decir que T(n) > 2 * T(n-2) …
 y por lo tanto: T(n) > 2 * 2 * T(n-4) …
 y T(n) > 2 * 2 * 2 * T(n-6) … Por lo tanto:
T(n) > 2n/2
 y así sucesivamente hasta: y podemos decir
T(n) > 2 * 2 * 2 * …. * 2 * T(1) que el orden del
algoritmo es
O(2n/2)
n/2 veces

You might also like