Sie sind auf Seite 1von 23

Análisis y Diseño de Algoritmos

Análisis de Algoritmos
Cesar Liza Avila

website : www.cesarliza.com
e-mail : creadores@hotmail.com

César Liza Avila www.cesarliza.com


Eficiencia de Algoritmos
Siempre que elaboremos un algoritmo debemos preocuparnos en
analizar su eficiencia.

Esto implica determinar la cantidad de recursos que utiliza:

a) Cantidad de memoria
b) Tiempo de cómputo requerido

Estos dos parámetros nos permiten comparar dos algoritmos que


resuelven el problema.

César Liza Avila www.cesarliza.com


Cantidad de memoria
Se puede determinar fácilmente por el número y tamaño de las
variables.

Tiempo de ejecución
Se determina por el número de operaciones elementales.

Compromiso espacio- tiempo


Se reduce el espacio de almacenamiento con un incremento
del tiempo de ejecución

César Liza Avila www.cesarliza.com


Lo que consideramos en este curso

Nosotros limitaremos nuestro análisis al tiempo de ejecución, pues


la memoria es barata en comparación al tiempo del procesador, y
además es fácil calcular cuanta memoria se necesitará.

Debe tenerse en cuenta que la memoria puede llegar a ser un


recurso muy escaso, tal como ocurre en los sistemas empotrados.

César Liza Avila www.cesarliza.com


Medida del Tiempo de Ejecución

El tiempo de ejecución depende de la cantidad de datos a procesar.

Sin embargo, el “tiempo de reloj” depende de la velocidad de la


máquina, el software que se esta ejecutando (sistema operativo y
otros), por lo que no puede ser una medida adecuada.

Es por esto que necesitamos una medida independiente de la


implementación, entonces asumimos el modelo de computación
llamado Máquina de Acceso Directo (MAD). Aquí se usan un
conjunto básico de operaciones una detrás de otra, sin operaciones
concurrentes (en simultáneo).

César Liza Avila www.cesarliza.com


Sin usar fórmula calcule la suma de
los primeros n números naturales
PsuedoCódigo
Leer n t1 se ejecuta 1 vez
suma=0 t2 se ejecuta 1 vez
Para i=1 hasta i=n t3 se ejecuta n veces
suma=suma +i t4 se ejecuta n veces
Imprimir suma t5 se ejecuta 1 vez

Tiempo total de ejecución = t1 + t2 + t3.n + t4.n + t5


T(n) = (t1 + t2 + t5)+ (t3 + t4).n

Note que los tiempos son valores que se pueden obtener una vez conocida la
máquina en la que se ejecutará.

El tiempo total de cálculo depende del tamaño de la entrada n, sea cual fuera
la máquina en la que correrá. Así que podríamos decir que este algoritmo
tiene tiempo de ejecución que depende de n.

César Liza Avila www.cesarliza.com


La Notación Asintótica

La notación asintótica se emplea para mostrar el


comportamiento de una función respecto a otra.

Puede indicar que dos funciones son aproximadamente iguales


o que una crece mas rápidamente que la otra.

César Liza Avila www.cesarliza.com


Cota superior asintótica
Es una función que sirve como cota
superior de otra función cuando el
argumento tiende al infinito

La Notación “O Grande”
Para expresar la cota superior asintótica de una función, se usa la
notación “O Grande”. Matemáticamente:

La función f(x) esta acotada por O( g(x) ), si existe una constante c, a


partir de un punto inicial (+), de tal forma que si tomamos cualquier otro
punto la función f(x) es menor que la otra.

César Liza Avila www.cesarliza.com


Cota inferior asintótica
Es una función que sirve como cota
inferior de otra función cuando el
argumento tiende al infinito

La Notación “Omega Grande”


Para expresar la cota inferior asintótica de una función, se usa la
notación “Ω Grande”. Matemáticamente:

La función f(x) esta acotada inferiormente por Ω ( g(x) ), si existe una


constante c, a partir de un punto inicial (+), de tal forma que si tomamos
cualquier otro punto la función f(x) es mayor que la otra.

César Liza Avila www.cesarliza.com


Cota ajustada asintótica
Es una función que sirve tanto de cota
superior como de cota inferior de otra
función cuando el argumento tiende al
infinito.

La Notación “Theta Grande”


Para expresar la cota ajustada asintótica de una función, se usa la
notación “Θ Grande”. Matemáticamente:

La función f(x) puede ser acotada por Θ ( g(x) ), tanto inferior como
superiormente, cuando usamos constantes diferentes.

César Liza Avila www.cesarliza.com


Resumen:
Cota Superior asintótica usa notación “O Grande”
Cota Inferior asintótica usa notación “Omega Grande”
Cota Ajustada asintótica usa notación “Theta Grande”

César Liza Avila www.cesarliza.com


Relaciones entre O,  y 

César Liza Avila www.cesarliza.com


Ejemplo:
Sea la función f(x) = x+10, obtenga una cota superior, inferior y ajustada.

Cota Superior asintótica:


Podemos decir que la función g(x) = x2, es una cota superior cuando x>=1,
y c=11, ya que siempre se cumple que x+10<=<=11x2 cuando x>=1.

Haciendo uso de la notación “O Grande” diremos: f(x) = O(x2)

Cota Inferior asintótica:


Podemos decir que la función g(x) =x, es una cota inferior asintótica,
cuando x>=1 y c=1, ya que siempre se cumple que 1x<=x+10, cuando x>=1
Haciendo uso de la notación “Omega Grande” diremos f(x) = Ω(x)

Cota Ajustada asintótica:


Podemos decir que la función g(x) = x, es una cota superior asintótica,
cuando x>=1, y c1=1, y es una cota inferior asintótica, cuando x>=1, y
c2=11, ya que siempre se cumple:
1x <= x+10<=11x, cuando x>=1.
Haciendo uso de la notación “Θ Grande” diremos: f(x) = Θ(x)

César Liza Avila www.cesarliza.com


Entonces pues, dado un programa nos interesa obtener una función que
represente la cantidad de unidades de tiempo, para luego acotar esta
función.
A esto se le conoce como cálculo de la complejidad de un algoritmo.

Reglas para el cálculo de complejidad


Aunque no hay una receta que funcione siempre, daremos algunas
pautas de cómo calcular la complejidad de un algoritmo para diferentes
casos:

• Sentencias Simples
• Condicionales
• Bucles
• Llamadas a función
• Secuencias de instrucciones

César Liza Avila www.cesarliza.com


a) Sentencias simples
Cuando en un algoritmo intervienen sentencias simples, como
asignación, entrada o salida e datos, requieren un tiempo constante de
ejecución por lo que su complejidad será:
O(1)

Esto no incluye aquellas variables cuyo tamaño esta relacionado con el


tamaño del problema.

Por ejemplo no puedo considerar la suma de dos números gigantes


como sentencia simple.

César Liza Avila www.cesarliza.com


b) Condicionales
La evaluación de una expresión condicional requiere por lo general un
tiempo constante de ejecución por lo que su complejidad será O(1).

La complejidad que debe sumarse con la peor de las ramas ya sea las
instrucciones a ejecutar de ser verdadera o falsa la condición.

En decisiones múltiples (else if, switch case) se tomará la peor de las


ramas.

c) Bucles
Si el bucle tiene un contador de tamaño conocido entonces se multiplica
esa cantidad de veces por la sentencia de peor complejidad.

César Liza Avila www.cesarliza.com


d) Llamadas a funciones
Viene dada por la complejidad de sus sentencias. El costo de la
invocación a la función y su retorno se consideran constantes y se puede
obviar para el análisis asintótico.

El cálculo de la complejidad de una función se puede complicar si se


trata de funciones recursivas, las cuales estudiaremos mas adelante.

e) Secuencias de instrucciones
La complejidad de una secuencia de instrucciones es la suma de sus
complejidades individuales, debiendo aplicar todo lo anterior.

César Liza Avila www.cesarliza.com


Jerarquía de Ordenes de Complejidades

O(1) Orden constante


O(log n) Orden logarítmico
O(n) Orden lineal
O(n log n) Orden cuasi-lineal
O(n2) Orden cuadrático
O(n3) Orden cúbico
O(na) Orden polinómico
O(2n) Orden exponencial
O(n!) Orden factorial

César Liza Avila www.cesarliza.com


O(1): Complejidad constante. Cuando las instrucciones se
ejecutan una vez.

O(log n): Complejidad logarítmica. Esta suele aparecer en


determinados algoritmos con iteración o recursión no
estructural, ejemplo la búsqueda binaria.

O(n): Complejidad lineal. Es una complejidad buena y


también muy usual. Aparece en la evaluación de bucles
simples siempre que la complejidad de las instrucciones
interiores sea constante.

O(n log n): Complejidad cuasi-lineal. Se encuentra en


algoritmos de tipo divide y vencerás como por ejemplo en el
método de ordenación quicksort y se considera una buena
complejidad. Si n se duplica, el tiempo de ejecución es
ligeramente mayor del doble.
César Liza Avila www.cesarliza.com
O(n2): Complejidad cuadrática. Aparece en bucles o ciclos
doblemente anidados. Si n se duplica, el tiempo de ejecución
aumenta cuatro veces.

O(n3): Complejidad cúbica. Suele darse en bucles con triple


anidación. Si n se duplica, el tiempo de ejecución se
multiplica por ocho. Para un valor grande de n empieza a
crecer dramáticamente.

O(na): Complejidad polinómica (a > 3). Si a crece, la


complejidad del programa es bastante mala.

O(2n): Complejidad exponencial. No suelen ser muy útiles en


la práctica por el elevadísimo tiempo de ejecución. Se dan en
subprogramas recursivos que contengan dos o más llamadas
internas.
César Liza Avila www.cesarliza.com
Las constantes de proporcionalidad pueden alterar esta
consideración.

Ejemplo
Un programa emplea 100n unidades de tiempo para ser
ejecutado, otro programa emplea 2n2.

¿Cual de los dos programas es mejor?


Depende del tamaño del problema.
Para n < 50, el programa con tiempo 2n2 es mejor.
Para problemas con entrada de datos pequeño, es
preferible usar el programa cuyo tiempo de ejecución
es O(n2).
Sin embargo, cuando n crece, el programa con
tiempo de ejecución O(n2) emplea mas tiempo que el
programa O(n).
César Liza Avila www.cesarliza.com
Calcular la complejidad del siguiente
algoritmo

funcion( int n)
{
int i, j, k, x;
x=0;
para i=1 hasta n-1 hacer
para j=i+1 hasta n hacer
para k=1 hasta j hacer
x=x+1
}

César Liza Avila www.cesarliza.com


El bucle mas interno repite j veces una instrucción de tiempo O(1)
j
∑1 o sea la instrucción simple x=x+1 se realiza j veces.
k=1 funcion( int n)
{
El segundo bucle mas interno int i, j, k, x;
x=0;
n para i=1 hasta n-1 hacer
∑ j = n (n+1)/2 – i (i+1)/2 para j=i+1 hasta n hacer
para k=1 hasta j hacer
j=i+1 x=x+1
}
El tercer bucle (el externo) tenemos
n-1 n-1 n-1
∑ [ n (n+1)/2 – i (i+1)/2 ] = ∑ n (n+1)/2 – ∑ i (i+1)/2
i=1 i=1 i=1
n-1
= (n-1) n (n+1) / 2 - 1/2 ∑ (i2+i)
i=1

n-1
= (n-1) n (n+1) / 2 - 1/2 ∑ (i2+i)
i=1
= (n-1) n (n+1) / 2 - 1/2. (n-1)(n)(2n-1)/6 – 1/2.(n-1)n/2
= n(n2-1)/3
ε (n3)
César Liza Avila www.cesarliza.com

Das könnte Ihnen auch gefallen