En esta parte analizaremos como usarlos,
ponerlos en practica y aprobar en
los exámenes. (Siento tardar tanto en
subirlo,
estuve muy ocupado en la escuela)
Analisis:
Recursos De Computadores Y Complejidad
Algoritmo: Conjunto de reglas para resolver un problema. Su ejecución requiere unos recursos.
Un algoritmo es mejor cuantos menos recursos consuma, su facilidad de programarlo, corto, fácil de entender, robusto, etc.
Criterio empresarial: Maximizar la eficiencia.
Eficiencia: Relación entre los recursos consumidos y los productos conseguidos.
Recursos consumidos:
Tiempo de ejecución.
Memoria principal:
Entradas/salidas a disco.
Comunicaciones, procesadores, etc.
Lo que se consigue:
Resolver un problema de forma exacta, forma aproximada o algunos casos.
Recursos consumidos:
Ejemplo. ¿Cuántos recursos de tiempo y memoria consume el siguiente algoritmo sencillo?
i:= 0
a[n+1]:= x
repetir
i:= i + 1
hasta a[i] = x
Respuesta: Depende.
¿De qué depende? De lo que valga n y x, de lo que haya en a, de los tipos de datos, de la máquina...
En general los recursos dependen de:
Factores externos.
El ordenador donde lo ejecutemos: 286, Pentium III, Cray,...
El lenguaje de programación y el compilador usado.
La implementación que haga el programador del algoritmo. En particular, de las estructuras de datos utilizadas.
Tamaño de los datos de entrada.
Ejemplo. Calcular la media de una matriz de NxM.
Contenido de los datos de entrada.
Mejor caso. El contenido favorece una rápida ejecución.
Peor caso. La ejecución más lenta posible.
Caso promedio. Media de todos los posibles contenidos.
Los factores externos no aportan información sobre el algoritmo.
Conclusión: Estudiar la variación del tiempo y la memoria necesitada por un algoritmo respecto al tamaño de la entrada y a los posibles casos, de forma aproximada (y parametrizada).
externos no aportan información sobre el algoritmo.
Normalmente usaremos la notación T(N)=..., pero ¿qué significa T(N)?
Tiempo de ejecución en segundos. T(N) = bN + c.
Suponiendo que b y c son constantes, con los segundos que tardan las operaciones básicas correspondientes.
Instrucciones ejecutadas por el algoritmo. T(N) = 2N + 4.
¿Tardarán todas lo mismo?
Ejecuciones del bucle principal. T(N) = N+1.
¿Cuánto tiempo, cuántas instrucciones,...?
Sabemos que cada ejecución lleva un tiempo constante, luego se diferencia en una constante con los anteriores.
Asignación de tiempos, para el conteo de instrucciones. Algunas reglas básicas.
Operaciones básicas (+, -, *, :=,...): Una unidad de tiempo, o alguna constante.
Operaciones de entrada salida: Otra unidad de tiempo, o una constante diferente.
Bucles FOR: Se pueden expresar como una sumatoria, con los límites del FOR.
IF y CASE: Estudiar lo que puede ocurrir. Mejor caso y peor caso según la condición. ¿Se puede predecir cuándo se cumplirán las condiciones?
Llamadas a procedimientos: Calcular primero los procedimientos que no llaman a otros.
Bucles WHILE y REPEAT: Estudiar lo que puede ocurrir. ¿Existe una cota inferior y superior del número de ejecuciones? ¿Se puede convertir en un FOR?
El análisis de algoritmos también puede ser a posteriori: implementar el algoritmo y contar lo que tarda para distintas entradas.
Ejemplo. Programa “cifras.exe”:
N= 4, T(4)= 0.1 ms
N= 5, T(5)= 5 ms
N= 6, T(6)= 0.2 s
N= 7, T(7)= 10 s
N= 8, T(8)= 3.5 min
¿Qué conclusiones podemos extraer?
Análisis a priori: Evitamos la implementación, si el algoritmo es poco eficiente. Podemos hacer previsiones. Podemos comparar con otros algoritmos.
Medidas Asintoticas
Notación asintótica:
El tiempo de ejecución T(n) está dado en base a unas constantes que dependen de factores externos.
Nos interesa un análisis que sea independiente de esos factores.
Notaciones asintóticas: Indican como crece T, para valores suficientemente grandes (asintóticamente) sin considerar constantes.
O(T): Orden de complejidad de T.
W(T): Orden inferior de T, u omega de T.
Q(T): Orden exacto de T.
Orden de complejidad de f(n): O(f)
Dada una función f: N ® R+, llamamos orden de f al conjunto de todas las funciones de N en R+ acotadas superiormente por un múltiplo real positivo de f, para valores de n suficientemente grandes.
O(f)= { t: N ® R+ / $ c Î R+, $ n0 Î N, " n ³ n0: t(n) £ c" f(n) }
Nota:
O(f) es un conjunto de funciones, no una función.
“Valores de n sufic. Grandes...”: no nos importa lo que pase para valores pequeños.
“Funciones acotadas superiormente por un múltiplo de f...”: nos quitamos las constantes.
La definición es aplicable a cualquier función de N en R, no sólo tiempos de ejec.
Propiedades
P1. Si f Î O(g) y g Î O(h) entonces f Î O(h).
Si f Î W(g) y g Î W(h) entonces f Î W(h)
Ej. 2n+1 Î O(n), n Î O(n2) Þ 2n+1 Î O(n2)
P2. Si f Î O(g) entonces O(f) Í O(g).
¿Cómo es la relación para los W?
P3. Dadas f y g de N en R+, se cumple:
i) O(f) = O(g) Û f Î O(g) y g Î O(f)
ii) O(f) Í O(g) Û f Î O(g)
¿La relación de orden entre O(..) es completa? Dadas f y g, ¿se cumple O(f)ÍO(g) ó O(g)ÍO(f)?
P4. Dadas f y g, de N en R+, O(f+g) = O(max(f, g)).
W(f+g) = W(max(f+g))
¿Y para los Q(f+g)?
¿Es cierto que O(f - g) = O(max(f, -g))?
P5. Dadas f y g de N en R+, se cumple:
i) limn¥® f(n) Î R+ Þ O(f)=O(g), W(f)=W(g), Q(f)=Q(g)
g(n)
ii) limn¥® f(n) = 0 Þ O(f) Í O(g), W(g) Í W(f)
g(n)
P5. Ej. ¿Qué relación hay entre O(log2 n) y O(log10 n)?
P6. Dadas f y g de N en R+, O(f)=O(g) Û Q(f)=Q(g) Û f Î Q(g) Û W(f)=W(g)
P7. Dadas f y g de N en R+, se cumple:
i) limn¥® f(n) Î R+ Þ O(f) = O(g)
g(n)
ii) limn¥® f(n) = 0 Þ O(f) Ì O(g)
g(n)
iii) limn¥® f(n) = +¥ Þ O(f) É O(g)
g(n)
Notación con varios parámetros:
En general, el tiempo y la memoria consumidos pueden depender de muchos parámetros.
f: Nm ® R+ (f: Nx...m..xN ® R+)
Ej. Memoria en una tabla hash. M(B,n, l, k) = kB+l+n+2kn
Orden de complejidad de f(n1, n2, ..., nm): O(f)
Dada una función f: Nm ® R+, llamamos orden de f al conjunto de todas las funciones de Nm en R+ acotadas superiormente por un múltiplo real positivo de f, para valores de (n1, ..., nm) suficientemente grandes.
O(f)= { t: Nm ® R+ / $ c Î R+, $ n1, n2, .., nm Î N, " k1 ³ n1 ,
k2 ³ n2 ,..," km ³ nm : t(k1, k2, ..., km) £ c" f(k1, k2, ..., km) }
De la misma forma, podemos extender los conceptos de W(f) y Q(f), para funciones con varios parámetros.
Las propiedades se siguen cumpliendo ® Demostrarlo.
Ejemplo. T(N) = T(N, a, b) = a" N + b
El tiempo depende del tamaño del problema N, y del tiempo de inicialización b y de ejecución de un paso a.
Podemos suponerlos constantes T(N), o variables T(N,a,b).
¿Qué relación hay entre los siguientes órdenes?
O(n+m), O(nm) O(n2), O(n+2m)
Notaciones condicionales:
En algunos casos interesa estudiar el tiempo sólo para ciertos tamaños de entrada.
Ejemplo. Algoritmo de búsqueda
BINARIA
: Si N es potencia de 2 el estudio se simplifica.
Orden condicionado de f(n): O(f | P)
Dada una función f: N ® R+, y P: N ® B, llamamos orden de f según P (o condicionado a P) al conjunto:
O(f | P)= { t: N ® R+ / $ c Î R+, $ n0 Î N, " n ³ n0:
P(n) Þ t(n) £ c" f(n) }
De igual forma, tenemos W(f | P) y Q(f | P).
O(f) = O(f | true). Para cualquier f y g, f Î O(g | false).
¿O(f) « O(f | P)?
Ordenes De Complejidad
Uso de los órdenes de complejidad:
Dado un tiempo t(n), encontrar la función f más simple tal que t Î O(f), y que más se aproxime asintóticamente.
Ejemplo. t(n) = 2n2/5 + 3p/2; t(n) Î O(n2).
•
•Relación de orden entre O(..) = Relación de inclusión entre conjuntos.
-O(f) £ O(g) Û O(f) Í O(g) Û Para toda t Î O(f), t Î O(g)
•Se cumple que:
O(c) = O(d), siendo c y d constantes positivas.
O(c) Ì O(n)
O(cn + b) = O(dn + e)
O(p) = O(q), si p y q son polinomios del mismo grado.
O(p) Ì O(q), si p es un polinomio de menor grado que q.
Orden inferior u omega de f(n): W(f):
Dada una función f: N ® R+, llamamos omega de f al conjunto de todas las funciones de N en R+ acotadas inferiormente por un múltiplo real positivo de f, para valores de n suficientemente grandes.
W(f)= { t: N ® R+ / $ c Î R+, $ n0 Î N, " n ³ n0: t(n) ³ c" f(n) }
La notación omega se usa para establecer cotas inferiores del tiempo de ejecución.
Relación de orden: igual que antes.
Orden exacto de f(n): Q(f):
Dada una función f: N ® R+, llamamos orden exacto de f al conjunto de todas las funciones de N en R+ que crecen igual que f, asintóticamente y salvo constantes.
Q(f) = O(f) Ç W(f) =
= { t: N ® R+ / $ c, d Î R+, $ n0 Î N, " n ³ n0: c" f(n) ³ t(n) ³ d" f(n) }
Notación o pequeña de f(n): o(f):
Dada una función f: N ® R+, llamamos o pequeña de f al conjunto de todas las funciones de N en R+ que crecen igual que f asintóticamente:
o(f)= { t: N ® R+ / lim t(n)/f(n) = 1}n¥®
Esta notación conserva las constantes multiplicativas para el término de mayor orden.
Ejemplo. t(n) = amnm + am-1nm-1 + ... +a1n + a0
t(n) Î o(amnm) ¹ o(nm)
¿o(amnm) Í O(amnm)? ¿o(t) Í O(t)?
Costa de complejidad con frecuencia
Algunas relaciones entre órdenes frecuentes:
O(1) Ì O(log n) Ì O(n) Ì O(n" log n) Ì O(n" (log n)2) Ì O(n1.001...) Ì O(n2) Ì O(n3) Ì ... Ì O(2n) Ì O(n!) Ì O(nn)
¿Qué pasa con las omegas? ¿Y con los órdenes exactos?
El orden de un polinomio anxn+...+a1x+a0 es O(xn).
n n n
å1 = n Î O(n); åi = n(n+1)/2 Î O(n2); åim Î O(nm+1)
i=1 i=1 i=1
Si hacemos una operación para n, otra para n/2, n/4, ..., aparecerá un orden logarítmico O(log2 n). Los logaritmos son del mismo orden, independientemente de la base.