0% encontró este documento útil (0 votos)
33 vistas42 páginas

4 - Análisis de Algorítmos

Este documento analiza diferentes métodos para evaluar la eficiencia de los algoritmos, incluyendo estudios experimentales, contando operaciones primitivas y analizando el caso peor. También introduce las siete funciones más importantes utilizadas en el análisis de algoritmos.

Cargado por

maria
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PPTX, PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
33 vistas42 páginas

4 - Análisis de Algorítmos

Este documento analiza diferentes métodos para evaluar la eficiencia de los algoritmos, incluyendo estudios experimentales, contando operaciones primitivas y analizando el caso peor. También introduce las siete funciones más importantes utilizadas en el análisis de algoritmos.

Cargado por

maria
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PPTX, PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 42

Análisis de Algorítmos

Unidad 4

Algorítmica y Programación II Lic. Renato Mazzanti


Estudios experimentales
• Una manera de estudiar la eficiencia de un algoritmo es
implementarlo y experimentar ejecutando el programa
en varias entradas de prueba mientras se registra el
tiempo gastado durante cada ejecución.
• Para recopilar estos tiempos de ejecución en Java se basa
en el uso del método currentTimeMillis de la clase
System.
• Ese método informa el número de milisegundos que han
pasado desde un tiempo de referencia conocido como la
época (siglo, parte temporal?) (1 de enero de 1970 UTC).

Algorítmica y Programación II
Estudios experimentales
• Podemos medir el tiempo transcurrido
(elapsed time) de la ejecución de un algoritmo.
¿cómo?

• Para operaciones extremadamente rápidas,


Java proporciona un método, nanoTime, que
mide en nanoseconds
Algorítmica y Programación II
Estudios experimentales
• ¿Por qué estamos interesados en la
dependencia general del tiempo de ejecución
sobre el tamaño y la estructura de la entrada?
• Podemos graficar cada ejecución del algoritmo
como un punto con coordenada x igual al
tamaño de la entrada, n, y coordenada y igual
al tiempo de ejecución, t.
• Relación entre el tamaño del problema y el
tiempo de ejecución del algoritmo.
Algorítmica y Programación II
Estudios experimentales
• Esto puede ir seguido por un análisis estadístico
que busca ajustar la mejor función del tamaño de
entrada a los datos experimentales.
• Este análisis requiere que escojamos buenos datos
de muestra y probemos bastantes de ellos para ser
capaces de hacer afirmaciones estadísticas sobre
el tiempo de ejecución del algoritmo.
• ¿tiene algún efecto la plataforma donde se ejecuta
el algorítmo sobre los resultados obtenidos de este
modo?
Algorítmica y Programación II
Estudios experimentales
repeat('*', 40)

Algorítmica y Programación II
Estudios experimentales
• Mientras repeat1 ya está tardando más de 3 días en
componer una cadena de 12.8 millones de caracteres,
repeat2 es capaz de hacer lo mismo en una fracción de
segundo.
• También vemos algunas tendencias interesantes en cómo
los tiempos de ejecución de los algoritmos dependen cada
uno del tamaño de n.
• A medida que el valor de n se duplica, el tiempo de
ejecución de repeat1 aumenta más de cuatro veces,
mientras que el tiempo de ejecución de repeat2 se
duplica, aproximadamente.
Algorítmica y Programación II
Desafíos del análisis experimental
• Los tiempos de ejecución experimentales de dos
algoritmos son difíciles de comparar directamente a menos
que los experimentos se realicen en los mismos entornos
de hardware y software.
• Los experimentos pueden hacerse solamente en un
conjunto limitado de datos de prueba; por lo tanto, dejan
fuera los tiempos de ejecución de los datos no incluidos en
el experimento (y estos datos pueden ser importantes).
• Un algoritmo debe ser completamente implementado para
ejecutarlo para estudiar experimentalmente su tiempo de
ejecución.

Algorítmica y Programación II
Más allá del análisis experimental
• Nuestro objetivo es desarrollar un enfoque para
analizar la eficiencia de los algoritmos que:
1. Nos permita evaluar la eficiencia relativa de
cualquiera de los dos algoritmos de una manera
que sea independiente del entorno de hardware y
software.
2. Se realiza estudiando una descripción de alto nivel
del algoritmo sin necesidad de implementación.
3. Que tome en cuenta todas las entradas posibles.

Algorítmica y Programación II
Contando Operaciones Primitivas
• Definimos un conjunto de operaciones primitivas
como las siguientes:
– Asignación de un valor a una variable
– “Seguir” una referencia de objeto
– Realizar una operación aritmética (por ejemplo, sumar
dos números)
– Comparación de dos números
– Acceso a un elemento de un arreglo con índice
– Llamar a un método
– Retorno de un método

Algorítmica y Programación II
Contando Operaciones Primitivas
• Idealmente, este podría considerarse como el tipo de operación
básica que ejecuta el hardware, aunque estas operaciones
primitivas se traducirán a un pequeño número de instrucciones.
• En lugar de intentar determinar el tiempo de ejecución
específico de cada operación primitiva, simplemente
contaremos cuántas operaciones primitivas se ejecutarán y
usaremos este número t como una medida del tiempo de
ejecución del algoritmo.
• El número t de operaciones primitivas que realiza un algoritmo
será proporcional al tiempo real de ejecución de ese algoritmo.

Algorítmica y Programación II
Medición de operaciones como una función
del tamaño de entrada
• Para capturar el orden de crecimiento del
tiempo de ejecución de un algoritmo,
asociaremos, con cada algoritmo, una función
f (n) que caracteriza el número de operaciones
primitivas que se realizan en función del
tamaño de entrada n.

Algorítmica y Programación II
El peor caso de la entrada
• Un algoritmo puede funcionar más rápido en algunas entradas que en otras
del mismo tamaño.
• Por lo tanto, podemos desear expresar el tiempo de ejecución de un
algoritmo como la función del tamaño de entrada obtenido tomando el
promedio de todas las entradas posibles del mismo tamaño.
• Desafortunadamente, este análisis de casos promedio suele ser muy difícil
(sofisticada teoría de probabilidad).
• El análisis del peor caso es mucho más fácil que el análisis del caso promedio,
ya que sólo requiere la capacidad de identificar el input del peor caso, que es
a menudo simple.
• El peor caso es el que mejores “músculos” le pide al algorítmo.
• Dependiendo de la distribución de entrada, el tiempo de ejecución de un
algoritmo puede estar en cualquier lugar entre el tiempo del peor caso y el
tiempo del mejor caso.

Algorítmica y Programación II
El peor caso de la entrada

Algorítmica y Programación II
7 funciones
• Veremos las siete funciones más importantes
utilizadas en el análisis de algoritmos.
• Usaremos solamente estas siete funciones
simples para casi todos los análisis que
hacemos en este curso.

Algorítmica y Programación II
La función constante
• La función más simple que podemos pensar es la función constante,
es decir, f (n) = c,
• Ej. c = 5, c = 27, or c = 210
• Independientemente del valor de n se asigna a c.
• La función constante fundamental es g (n) = 1, y esta es la función
constante típica que usaremos en este curso.
• Cualquier función constante, f (n) = c, puede escribirse como una
constante c veces g(n). En este caso sería, f (n) = c.g(n)
• Tan simple como es la función constante es útil en el análisis de
algoritmos porque caracteriza el número de pasos necesarios para
realizar una operación básica en un ordenador, como sumar dos
números, asignar un valor a una variable o comparar dos números.

Algorítmica y Programación II
La función logarítmo
• f (n) = log b n, con constante b > 1.
• Se define como la inversa de la potencia, x = log b n si y solo si bx
= n.
• log n = log2 n
• Reglas: para
• a > 0, b > 1, c > 0,and d > 1

• Como cuestión práctica, observamos que la regla 4 nos da una


manera de calcular el logaritmo de la base-dos en una
calculadora que tiene logaritmo de base 10, como: log2 n = LOG
n/LOG 2
Algorítmica y Programación II
La función lineal
• f (n) = n.
• Por ejemplo, comparar un número x con cada
elemento de un arreglo de tamaño n requerirá n
comparaciones.
• La función lineal también representa el tiempo de
ejecución para cualquier algoritmo que procesa
cada uno de los n objetos que no están ya en la
memoria del ordenador, ya que la lectura en los n
objetos demandará de n operaciones de lectura.
Algorítmica y Programación II
La función N-Log-N
• f (n) = nlog n
• Esta función crece un poco más rápidamente
que la función lineal y mucho menos
rápidamente que la función cuadrática.
• Por lo tanto, preferiríamos mucho un
algoritmo con un tiempo de ejecución que sea
proporcional a n log n, que uno con tiempo de
ejecución cuadrático.

Algorítmica y Programación II
La función cuadrática
• f (n) = n 2
• La razón principal por la cual la función
cuadrática aparece en el análisis de algoritmos
es que hay muchos algoritmos que tienen
bucles anidados, donde el bucle interno realiza
un número lineal de operaciones y el bucle
externo se realiza un número lineal de veces.
• Por lo que el algoritmo se ejecuta n*n= n 2

Algorítmica y Programación II
La función cuadrática
• En 1787, un maestro alemán decidió mantener a sus
alumnos de 9 y 10 años ocupados sumando los
números enteros de 1 a 100. Pero casi de inmediato
uno de los niños afirmó tener la respuesta. El
maestro sospechó, pues el estudiante sólo tenía la
respuesta en su pizarra. Pero la respuesta, 5050, era
correcta y el estudiante, Carl Gauss, llegó a ser uno
de los matemáticos más grandes de su tiempo.
• Suponemos que el joven Gauss utilizó la siguiente
identidad. Para n>1

Algorítmica y Programación II
La función cuadrática

• Justificación visual
• Para ser justos, el número de
operaciones es n2 / 2 + n / 2, por
lo que esto es poco más de la
mitad del número de operaciones
que un algoritmo que utiliza n
operaciones cada vez que se
realiza el bucle interno. Pero el
orden de crecimiento sigue
siendo cuadrático para n

Algorítmica y Programación II
La función cúbica y otras polinomiales

• f (n) = n3

Algorítmica y Programación II
La función exponencial

• Por ejemplo, un entero que contenga n bits puede


representar todos los enteros no negativos inferiores a
2n.
• Si tenemos un bucle que comienza realizando una
operación y luego duplica el número de operaciones
realizadas con cada iteración, entonces el número de
operaciones realizadas en la iteración n es 2n.
Algorítmica y Programación II
Comparación de las tasas de crecimiento

Algorítmica y Programación II
Análisis asintótico
• Nos centramos en la tasa de crecimiento del
tiempo de ejecución en función del tamaño de
entrada n, tomando un enfoque de "big-
picture".
• Por ejemplo, a menudo basta con saber que el
tiempo de ejecución de un algoritmo como
crece en proporción a n.

Algorítmica y Programación II
La notación “Big-Oh”
Sea f (n) y g (n) funciones que relacionan enteros positivos con
números reales positivos. Se dice que f (n) es O (g (n)) si existe
una constante real c> 0 y una constante entera n0 ≥ 1 tal que f (n)
≤ c · g (n), para n ≥ n0.

Ejemplo: 8n+5 es de O(n)


Algorítmica y Programación II
La notación “Big-Oh”
Ejemplo: 8n+5 es de O(n)
Justificación: Por la definición de gran O, necesitamos
encontrar una constante real c> 0 y una constante
entera n0 ≥ 1 tal que 8n + 5 ≤ cn para cada entero n ≥
n0.
• Es fácil ver que una posible opción es c = 9 y n0 = 5.
• De hecho, esta es una de una infinidad de opciones
posibles. Por ejemplo, podríamos confiar en las
constantes c = 13 y n0 = 1.

Algorítmica y Programación II
La notación “Big-Oh”
• “ f (n) ≤ O(g(n))”,
• El big-Oh ya denota el concepto de "menor-o-
igual-a".
• Aunque es común, no es totalmente correcto
decir "f (n) = O (g (n))“
• Podemos decir que "f (n) es el orden de g (n)".
• También es correcto decir “ f (n) ∈ O(g(n))”

Algorítmica y Programación II
Algunas propiedades de la notación Big O

Algorítmica y Programación II
Carecterizando funciones en los términos
más simples
• Debemos usar la notación big-Oh para caracterizar a
una función lo más cercana posible.
• Si bien es cierto que la función f (n) = 4n3 + 3n2 es O (n5)
o incluso O (n4), es más exacto decir que f (n) es O (n3).
• También se considera de mal gusto incluir factores
constantes y términos de orden inferior en la notación
de big Oh
• Ejemplo: un algoritmo que se ejecuta en el tiempo
como máximo 5n + 20log n + 4 se dirá que es de tiempo
lineal O(n).

Algorítmica y Programación II
Big-Omega
• Así como la notación de Big Oh proporciona una forma
asintótica de decir que una función es "menor o igual
a" otra función, las siguientes notaciones proporcionan
una manera asintótica de decir que una función crece a
una velocidad que es "mayor o igual a“ la otra.
• Dadas las funciones f (n) y g(n) que van de los enteros
a los reales. Decimos que f (n) es Ω(g(n)), y decimos
“f (n) es omega de g(n)” si g(n) es O( f (n)), si, hay una
constante c> 0 y una constante entero n0 ≥ 1 tal que
f(n) ≥ cg(n), for n ≥ n0.

Algorítmica y Programación II
Big-Theta
• Hay una notación que nos permite decir que dos
funciones crecen a la misma velocidad, con
factores constantes.
• Decimos que f(n) es Ɵ(g (n)) y f(n), y decimos
que “f(n) es Ɵ (g (n))”, si f(n) es de O(g (n)) f(n) is
Ω(g(n)), es decir, hay constantes reales c'> 0 y
c”> 0 y una constante entera n0 ≥ 1 tal que c‘g(n)
≤ f(n) ≤ c” g(n), para todo n ≥ n0.
• Ejemplo: 3nlog n+4n+5logn es Ɵ(nlog n).
Algorítmica y Programación II
Análisis comparativo
• Podemos utilizar la notación Big-Oh para
ordenar clases de funciones por la tasa de
crecimiento asintótica.

Algorítmica y Programación II
Análisis comparativo
• El tamaño máximo permitido para una
instancia de entrada que es procesada por un
algoritmo en 1 segundo, 1 minuto y 1 hora
• Muestra la importancia de un buen diseño de
algoritmos

Algorítmica y Programación II
Análisis comparativo
• La importancia de un buen diseño de algoritmos va más allá
de lo que puede resolverse eficazmente en una computadora
determinada.
• Incluso si alcanzamos una aceleración enorme por hardware,
no podemos superar la desventaja de un algoritmo
asintóticamente lento.
• El aumento del tamaño máximo de un problema que se
puede resolver en un tiempo fijo, utilizando un ordenador 256
veces más rápido que el anterior. Cada entrada es una función
de m, el tamaño máximo del problema anterior.

Algorítmica y Programación II
Algunas palabras de precaución
• En términos generales, cualquier algoritmo que se
ejecuta en tiempo O (n log n) (con un factor
constante razonable) debe ser considerado eficiente.
• Incluso una función O(n2)-tiempo puede ser
suficientemente rápida en algunos contextos, es
decir, cuando n es pequeño.
• Pero un algoritmo cuyo tiempo de ejecución es una
función exponencial, por ejemplo, O(2n), casi nunca
debe ser considerado eficiente.

Algorítmica y Programación II
Tiempos de Ejecución Exponenciales
• Para ver cuán rápido crece la función 2n, considere la
famosa historia sobre el inventor del juego de ajedrez.
• Sólo le pidió a su rey que le pagara 1 grano de arroz por la
primera posición del tablero, 2 granos por el segundo, 4
granos por el tercero, 8 por el cuarto, y así sucesivamente.
El número de granos en la 64ava casilla sería: 263 =
9,223,372,036,854,775,808, (nueve billón de billones)
• Debemos trazar una línea entre algoritmos eficientes e
ineficientes, por lo tanto, es natural hacer esta distinción
entre los algoritmos que funcionan en tiempo polinomial
y los que funcionan en tiempo exponencial.
Algorítmica y Programación II
Ejemplos
• Operaciónes de tiempo constante: O(1)
• A.length()
• A[j] (obtención del índice)

Algorítmica y Programación II
Buscando el mayor de un arreglo
• O(n)

Algorítmica y Programación II
Disjunción de tres vías
• O(n3)

• O(n2)

Algorítmica y Programación II
Bibliografía
• Data Structures and Algorithms in Java™. Sixth
Edition. Michael T. Goodrich, Department of
Computer Science University of California.
Roberto Tamassia, Department of Computer
Science Brown University. Michael H.
Goldwasser, Department of Mathematics and
Computer Science Saint Louis University.
Wiley. 2014.

Algorítmica y Programación II

También podría gustarte