Está en la página 1de 161

UNIDAD 1

ANÁLISIS DE COMPLEJIDAD
ALGORÍTMICO

ANÁLISIS DE ALGORITMOS
1155404-B

1
1. Conceptos Básicos
2. Definición de algoritmo
3. Complejidad de algoritmos

AGENDA 4. Comportamiento
5. Dominio asintótico

2
CONCEPTOS BÁSICOS

Un problema computacional especifica una relación de entrada-salida

¿Qué aspecto tiene la entrada?


¿Cuál debería ser la salida para cada entrada?

Ejemplo:
Entrada: un número entero N que representa el número de la tarjeta de crédito
Salida: verdadero / falso, si existe esa tarjeta de crédito

Ejemplo:
Entrada: El primer nombre en la búsqueda de facebook
Salida: Una lista de personas para añadir a facebook

Ejemplo:
Entrada: una foto con una obra de arte
Salida: La información del creador de la obra de arte

3
DEFINICIÓN DE ALGORITMOS

Un algoritmo es un conjunto ordenado de


pasos o instrucciones ejecutables y no
ambiguas utilizadas para resolver un
problema específico.

Las etapas o pasos que sigue el


algoritmo deben tener una estructura
bien establecida en términos del orden
en que se ejecutan las etapas. Esto no
significa que las etapas se deban
ejecutar en secuencia.

https://ed.team/comunidad/que-es-un-algoritmo
4
DEFINICIÓN DE ALGORITMOS

PROPIEDADES

1. Especificación precisa de la entrada. Un algoritmo debe dejar claros el número y tipo de


valores de entrada y las condiciones iniciales que deben cumplir esos valores de entrada para
conseguir que las operaciones tengan éxito.

2. Especificación precisa de cada instrucción. Cada etapa de un algoritmo debe ser definida con
precisión. Esto significa que no puede haber ambigüedad sobre las acciones que se deban
ejecutar en cada momento.

3. Exactitud. Un algoritmo debe ser exacto, correcto. Se debe poder demostrar que el algoritmo
resuelve el problema.

5
DEFINICIÓN DE ALGORITMOS

PROPIEDADES

4. Etapas bien definidas y concretas. Cada etapa debe ser totalmente comprendida por la
persona o máquina que debe ejecutar el algoritmo. Cada etapa debe ser ejecutable
en una cantidad finita de tiempo.

5. Número finito de pasos. Si la descripción del algoritmo consta de un número infinito de


etapas, nunca se podrá implementar como un programa de computador. La mayoría de los
lenguajes que describen algoritmos (español, inglés o pseudocógio) proporciona un método
para ejecutar acciones repetidas, conocidas como iteraciones, que controlan las salidas de
bucles o secuencias repetitivas.

6. Un algoritmo debe terminar. No puede entrar en un bucle infinito.

7. Descripción del resultado o efecto. La salida esperada debe estar especificada.

6
DEFINICIÓN DE ALGORITMOS

¿Por qué son importantes?

Es un conjunto de reglas bien definidas para resolver algún problema computacional.

Quizás tiene un montón de números y quiere reorganizarlos para que estén en orden. ¿Cuál
sería el algoritmo?

Tal vez tenga un mapa de carreteras y quiere calcular el camino más corto desde un origen
hasta un destino. ¿Cuál sería el algoritmo?

Tal vez necesite completar varias tareas antes de ciertos plazos, y quiere saber en qué orden
debe terminar las tareas parapara completarlas todas en sus respectivos plazos. ¿Cuál sería el
algoritmo?

7
DEFINICIÓN DE ALGORITMOS

¿Por qué son importantes?

Es una forma de pensar.

8
DEFINICIÓN DE ALGORITMOS

¿Sirven solo para resolver problemas computacionales?

9
DEFINICIÓN DE ALGORITMOS

¿Sirven solo para resolver problemas computacionales?

Pues no.

El siguiente es un algoritmo para preparar una tortilla.

10
MEDICIÓN DE UN ALGORITMO

¿Sirven solo para resolver problemas computacionales?

El diseño de un algoritmo para ser implementado por un programa de computadora debe


tener dos características principales:

1. Que sea fácil de entender, codificar y depurar.


2. Que consiga la mayor eficiencia para los recursos de la computadora.

¿Cómo medir la eficiencia de un algoritmo o programa?

El método correspondiente se denomina análisis de algoritmos y permite medir la dificultad


inherente a un problema.

Eficiencia y Exactitud

11
EFICIENCIA Y EXACTITUD

EFICIENCIA

No existe un único algoritmo para resolver un problema determinado.

Normalmente un algoritmo es un orden de magnitud más eficiente que el otro.

Métodos que tratan de medir la eficiencia de los algoritmos:

• basados en el número de operaciones que debe efectuar un algoritmo para realizar una
tarea;
• basados en medir el tiempo que se emplea en llevar a cabo una determinada tarea, ya que lo
importante para el usuario final es que ésta se efectúe de forma correcta y en el menor
tiempo posible.

12
EFICIENCIA Y EXACTITUD

EFICIENCIA

No existe un único algoritmo para resolver un problema determinado.

¿Dificultades?
Normalmente un algoritmo es un orden de magnitud más eficiente que el otro.

Métodos que tratan de medir la eficiencia de los algoritmos:

• basados en el número de operaciones que debe efectuar un algoritmo para realizar una
tarea;
• basados en medir el tiempo que se emplea en llevar a cabo una determinada tarea, ya que lo
importante para el usuario final es que ésta se efectúe de forma correcta y en el menor
tiempo posible.

13
EFICIENCIA Y EXACTITUD

EFICIENCIA

No existe un único algoritmo para resolver un problema determinado.

¿Dificultades?
Normalmente un algoritmo es un orden de magnitud más eficiente que el otro.

Métodos que tratan de medir la eficiencia de los algoritmos:

• basados en el número de operaciones que debe efectuar un algoritmo para realizar una
tarea;
• basados en medir el tiempo que se emplea en llevar a cabo una determinada tarea, ya que lo
importante para el usuario final es que ésta se efectúe de forma correcta y en el menor
tiempo posible.

La máquina en la que se efectuó, el ambiente del


procesamiento y el tamaño de la muestra.
14
EFICIENCIA Y EXACTITUD

EFICIENCIA

El estudio de la eficiencia de los algoritmos se centra, fundamentalmente, en el análisis de la


ejecución de ciclos, ya que en el caso de funciones lineales —no contienen ciclos—, la eficiencia
es función del número de instrucciones que contiene. En este caso, su eficiencia depende de
la velocidad de las computadoras y, generalmente, no es un factor decisivo en la eficiencia
global de un programa.

Al crear programas que se ejecutan muchas veces a lo largo de su vida y/o tienen grandes
cantidades de datos de entrada, las consideraciones de eficiencia no se pueden descartar.

En la actualidad existen un gran número de aplicaciones informáticas que requieren


características especiales de hardware y software en las cuales los criterios de eficiencia
deben ser siempre tenidas en cuenta.

15
EFICIENCIA Y EXACTITUD

EFICIENCIA

16
EFICIENCIA Y EXACTITUD

FORMATO GENERAL DE LA EFICIENCIA

En general, el formato se puede expresar mediante una función:

f(n)=eficiencia

Es decir, la eficiencia del algoritmo se examina como una función del número de elementos
que tienen que ser procesados.  Bucles o ciclos

En los ciclos se repiten las sentencias del cuerpo del bucle un número determinado de veces.
Esto determina la eficiencia del mismo.

17
EFICIENCIA Y EXACTITUD

FORMATO GENERAL DE LA EFICIENCIA

Ejemplo 1. ¿Cuántas veces se repite el cuerpo del ciclo en el siguiente código?

18
EFICIENCIA Y EXACTITUD

FORMATO GENERAL DE LA EFICIENCIA

Ejemplo 1. ¿Cuántas veces se repite el cuerpo del ciclo en el siguiente código?

Si n es un entero, por ejemplo de valor 100, la respuesta es 100 veces. El número de iteraciones
es directamente proporcional al factor del bucle, n. Esto es, la función que expresa la eficiencia
es:

f(n) = n

19
EFICIENCIA Y EXACTITUD

FORMATO GENERAL DE LA EFICIENCIA

Ejemplo 1.1. ¿Cuántas instrucciones se ejecutan en el siguiente código? Asuma n = 5.

Reúnanse con el compañero unos 5 minutos y discutan la solución.

Discutan, discutan y discutan… podría haber un truco en el ejercicio.

20
EFICIENCIA Y EXACTITUD

FORMATO GENERAL DE LA EFICIENCIA

Ejemplo 1.1. ¿Cuántas instrucciones se ejecutan en el siguiente código? Asuma n = 5.

¿Cuántas veces se ejecuta?


¿Cuántas veces se ejecuta?

¿Cuántas veces se ejecuta?

f(5) = ?

21
EFICIENCIA Y EXACTITUD

FORMATO GENERAL DE LA EFICIENCIA

Ejemplo 2. ¿Cuántas veces se repite el cuerpo del ciclo en el siguiente código?

22
EFICIENCIA Y EXACTITUD

FORMATO GENERAL DE LA EFICIENCIA

Ejemplo 2. ¿Cuántas veces se repite el cuerpo del ciclo en el siguiente código?

Importante: El contador i avanza de 2 en 2, por lo que la respuesta es n/2. En este caso, el factor
de eficiencia es:

f(n) = n / 2

23
EFICIENCIA Y EXACTITUD

FORMATO GENERAL DE LA EFICIENCIA

Ciclos algorítmicos. ¿ Cuál será el valor i con respecto a la iteración?

Elabore una tabla donde muestre el valor de i para cada iteración. Tómese su tiempo, pero hágalo.

24
EFICIENCIA Y EXACTITUD

FORMATO GENERAL DE LA EFICIENCIA

Ciclos algorítmicos. ¿ Cuál será el valor i con respecto a la iteración?

Sin mirar, intente hacerlo, no es tan difícil

25
EFICIENCIA Y EXACTITUD

FORMATO GENERAL DE LA EFICIENCIA

Ciclos algorítmicos. ¿ Cuál será el valor i con respecto a la iteración?

26
EFICIENCIA Y EXACTITUD

FORMATO GENERAL DE LA EFICIENCIA

Ciclos algorítmicos. ¿Cuál será el valor i con respecto a la iteración?

27
EFICIENCIA Y EXACTITUD

FORMATO GENERAL DE LA EFICIENCIA

Ciclos algorítmicos. ¿ Cuál será el valor i con respecto a la iteración?

¿Y si fuera hasta 20,000?


¿Cómo se vería la gráfica?

28
EFICIENCIA Y EXACTITUD

FORMATO GENERAL DE LA EFICIENCIA

Ciclos algorítmicos. ¿ Cuál será el valor i con respecto a la iteración?

Las escalas logarítmicas ayudan a


mostrar la información de forma
útil cuando se tengan números
pequeños frente a otros números
muy grandes.

29
EFICIENCIA Y EXACTITUD

FORMATO GENERAL DE LA EFICIENCIA

Ciclos algorítmicos. ¿ Cuál será el valor i con respecto a la iteración?

Log2 n

30
EFICIENCIA Y EXACTITUD

FORMATO GENERAL DE LA EFICIENCIA

Ciclos algorítmicos. ¿ Cuál será el valor i con respecto a la iteración?

En ambos bucles se ejecutan 10 iteraciones. En cada iteración, el


valor de i se dobla en el bucle de multiplicar. Por consiguiente,
el número de iteraciones es una función del multiplicador, en este
caso 2.

Bucle de multiplicar 2iteraciones < 1000

Teoría de logaritmos:

El logaritmo binario de n es la potencia a la que debe elevarse el


número 2 para obtener el valor n.

log 2 1000 = 9,9657 ≅ 10

31
EFICIENCIA Y EXACTITUD

FORMATO GENERAL DE LA EFICIENCIA

Bubles anidados.

En el caso de bucles anidados (bucles que contienen otros bucles), se determinan cuántas
iteraciones contiene cada bucle. El total es entonces el producto del número de iteraciones del
bucle interno y el número de iteraciones del bucle externo.

iteraciones : iteraciones del bucle externo x iteraciones bucle interno

32
1. Conceptos Básicos
2. Definición de algoritmo
3. Complejidad de algoritmos

AGENDA 4. Comportamiento
5. Dominio asintótico

33
EFICIENCIA Y EXACTITUD

ANÁLISIS DE RENDIMIENTO

La medida del rendimiento de un programa se consigue mediante la complejidad del espacio y


del tiempo de un programa.

La complejidad del espacio de un programa es la cantidad de memoria que se necesita para


ejecutarlo hasta la terminación. El avance tecnológico proporciona hoy en día memoria abundante;
por esa razón, el análisis de algoritmos se centra fundamentalmente en el tiempo de ejecución. Sin
embargo…

¿puedo cargar todos los datos en memoria?

34
EFICIENCIA Y EXACTITUD

ANÁLISIS DE RENDIMIENTO

La medida del rendimiento de un programa se consigue mediante la complejidad del espacio y


del tiempo de un programa.

La complejidad del tiempo de un programa es la cantidad de tiempo de computadora que se


necesita para ejecutarlo. Se utiliza una función, T(n), para representar el número de unidades de
tiempo tomadas por un programa o algoritmo para cualquier entrada de tamaño n. Si la función
T(n) de un programa es T(n) = c * n, entonces el tiempo de ejecución es linealmente proporcional al
tamaño de la entrada sobre la que se ejecuta. Tal programa se dice que es de tiempo lineal o,
simplemente lineal.

35
EFICIENCIA Y EXACTITUD

ANÁLISIS DE RENDIMIENTO

Ejemplo 3. Tiempo de ejecución lineal de una función que calcula una serie de n términos

La función T(n) del método es:

36
EFICIENCIA Y EXACTITUD

ANÁLISIS DE RENDIMIENTO

Ejemplo 3. Tiempo de ejecución lineal de una función que calcula una serie de n términos

La función T(n) del método es:

T(n) = t1 + ?

37
EFICIENCIA Y EXACTITUD

ANÁLISIS DE RENDIMIENTO

Ejemplo 3. Tiempo de ejecución lineal de una función que calcula una serie de n términos

La función T(n) del método es:

T(n) = t1 + t2 + t3 + t4 ?

38
EFICIENCIA Y EXACTITUD

ANÁLISIS DE RENDIMIENTO

Ejemplo 3. Tiempo de ejecución lineal de una función que calcula una serie de n términos

La función T(n) del método es:

T(n) = t1 + t2 + t3 + t4 ?

¿Qué sucede con la iteración?

39
EFICIENCIA Y EXACTITUD

ANÁLISIS DE RENDIMIENTO

Ejemplo 3. Tiempo de ejecución lineal de una función que calcula una serie de n términos

La función T(n) del método es:

T(n) = t1 + t2 + t3 + t4 ?

T(n) = t1 + n*t2 + n*t3 + t4

40
EFICIENCIA Y EXACTITUD

ANÁLISIS DE RENDIMIENTO

Considerando a T(n) como el tiempo de ejecución de un programa con una entrada de tamaño n,
es posible evaluarlo desde diferentes puntos de vista:

Peor caso. Indica el tiempo peor que se puede tener. Este análisis es perfectamente adecuado
para algoritmos cuyo tiempo de respuesta es crítico; por ejemplo, para el caso del programa de
control de una central nuclear.

Piense por un momento en un arreglo ordenado de menor


a mayor de n números enteros, y necesita encontrar un
número. Describa cuál podría ser el peor caso.

41
EFICIENCIA Y EXACTITUD

ANÁLISIS DE RENDIMIENTO

Considerando a T(n) como el tiempo de ejecución de un programa con una entrada de tamaño n,
es posible evaluarlo desde diferentes puntos de vista:

Peor caso. Indica el tiempo peor que se puede tener. Este análisis es perfectamente adecuado
para algoritmos cuyo tiempo de respuesta es crítico; por ejemplo, para el caso del programa de
control de una central nuclear.

Mejor caso. Indica el tiempo mejor que podemos tener.

Piense por un momento en un arreglo ordenado de menor


a mayor de n números enteros, y necesita encontrar un
número. Describa cuál podría ser el mejor caso.

42
EFICIENCIA Y EXACTITUD

ANÁLISIS DE RENDIMIENTO

Considerando a T(n) como el tiempo de ejecución de un programa con una entrada de tamaño n,
es posible evaluarlo desde diferentes puntos de vista:

Peor caso. Indica el tiempo peor que se puede tener. Este análisis es perfectamente adecuado
para algoritmos cuyo tiempo de respuesta es crítico; por ejemplo, para el caso del programa de
control de una central nuclear.

Mejor caso. Indica el tiempo mejor que podemos tener.

Caso medio. Se puede computar T(n) como el tiempo medio de ejecución del programa sobre
todas las posibles ejecuciones de entradas de tamaño n. El tiempo de ejecución medio es a
veces una medida más realista de lo que el rendimiento será en la práctica, pero es,
normalmente, mucho más difícil de calcular que el tiempo de ejecución en el peor caso.

43
EFICIENCIA Y EXACTITUD

ANÁLISIS DE RENDIMIENTO

El tiempo de ejecución de un algoritmo varía con las entradas y


normalmente crece con el tamaño de las entradas.

Para evaluar un algoritmo o comparar dos algoritmos, hay que


centrarse en sus tasas de crecimiento relativas frente al
aumento del tamaño de la entrada.

El tiempo medio de ejecución es difícil de determinar.

El enfoque del análisis está en el peor caso de tiempo de


ejecución. ¿Por qué?

• Es más fácil de analizar


• Crucial para aplicaciones como las finanzas, la robótica y los
juegos
44
EFICIENCIA Y EXACTITUD

ANÁLISIS DE RENDIMIENTO

Haga el siguiente experimento:

Escriba un programa que recorra dos veces, por


separado, una lista de tamaño n. En el primer
recorrido, calcule el módulo del valor almacenado, y
súmelo en una variable.
Grafique los resultados en milisegundos vs el tamaño
En el segundo recorrido, tome el valor almacenado y de la lista.
divídalo entre el contador del ciclo, y súmelo a otra
variable. Al final, imprima la sumatoria de ambas ¿Qué encontró?
variables.

Ejecute el problema variando, considerablemente, la


cantidad de elementos de la lista. Use la función
Random para llenar el arreglo de forma automática.
45
EFICIENCIA Y EXACTITUD

ANÁLISIS DE RENDIMIENTO

Haga el siguiente experimento:

Escriba un programa que recorra dos veces, por


separado, una lista de tamaño n. En el primer
recorrido, calcule el módulo del valor almacenado, y
súmelo en una variable.

En el segundo recorrido, tome el valor almacenado y


divídalo entre el contador del ciclo, y súmelo a otra
variable. Al final, imprima la sumatoria de ambas
variables.

Ejecute el problema variando, considerablemente, la


cantidad de elementos de la lista. Use la función
Random para llenar el arreglo de forma automática.
46
EFICIENCIA Y EXACTITUD

ANÁLISIS DE RENDIMIENTO

La ventaja del análisis “teórico” es que no depende de la computadora que se use, ni del lenguaje
de programación, ni de la habilidad del programador.

Permite ahorrar, tanto el tiempo que se gastaría innecesariamente al programar un algoritmo


ineficiente, como el tiempo de máquina que se gastaría probándolo.

Permite estudiar la eficiencia de un algoritmo cuando se usa sobre ejemplares de cualquier


tamaño.

Claramente no es posible expresar la eficiencia por ejemplo en segundos, ya que no se cuenta con
una computadora estándar a la cual pudieran hacer referencia todas las mediciones.

Una respuesta a esta situación está dada por el principio de invarianza, el cual enuncia que dos
implementaciones diferentes del mismo algoritmo no diferirán en eficiencia por más de alguna
constante multiplicativa.
47
EFICIENCIA Y EXACTITUD

ANÁLISIS DE RENDIMIENTO

Principio de Invarianza

Si dos implementaciones del mismo algoritmo toman respectivamente t1(n) y t2(n) segundos para
resolver un caso de tamaño n, entonces siempre existen constantes positivas c y d tales que

t1(n) ≤ ct2(n) y t2(n) ≤ dt1(n)

siempre que n sea suficientemente grande.

En otras palabras, el tiempo de ejecución de cualquiera de las dos implementaciones está acotado
por un múltiplo constante del tiempo de ejecución de la otra.

48
EFICIENCIA Y EXACTITUD

ANÁLISIS DE RENDIMIENTO

Principio de Invarianza

Si esta constante resulta ser 5, por ejemplo, entonces sabremos que si la primera implementación
toma un segundo para resolver ejemplares de cierto tamaño, entonces la segunda implementación
(pudiera estar sobre una máquina distinta o escrita en un lenguaje de programación distinto) no
tomará más de 5 segundos para resolver los mismos ejemplares.

Así un cambio de máquina podría permitirnos resolver un problema 10 o 100 veces más rápido lo
cual nos incrementa la rapidez en un factor constante.

Por otro lado, un cambio de algoritmo y sólo un cambio de algoritmo podría darnos una mejora
que sería más y más marcada conforme aumenta el tamaño de los ejemplares.

49
EFICIENCIA Y EXACTITUD

TIEMPO DE EJECUCIÓN DE UN ALGORITMO (Retomando T(n))

Para medir T(n) usamos el número de operaciones elementales (OE). Una operación elemental
puede ser:

• Operación aritmética.
• Asignación a una variable.
• Llamada a una función.
• Retorno de una función.
• Comparaciones lógicas (con salto).
• Acceso a una estructura (arreglo, matriz, lista ligada…).

Se le llama tiempo de ejecución, no al tiempo físico, sino al número de OE que se llevan a cabo en
el algoritmo.

50
EFICIENCIA Y EXACTITUD

TIEMPO DE EJECUCIÓN DE UN ALGORITMO (Retomando T(n))

Ejemplo. Análisis de operaciones elementales en un algoritmo que busca un número dado dentro
de un arreglo ordenado. ¿Cuántas operaciones elementales contiene este código?

51
EFICIENCIA Y EXACTITUD

TIEMPO DE EJECUCIÓN DE UN ALGORITMO (Retomando T(n))

Ejemplo. Análisis de operaciones elementales en un algoritmo que busca un número dado dentro
de un arreglo ordenado. ¿Cuántas operaciones elementales contiene este código?

Ver Tiktok Hacer el ejercicio

52
EFICIENCIA Y EXACTITUD

TIEMPO DE EJECUCIÓN DE UN ALGORITMO (Retomando T(n))

Ejemplo. Análisis de operaciones elementales en un algoritmo que busca un número dado dentro
de un arreglo ordenado. ¿Cuántas operaciones elementales contiene este código?

1 OE (asignación)
1 OE (asignación)
1 OE (asignación)

53
EFICIENCIA Y EXACTITUD

TIEMPO DE EJECUCIÓN DE UN ALGORITMO (Retomando T(n))

Ejemplo. Análisis de operaciones elementales en un algoritmo que busca un número dado dentro
de un arreglo ordenado. ¿Cuántas operaciones elementales contiene este código?

1 OE (asignación)
1 OE (asignación)
1 OE (asignación)

2 OE (incremento + asignación)

1 OE (salida)
1 OE (salida)

54
EFICIENCIA Y EXACTITUD

TIEMPO DE EJECUCIÓN DE UN ALGORITMO (Retomando T(n))

Ejemplo. Análisis de operaciones elementales en un algoritmo que busca un número dado dentro
de un arreglo ordenado. ¿Cuántas operaciones elementales contiene este código?

1 OE (asignación)
1 OE (asignación)
1 OE (asignación)
4 OE (1 acceso + 2 comparaciones + 1 AND)
2 OE (incremento + asignación)
4 OE (1 acceso + 2 comparaciones + 1 AND)
1 OE (salida)
1 OE (salida)

55
EFICIENCIA Y EXACTITUD

TIEMPO DE EJECUCIÓN DE UN ALGORITMO (Retomando T(n))

Ejemplo. Análisis de operaciones elementales en un algoritmo que busca un número dado dentro
de un arreglo ordenado. ¿Cuántas operaciones elementales contiene este código?

1 OE (asignación)
¿Siempre se
1 OE (asignación) ejecutarán la misma
1 OE (asignación) cantidad de
operaciones
4 OE (1 acceso + 2 comparaciones + 1 AND)
elementales?
2 OE (incremento + asignación)
4 OE (1 acceso + 2 comparaciones + 1 AND)
1 OE (salida)
1 OE (salida)

56
EFICIENCIA Y EXACTITUD

TIEMPO DE EJECUCIÓN DE UN ALGORITMO (Retomando T(n))

Ejemplo. Análisis de operaciones elementales en un algoritmo que busca un número dado dentro
de un arreglo ordenado. Analizar el número de operaciones elementales de este
mismo algoritmo tomando en cuenta el mejor caso, es decir, cuando el número buscado se
encuentra inmediatamente en el primer elemento del arreglo.

57
EFICIENCIA Y EXACTITUD

TIEMPO DE EJECUCIÓN DE UN ALGORITMO (Retomando T(n))

Ejemplo. Análisis de operaciones elementales en un algoritmo que busca un número dado dentro
de un arreglo ordenado. Analizar el número de operaciones elementales de este
mismo algoritmo tomando en cuenta el mejor caso, es decir, cuando el número buscado se
encuentra inmediatamente en el primer elemento del arreglo.

1 OE (asignación)
1 OE (asignación)
1 OE (asignación)
1

58
EFICIENCIA Y EXACTITUD

TIEMPO DE EJECUCIÓN DE UN ALGORITMO (Retomando T(n))

Ejemplo. Análisis de operaciones elementales en un algoritmo que busca un número dado dentro
de un arreglo ordenado. Analizar el número de operaciones elementales de este
mismo algoritmo tomando en cuenta el mejor caso, es decir, cuando el número buscado se
encuentra inmediatamente en el primer elemento del arreglo.

1 OE (asignación)
1 OE (asignación)
1 OE (asignación)
1
4 OE (1 acceso + 2 comparaciones + 1 AND)

59
EFICIENCIA Y EXACTITUD

TIEMPO DE EJECUCIÓN DE UN ALGORITMO (Retomando T(n))

Ejemplo. Análisis de operaciones elementales en un algoritmo que busca un número dado dentro
de un arreglo ordenado. Analizar el número de operaciones elementales de este
mismo algoritmo tomando en cuenta el mejor caso, es decir, cuando el número buscado se
encuentra inmediatamente en el primer elemento del arreglo.

1 OE (asignación)
1 OE (asignación)
1 OE (asignación)
1
4 OE (1 acceso + 2 comparaciones + 1 AND)

4 OE (1 acceso + 2 comparaciones + 1 AND)

1 OE (salida)

60
EFICIENCIA Y EXACTITUD

TIEMPO DE EJECUCIÓN DE UN ALGORITMO (Retomando T(n))

Ejemplo. Análisis de operaciones elementales en un algoritmo que busca un número dado dentro
de un arreglo ordenado. Analizar el número de operaciones elementales de este
mismo algoritmo tomando en cuenta el mejor caso, es decir, cuando el número buscado se
encuentra inmediatamente en el primer elemento del arreglo.

1 OE (asignación) T(9) = 3+4+4+1 = 12


1 OE (asignación)
1 OE (asignación)
1
4 OE (1 acceso + 2 comparaciones + 1 AND)

¿Y este por qué no?


4 OE (1 acceso + 2 comparaciones + 1 AND)

1 OE (salida)

61
EFICIENCIA Y EXACTITUD

TIEMPO DE EJECUCIÓN DE UN ALGORITMO (Retomando T(n))

Ejemplo. Análisis de operaciones elementales en un algoritmo que busca un número dado dentro
de un arreglo ordenado (peor caso). Analizar el número de operaciones elementales de este
mismo algoritmo cuando el número buscado no se encuentra.

1 OE (asignación)
1 OE (asignación)
1 OE (asignación)
50

62
EFICIENCIA Y EXACTITUD

TIEMPO DE EJECUCIÓN DE UN ALGORITMO (Retomando T(n))

Ejemplo. Análisis de operaciones elementales en un algoritmo que busca un número dado dentro
de un arreglo ordenado (peor caso). Analizar el número de operaciones elementales de este
mismo algoritmo cuando el número buscado no se encuentra.

1 OE (asignación)
1 OE (asignación)
1 OE (asignación)
50
1
4 OE (1 acceso + 2 comparaciones y 1 AND)
2 OE (acceso + asignación)

2 OE (comparación + AND)

1 OE (salida)

63
EFICIENCIA Y EXACTITUD

TIEMPO DE EJECUCIÓN DE UN ALGORITMO (Retomando T(n))

Ejemplo. Análisis de operaciones elementales en un algoritmo que busca un número dado dentro
de un arreglo ordenado (peor caso). Analizar el número de operaciones elementales de este
mismo algoritmo cuando el número buscado no se encuentra.

Pero… ¿cuántas veces se


1 OE (asignación) ejecutan las operaciones
del ciclo?
1 OE (asignación)
1 OE (asignación)
50
1
4 OE (1 acceso + 2 comparaciones y 1 AND)
2 OE (acceso + asignación)

2 OE (comparación + AND)

1 OE (salida)

64
EFICIENCIA Y EXACTITUD

TIEMPO DE EJECUCIÓN DE UN ALGORITMO (Retomando T(n))

Ejemplo. Análisis de operaciones elementales en un algoritmo que busca un número dado dentro
de un arreglo ordenado (peor caso). Analizar el número de operaciones elementales de este
mismo algoritmo cuando el número buscado no se encuentra.

Hay que tomar en cuenta que el ciclo while se ejecuta n


veces, donde n es el tamaño del arreglo, en este caso 9.
50
1
Además, una vez que se ejecuta este ciclo 9 veces, se
hacen otras 2 operaciones elementales para verificar que
se terminó la búsqueda.

65
EFICIENCIA Y EXACTITUD

TIEMPO DE EJECUCIÓN DE UN ALGORITMO (Retomando T(n))

Ejemplo. Análisis de operaciones elementales en un algoritmo que busca un número dado dentro
de un arreglo ordenado (peor caso). Analizar el número de operaciones elementales de este
mismo algoritmo cuando el número buscado no se encuentra.

T(n) = 3 + σ𝑛−1
𝑗=0 4 + 2 + 2 + 2 + 1

1 OE (asignación) T(n) = 3 + 6𝑛 + 5
1 OE (asignación) T(9) = 62
1 OE (asignación)
50
1
4 OE (1 acceso + 2 comparaciones y 1 AND)
2 OE (acceso + asignación)

2 OE (comparación + AND)

1 OE (salida)

66
EFICIENCIA Y EXACTITUD

TIEMPO DE EJECUCIÓN DE UN ALGORITMO (Retomando T(n))

Ejemplo. Análisis de operaciones elementales en un algoritmo que busca un número dado dentro
de un arreglo ordenado (peor caso). Analizar el número de operaciones elementales de este
mismo algoritmo cuando el número buscado no se encuentra.

T(n) = 3 + σ𝑛−1
𝑗=0 4 + 2 + 2 + 2 + 1

1 OE (asignación) T(n) = 3 + 6𝑛 + 5
1 OE (asignación) T(9) = 62
¿De dónde salió?
1 OE (asignación)
50
1
4 OE (1 acceso + 2 comparaciones y 1 AND)
2 OE (acceso + asignación)

2 OE (comparación + AND)

1 OE (salida)

67
EFICIENCIA Y EXACTITUD

TIEMPO DE EJECUCIÓN DE UN ALGORITMO (Retomando T(n))

Cálculo del tiempo de ejecución en un ciclo for

Normalmente se considera el peor caso,


cuando se calcula el número de OE.

Consideramos que el tiempo de una OE es,


por definición, de orden 1.

El tiempo de ejecución de una secuencia


consecutiva de instrucciones se calcula
sumando los tiempos de ejecución de cada
una de las instrucciones.

68
EFICIENCIA Y EXACTITUD

TIEMPO DE EJECUCIÓN DE UN ALGORITMO (Retomando T(n))

Cálculo del tiempo de ejecución en un ciclo for


El tiempo total en el peor caso es:

𝑛−1

𝑇 𝑛 = 1 + 1 + ෍ (#𝑂𝐸 𝑑𝑒 𝑖𝑛𝑠𝑡𝑟𝑢𝑐𝑐𝑖𝑜𝑛𝑒𝑠 + 2 + 1)
𝑖=0

El primer 1 es el de la asignación, el segundo 1 es


el de la última comparación (cuando ya no se
cumple la condición) y al final hay que sumar el
resultado de multiplicar n veces el número de OE
de las instrucciones dentro del ciclo más 2 OE del
incremento más 1 OE de la comparación, es decir:

n (#OE de instrucciones + 2 + 1)

69
EFICIENCIA Y EXACTITUD

Subiendo la complejidad

• El número de iteraciones es: (n – k) / m


• La inicialización, i = k, es ejecutada una vez
• La condición, i < n, es ejecutada (n – k) / m + 1 veces
• La sentencia de actualización, i = i+m, es ejecutada (n - k) / m veces
• Los statement1 y statement2 son ejecutados (n – k) / m veces

70
EFICIENCIA Y EXACTITUD

Subiendo la complejidad Cambió la condición

• El número de iteraciones es: ?


• La inicialización, i = k, es ejecutada ? veces
• La condición, i <= n, es ejecutada ? veces
• La sentencia de actualización, i = i+m, es ejecutada ? veces
• Los statement1 y statement2 son ejecutados ? veces

71
EFICIENCIA Y EXACTITUD

Subiendo la complejidad Cambió la condición

• El número de iteraciones es: (n – k) / m + 1


• La inicialización, i = k, es ejecutada 1 vez
• La condición, i < n, es ejecutada (n – k) / m + 2 veces
• La sentencia de actualización, i = i+m, es ejecutada (n - k) / m + 1 veces
• Los statement1 y statement2 son ejecutados (n – k) / m + 1 veces

72
EFICIENCIA Y EXACTITUD

Ejercicio. Analizar el siguiente código y calcular la cantidad de operaciones elementales:

73
EFICIENCIA Y EXACTITUD

Ejercicio. Analizar el siguiente código y calcular la cantidad de operaciones elementales:

En el siguiente slide está la solución, pero


no mire, siga intentando y verá que lo
consigue.

74
EFICIENCIA Y EXACTITUD

Ejercicio. Analizar el siguiente código y calcular la cantidad de operaciones elementales:

2 OE (asignación)
𝑛−1

𝑇 𝑛 = 1 + 1 + ෍ (#𝑂𝐸 𝑑𝑒 𝑖𝑛𝑠𝑡𝑟𝑢𝑐𝑐𝑖𝑜𝑛𝑒𝑠 + 2 + 1)
𝑖=0

75
EFICIENCIA Y EXACTITUD

Ejercicio. Analizar el siguiente código y calcular la cantidad de operaciones elementales:

2 OE (asignación)
𝑛−1

𝑇 𝑛 = 1 + 1 + ෍ (#𝑂𝐸 𝑑𝑒 𝑖𝑛𝑠𝑡𝑟𝑢𝑐𝑐𝑖𝑜𝑛𝑒𝑠 + 2 + 1)
𝑖=0

𝑛−1

𝑇 𝑛 = 2 + 1 + 1 + ෍ (7 + 2 + 1)
𝑖=0
𝑇 𝑛 = 4 + 𝑛 ∗ (10)
𝑇 𝑛 = 10𝑛 + 4
76
EFICIENCIA Y EXACTITUD

Ejercicio. Calcular la complejidad de tiempo para el mejor caso y el peor caso. Discuta con sus
compañeros cuáles serían las situaciones que describirán al mejor caso y al peor caso.

77
EFICIENCIA Y EXACTITUD

Ejercicio. Calcular la complejidad de tiempo para el mejor caso y el peor caso. Discuta con sus
compañeros cuáles serían las situaciones que describirán al mejor caso y al peor caso.

78
EFICIENCIA Y EXACTITUD

Ejercicio. Calcular la complejidad de tiempo para el mejor caso y el peor caso. Discuta con sus
compañeros cuáles serían las situaciones que describirán al mejor caso y al peor caso.

79
EJEMPLO

EL PROBLEMA FIZZBUZZ

Escriba el algoritmo en Java para resolver el siguiente problema, y calcule su complejidad de


tiempo. Trabaje en grupos de 2 o 3, y comparen al final sus tiempos:

Imprimir los enteros del 1 al N, pero imprime "Fizz" si un entero es divisible por 3, "Buzz" si un
entero es divisible por 5, y "FizzBuzz" si un entero es divisible tanto por 3 como por 5.

Hay muchas maneras de conseguir el resultado deseado, pero algunos métodos son mejores
que otros.

Las grandes soluciones a FizzBuzz no "sólo funcionan". Se adhieren a buenos principios de


programación, permiten flexibilidad para cambios posteriores y aprovechan los puntos fuertes
del lenguaje.

80
EJEMPLO

EL PROBLEMA FIZZBUZZ

Imprimir los enteros del 1 al N, pero imprime "Fizz" si un entero es divisible por 3, "Buzz" si un
entero es divisible por 5, y "FizzBuzz" si un entero es divisible tanto por 3 como por 5.

Solución 1. La del estudiante (20 minutos, grupos 2)


Cada estudiante del grupo hará su propia implementación. Luego comparen las
implementaciones.
Solución 2. La del profesor (Internet)
Solución 3. Mejorada

81
EJEMPLO

EL PROBLEMA FIZZBUZZ

Imprimir los enteros del 1 al N, pero


imprime "Fizz" si un entero es divisible
por 3, "Buzz" si un entero es divisible
por 5, y "FizzBuzz" si un entero es
divisible tanto por 3 como por 5.

Solución 1. La del estudiante


Solución 2. La del profesor (Internet)
Solución 3. Mejorada

82
EJEMPLO

EL PROBLEMA FIZZBUZZ

Imprimir los enteros del 1 al N, pero


imprime "Fizz" si un entero es divisible
por 3, "Buzz" si un entero es divisible
por 5, y "FizzBuzz" si un entero es
divisible tanto por 3 como por 5.

Solución 1. La del estudiante


Solución 2. La del profesor (Internet)
Solución 3. Mejorada

83
EJEMPLO

EL PROBLEMA FIZZBUZZ

Imprimir los enteros del 1 al N, pero


imprime "Fizz" si un entero es divisible
por 3, "Buzz" si un entero es divisible
por 5, y "FizzBuzz" si un entero es
divisible tanto por 3 como por 5.

Solución 1. La del estudiante


Solución 2. La del profesor (Internet)
Solución 3. Mejorada

84
ACTIVIDAD EN CLASE

Realice los siguientes ejercicios en grupos de 3, pero cada estudiante deberá realizar el
ejercicio de manera individual. Para cada ejercicio considere peor caso y mejor caso, y calcule
la complejidad de tiempo.

1. Diseñar un algoritmo que calcule el número de veces que una cadena de caracteres aparece
como una subcadena de otra cadena. Por ejemplo, abc aparece dos veces en la cadena abcdabc,
y la cadena aba aparece dos veces en la cadena ababa.

2. Diseñar un algoritmo para determinar si un número n es primo. (Un número primo sólo puede
ser divisible por él mismo y por la unidad.)

3. Escribir un algoritmo que indique si una palabra leída del teclado es un palíndromo. Un
palíndromo es una palabra que se lee igual en ambos sentidos como “radar”.

85
ACTIVIDAD EN CLASE

Realice los siguientes ejercicios en grupos de 2, pero cada estudiante deberá realizar el
ejercicio de manera individual.

4. Calcule la eficiencia de los siguientes algoritmos:

86
IMPORTANTE

Quiz la próxima clase

87
1. Complejidad Algorítmica, medidas asintóticas

AGENDA

88
MEDIDAS ASINTÓTICAS

Las cotas de complejidad, también llamadas medidas asintóticas, sirven para clasificar y comparar
funciones. Las medidas asintóticas permiten analizar qué tan rápido crece el tiempo de ejecución de
un algoritmo cuando crece el tamaño de los datos de entrada, sin importar el lenguaje en el que esté
implementado ni el tipo de máquina en la que se ejecute.
En el análisis matemático, el análisis asintótico es un
método utilizado para describir el valor (es decir, el límite)
al que se aproxima una función cuando la entrada se acerca
a algún otro valor.

89
MEDIDAS ASINTÓTICAS

Como ejemplo, considere que quiere estudiar el comportamiento de una función f(n) a medida que el
número n se hace significativamente grande.

Si f (n) = n4 + 4n + 10 y el número n es muy grande, entonces el término 4n será insignificante en


comparación con el término n4 mientras que n no tiene ningún impacto sobre la constante 10. Por lo
tanto, se dice que la función f(n) es asintóticamente equivalente a n4 a medida que n se acerca a
infinito.

90
MEDIDAS ASINTÓTICAS

En el contexto de los algoritmos, el análisis asintótico se realiza para describir o evaluar el


rendimiento de un algoritmo en función del tamaño de la entrada.

Considere el siguiente caso, ud quiere transferir un


archivo a una amiga que vive a 3 horas de su casa.

¿Qué haría?

91
MEDIDAS ASINTÓTICAS

En el contexto de los algoritmos, el análisis asintótico se realiza para describir o evaluar el


rendimiento de un algoritmo en función del tamaño de la entrada.

Considere el siguiente caso, ud quiere transferir un


archivo a una amiga que vive a 3 horas de su casa.

1) Transferirlo electrónicamente.
2) Viajar 3 horas y entregárselo (físicamente) en una
memoria USB.

92
MEDIDAS ASINTÓTICAS

En el contexto de los algoritmos, el análisis asintótico se realiza para describir o evaluar el


rendimiento de un algoritmo en función del tamaño de la entrada.

Considere el siguiente caso, ud quiere transferir un


archivo a una amiga que vive a 3 horas de su casa.

1) Transferirlo electrónicamente.
2) Viajar 3 horas y entregárselo (físicamente) en una
memoria USB.

El tiempo de transferencia se verá afectado por el


tamaño del archivo. Cuanto más grande sea el archivo,
más tiempo necesitará para ser transferido a tu amiga.

93
MEDIDAS ASINTÓTICAS

En el contexto de los algoritmos, el análisis asintótico se realiza para describir o evaluar el


rendimiento de un algoritmo en función del tamaño de la entrada.

Considere el siguiente caso, ud quiere transferir un


archivo a una amiga que vive a 3 horas de su casa.

1) Transferirlo electrónicamente.
2) Viajar 3 horas y entregárselo (físicamente) en una
memoria USB.

El tiempo de transferencia será de 3 horas,


independientemente de lo pequeño o grande que sea el
archivo y, por tanto, el tamaño del mismo no afectará al
tiempo de transferencia.

94
MEDIDAS ASINTÓTICAS

En el contexto de los algoritmos, el análisis asintótico se realiza para describir o evaluar el


rendimiento de un algoritmo en función del tamaño de la entrada.

Considere el siguiente caso, ud quiere transferir un


archivo a una amiga que vive a 3 horas de su casa.

1) Transferirlo electrónicamente.
2) Viajar 3 horas y entregárselo (físicamente) en una
memoria USB.

Este comportamiento se muestra en la figura:


O(s) corresponde a la complejidad temporal. A medida
que aumenta el tamaño del archivo s, también aumenta
el tiempo necesario para completar la transferencia
(aumento es lineal).
O(1) corresponde a la complejidad temporal. La
complejidad temporal es constante.
95
MEDIDAS ASINTÓTICAS

Existen diversas notaciones asintóticas para medir la complejidad, las tres cotas de complejidad más
comunes son: la notación O (o mayúscula), la notación Ω (omega mayúscula) y la notación θ (theta
mayúscula).

Notación Big-O (O) describe el escenario de peor caso.


Notación Omega (Ω) describe el escenario de mejor caso.
Notación Theta (θ) describe el escenario de promedio.

96
MEDIDAS ASINTÓTICAS

Existen diversas notaciones asintóticas para medir la complejidad, las tres cotas de complejidad más
comunes son: la notación O (o mayúscula), la notación Ω (omega mayúscula) y la notación θ (theta
mayúscula).

Notación Big-O (O) describe el escenario de peor caso.


Notación Omega (Ω) describe el escenario de mejor caso.
Notación Theta (θ) describe el escenario de promedio.

La notación “O grande” representa “está en el orden de” y se expresa como O(n), es decir, “en el
orden de n”. La notación O indica la cota superior del tiempo de ejecución de un algoritmo o
programa. Así, en lugar de decir que un algoritmo emplea un tiempo de 4n-1 en procesar un array de
longitud n, se dirá que emplea un tiempo O(n) que se lee “O grande de n”, o bien “O de n.

97
MEDIDAS ASINTÓTICAS

Con la notación O se expresa una aproximación de la relación entre el tamaño de un problema y la


cantidad de proceso necesario para hacerlo. Por ejemplo, si

f(n) = n2 – 2n + 3

entonces f(n) es O(n2).

98
MEDIDAS ASINTÓTICAS

Ejemplo.

Calcular la función O grande de eficiencia de las siguientes funciones:

99
MEDIDAS ASINTÓTICAS

Ejemplo.

Calcular la función O grande de eficiencia de las siguientes funciones:

100
MEDIDAS ASINTÓTICAS

Notación Big O

La notación Big-O nos proporciona una manera de saber cómo se va a comportar un algoritmo en
función de los argumentos que le pasemos y la escala de los mismos.

Por ejemplo, considere una función que se utiliza para localizar un elemento dentro de una lista de
elementos previamente guardados. Si es una operación de tipo O(1), quiere decir que da igual cuántos
elementos haya en la lista, la operación siempre tarda lo mismo.

Ahora suponga que tiene una función que dibuja en una gráfica los puntos que se le pasen en una
matriz. Si la complejidad es O(n), entonces quiere decir, que si pintar 1 punto implica, por ejemplo,
10ms, pintar 2 implicaría 20ms, 3 puntos serían 30ms, etc... O sea, el tiempo necesario para ejecutar
la función es función directa y lineal del número de elementos que se pasen.

101
MEDIDAS ASINTÓTICAS

Notación Big O

Es muy importante conocer el tipo de función/curva que se asocia con la ejecución de una función ya
que permitirá saber de antemano si el rendimiento de una aplicación se puede resentir en caso de
que el tamaño de los datos a manejar aumente mucho.

Así, entre dos algoritmos/funciones que hagan lo mismo, debería seleccionarse el que tenga una
complejidad asintótica menor, para lo cual se consultará su notación Big-O.

De acuerdo con su complejidad, las notaciones Big-O más comunes para todo tipo de algoritmos y
funciones son:

102
MEDIDAS ASINTÓTICAS
https://www.campusmvp.es/recursos/post/Rendimiento-de-algoritmos-y-notacion-Big-O.aspx

¿Qué puede concluir?


Tiempo

Número de elementos
MEDIDAS ASINTÓTICAS
A medida que aumenta la complejidad, el
O(2n) tiempo necesario para completar la tarea
crece mucho, pudiendo llegar a aumentar
enormemente en algunos casos en cuanto
O(n2) hay más datos a manejar.
Tiempo

Si tiene una función con complejidad


cuadrática (O(n2)) o exponencial (O(2n)) por
regla general será señal de que el
algoritmo necesita una revisión urgente, y
mejor no utilizarlo.

Número de elementos

¿Qué es lo interesante? Poder comparar algoritmos equivalentes sin la necesidad de hacer pruebas de
rendimiento que dependen del hardware utilizado.

Ante resultados equivalentes es posible elegir el algoritmo de mayor rendimiento, que lo será siempre
independientemente del hardware si el conjunto de datos es lo suficientemente grande.
MEDIDAS ASINTÓTICAS

https://www.bigocheatsheet.com/
MEDIDAS ASINTÓTICAS

O(1) - constante O(n) – lineal

Es el mejor resultado, y quiere decir que el tiempo El crecimiento es lineal en tanto el tiempo de
de ejecución no varía conforme aumenta el tamaño ejecución es cada vez mayor de modo proporcional a
de los datos de entrada, y la respuesta siempre cómo se incrementa el tamaño de la entrada. Por lo
tarda lo mismo sin importar la magnitud de entrada. que si tenemos el doble de elementos de entrada,
tardará el doble.
Ejemplo: Acceso directo en un array de datos
Ejemplo: recorrer un array en un ciclo for
MEDIDAS ASINTÓTICAS

O(n) – lineal

El crecimiento es lineal en tanto el tiempo de


ejecución es cada vez mayor de modo proporcional a
cómo se incrementa el tamaño de la entrada. Por lo
que si tenemos el doble de elementos de entrada,
tardará el doble.

Ejemplo: recorrer un array en un ciclo for

¿Qué pasa acá?


MEDIDAS ASINTÓTICAS

O(n) – lineal

El crecimiento es lineal en tanto el tiempo de


ejecución es cada vez mayor de modo proporcional a
cómo se incrementa el tamaño de la entrada. Por lo
que si tenemos el doble de elementos de entrada,
tardará el doble.

Ejemplo: recorrer un array en un ciclo for

No importa si se incluyen más o menos


ciclos ya que a la final se simplificará. Por
ejemplo, O(3n) se simplifica a O(n)
MEDIDAS ASINTÓTICAS

O(n2) - cuadrática

Crecimiento exponencial. Para valores pequeños de entrada


el tiempo será asumible, pero al aumentar el tamaño de
entrada el tiempo tenderá a ser muy elevado y es probable
que el procesador se quede inoperativo.

Ejemplo: recorrer un ciclo for anidado a otro


MEDIDAS ASINTÓTICAS

O(n2) - cuadrática

Crecimiento exponencial. Para valores pequeños de entrada


el tiempo será asumible, pero al aumentar el tamaño de
entrada el tiempo tenderá a ser muy elevado y es probable
que el procesador se quede inoperativo.

Ejemplo: recorrer un ciclo for anidado a otro

¿Qué pasa acá?


MEDIDAS ASINTÓTICAS

O(n2) - cuadrática

Crecimiento exponencial. Para valores pequeños de entrada


el tiempo será asumible, pero al aumentar el tamaño de
entrada el tiempo tenderá a ser muy elevado y es probable
que el procesador se quede inoperativo.

Ejemplo: recorrer un ciclo for anidado a otro

O(n) + O(n2), al final se simplifica al


más desfavorable: O(n + n2) -> O(n2)
MEDIDAS ASINTÓTICAS

Peor Caso

Recuerde que se usa el peor de los casos para expresar la notación Big O.

Es posible tener algoritmos de búsqueda que encuentren el elemento a la primera lo que sería un O(1) pero
hay casos que tiene que ir hasta el último elemento, y será este el que se usa para especificar el valor Big O
de un algoritmo, atendiendo al peor de los casos.

Ejemplo: buscando un elemento recorriendo


todos los datos
MEDIDAS ASINTÓTICAS

O(log n) - logarítmica

Una forma de crecimiento que crece al inicio pero tiende a


estabilizarse conforme aumentan el tamaño de entrada, es
un algoritmo que no tiende a resentirse.

Ejemplo: Binary Search

Parte de que los datos están ordenados, y que en cada paso


descarta la mitad de los datos: compara el valor con el
elemento en el medio del array, si no son iguales, la mitad
en la cual el valor no puede estar es eliminada y la
búsqueda continúa en la mitad restante hasta que el valor
se encuentre.
MEDIDAS ASINTÓTICAS

O(log n) - logarítmica

Actividad en clase. Implemente en java un algoritmo de


búsqueda binaria.
MEDIDAS ASINTÓTICAS

O(2n) - exponencial

Se trata de funciones que duplican su complejidad con cada elemento añadido al procesamiento. Son
algoritmos muy raros pues en condiciones normales no debería ser necesario hacer algo así. Un ejemplo
sería, por ejemplo, el cálculo recursivo de la serie de Fibonacci, que es muy poco eficiente (se calcula
llamándose a sí misma la función con los dos números anteriores: F(n)=F(n-1)+F(n-2)).

O(n!) - explosión combinatoria

Un algoritmo que siga esta complejidad es un algoritmo totalmente fallido. Una explosión combinatoria se
dispara de tal manera que cuando el conjunto crece un poco, lo normal es que se considere
computacionalmente inviable. Solo se suele dar en algoritmos que tratan de resolver algo por la mera fuerza
bruta. No deberías verlo nunca en un software "real".

O(n log n)

En este caso se trata de funciones similares a las anteriores, pero que rompen el problema en varios trozos
por cada elemento, volviendo a recomponer información tras la ejecución de cada "trozo".
MEDIDAS ASINTÓTICAS
MEDIDAS ASINTÓTICAS

En grupos de 3, discuta y explique por qué, para el peor caso, la complejidad es de orden 1 para
acceder a un elemento en un arreglo, y por qué es de orden n cuando se hará la inserción?

Igualmente discuta, también, por qué la complejidad es de orden 1 cuando se hace una inserción en
una cola, y por qué es de orden n cuando se quiere hacer un acceso.

Utilice una hoja de cuaderno, y márquela.


MEDIDAS ASINTÓTICAS
MEDIDAS ASINTÓTICAS

Complejidad de Sentencias en Java

• Sentencias Sencillas: Se refiere a las sentencias de asignación, entrada/salida, etc. siempre y cuando no
trabajen sobre variables estructuradas cuyo tamaño esté relacionado con el tamaño N del problema. La
inmensa mayoría de las sentencias de un algoritmo requieren un tiempo constante de ejecución, siendo su
complejidad O(1).

• Decisión (if): El tiempo de ejecución de una instrucción condicional “if” es el costo de las instrucciones que
se ejecutan condicionalmente, más el tiempo para evaluar la condición.

O(Tiempo(if)) = O(Tiempo(condición)) + O(Tiempo(cuerpo))


MEDIDAS ASINTÓTICAS

Complejidad de Sentencias en Java

• Decisión (if): El tiempo de ejecución de una instrucción condicional “if” es el costo de las instrucciones que
se ejecutan condicionalmente, más el tiempo para evaluar la condición.

O(Tiempo(if)) = O(Tiempo(condición)) + O(Tiempo(cuerpo))


MEDIDAS ASINTÓTICAS

Complejidad de Sentencias en Java

• Decisión (if): El tiempo de ejecución de una instrucción condicional “if” es el costo de las instrucciones que
se ejecutan condicionalmente, más el tiempo para evaluar la condición.

O(Tiempo(if)) = O(Tiempo(condición)) + O(Tiempo(cuerpo))

En decisiones múltiples (ELSIF, CASE), se tomará la peor


de las ramas.
MEDIDAS ASINTÓTICAS

Complejidad de Sentencias en Java

• Decisión (if):
MEDIDAS ASINTÓTICAS

Complejidad de Sentencias en Java

• Decisión (if):
MEDIDAS ASINTÓTICAS

Complejidad de Sentencias en Java

• Ciclos: En los ciclos con contador


explícito, es posible distinguir dos casos:
que el tamaño N forme parte de los
límites o que no. Si el ciclo se realiza un
número fijo de veces, independiente de
N, entonces la repetición sólo introduce
una constante multiplicativa que puede
absorberse.
MEDIDAS ASINTÓTICAS
MEDIDAS ASINTÓTICAS
MEDIDAS ASINTÓTICAS

Ejemplo 1. Determinar la complejidad del método:


MEDIDAS ASINTÓTICAS

Ejemplo 1. Determinar la complejidad del método:

El método consta de una sentencia de selección, cada alternativa


tiene complejidad constante, O(1); entonces, la complejidad del
método mayor() es O(1) .
MEDIDAS ASINTÓTICAS

Ejemplo 1. Determinar la complejidad del método:

El método consta de una sentencia de selección, cada alternativa


tiene complejidad constante, O(1); entonces, la complejidad del
método mayor() es O(1) .

Ejemplo 2. Determinar la complejidad del método:


MEDIDAS ASINTÓTICAS

Ejemplo 1. Determinar la complejidad del método:

El método consta de una sentencia de selección, cada alternativa


tiene complejidad constante, O(1); entonces, la complejidad del
método mayor() es O(1) .

Ejemplo 2. Determinar la complejidad del método:

El método consta de un bucle que se ejecuta n veces, O(n). El


cuerpo del bucle es la llamada a println(), complejidad constante
O(1).

Como conclusión, la complejidad del método es O(n)*O(1) = O(n).


MEDIDAS ASINTÓTICAS

Ejemplo 3. Determinar la complejidad del método:


MEDIDAS ASINTÓTICAS

Ejemplo 3. Determinar la complejidad del método:

suma() está formado por una sentencia de asignación múltiple, O(1), de


un bucle condicional y la sentencia que devuelve control de complejidad
constante, O(1). Por consiguiente, la complejidad del método está
determinada por el bucle.

El número de iteraciones es igual al número de veces que el algoritmo


multiplica por dos a la variable k. Si t es el número de veces que k se
puede multiplicar hasta alcanzar el valor de n, que hace que termine el
bucle, entonces k = 2t.

0, 2, 22, 23, ... , 2t ≥ n.

Tomando logaritmos: el máximo de iteraciones es t = log2 n.

El cuerpo del bucle consta de una sentencia simple y un sentencia de


selección de complejidad O(1), por lo que tiene complejidad constante,
O(1). Con todas estas consideraciones, la complejidad del bucle y del
método es: O(log2 n)*O(1) = O(log2 n)
MEDIDAS ASINTÓTICAS

Ejemplo 4. Determinar la complejidad del método:

¿Qué pasa en este escenario?


MEDIDAS ASINTÓTICAS

Ejemplo 4. Determinar la complejidad del método:

¿Qué pasa en este escenario?

No se puede simplemente multiplicar el número de


iteraciones del bucle exterior por el número de iteraciones
del bucle interior, porque el bucle interior tiene un número
diferente de iteraciones cada vez.

Idea: Considerar cuántas iteraciones tiene ese bucle


interior. Esa información se da en la siguiente tabla:
MEDIDAS ASINTÓTICAS

Ejemplo 4. Determinar la complejidad del método:

¿Qué pasa en este escenario?

No se puede simplemente multiplicar el número de


iteraciones del bucle exterior por el número de iteraciones
del bucle interior, porque el bucle interior tiene un número
diferente de iteraciones cada vez.

Idea: Considerar cuántas iteraciones tiene ese bucle


interior. Esa información se da en la siguiente tabla:
MEDIDAS ASINTÓTICAS

Ejemplo 4. Determinar la complejidad del método:

¿Qué pasa en este escenario?

No se puede simplemente multiplicar el número de


iteraciones del bucle exterior por el número de iteraciones
del bucle interior, porque el bucle interior tiene un número
diferente de iteraciones cada vez.

Idea: Considerar cuántas iteraciones tiene ese bucle


interior. Esa información se da en la siguiente tabla:
MEDIDAS ASINTÓTICAS

EJERCICIOS:
¿Cuál es la complejidad en el peor de los casos de cada uno de los siguientes fragmentos de código?
MEDIDAS ASINTÓTICAS

EJERCICIOS:
¿Cuál es la complejidad en el peor de los casos de cada uno de los siguientes fragmentos de código?

4. 5. 6.
MEDIDAS ASINTÓTICAS

EJERCICIOS:
¿Cuál es la complejidad en el peor de los casos de cada uno de los siguientes fragmentos de código?

5. Calcular la complejidad asintótica de los siguientes fragmentos de código


MEDIDAS ASINTÓTICAS

EJERCICIOS:
¿Cuál es la complejidad en el peor de los casos de cada uno de los siguientes fragmentos de código?

5. Calcular la complejidad asintótica de los siguientes fragmentos de código


UNIDAD 1
ANÁLISIS DE COMPLEJIDAD EN
ALGORITMOS RECURSIVOS

ANÁLISIS DE ALGORITMOS
1155404-B

141
RECURSIVIDAD
La recursividad (recursión) es aquella propiedad que posee un método por la cual puede llamarse a sí
mismo.

Un método recursivo es aquel que se llama a sí mismo, bien directamente o bien indirectamente, a través
de otro método.

Piense, por ejemplo, en la búsqueda de “Sierra de Lupiana” en páginas web, puede ocurrir que aparezcan
direcciones (enlaces) que lleven a otras páginas y éstas, a su vez, a otras nuevas y así hasta completar
todo lo relativo a la búsqueda inicial.

142
RECURSIVIDAD

Un método que tiene sentencias entre las que se encuentra al menos una que llama al propio
método se dice que es recursivo. Así, supongamos que se dispone de dos métodos metodo1 y
metodo2. La organización de una aplicación no recursiva adoptaría una forma similar a ésta:

Con una organización recursiva, se tendría esta situación:

143
RECURSIVIDAD

En general, para resolver un problema utilizando la recursividad, se divide en subproblemas. Cada


subproblema es el mismo que el problema original, pero de menor tamaño. Se puede aplicar el
mismo enfoque a cada subproblema para resolverlo recursivamente.

La recursión está en todas partes. Piensa en tomar café. Se puede describir el procedimiento de
forma recursiva como sigue:

public static void drinkCoffee(Cup cup) {


if (!cup.isEmpty()) {
cup.takeOneSip(); // Take one sip
drinkCoffee(cup); Supongamos que taza es un objeto tipo Taza de
} Café con los métodos isEmpty() y takeOneSip().
}
Se puede dividir el problema en dos
subproblemas: uno es beber un sorbo de café y
el otro es beber el resto del café de la taza. El
segundo problema es el mismo que el problema
original, pero de menor tamaño. El caso base
del problema es cuando la taza está vacía.
144
RECURSIVIDAD

Considere el problema de imprimir un mensaje n veces. Se puede dividir el problema en dos


subproblemas: uno es imprimir el mensaje una vez, y el otro es imprimirlo n - 1 veces.

El segundo problema es el mismo que el problema original, pero de menor tamaño. El caso base
para el problema es n == 0. Se puede resolver este problema utilizando la recursividad de la
siguiente manera:

public static void nPrintln(String message, int times) {


if (times >= 1) {
System.out.println(message);
nPrintln(message, times - 1);
} // The base case is times == 0
}

145
RECURSIVIDAD
EJEMPLO 1

Algoritmo recursivo de la función matemática que suma los n primeros números enteros positivos.

Como punto de partida, se puede afirmar que para n = 1 se tiene que la suma S(1) = 1. Para n = 2
se puede escribir S(2) = S(1) + 2; en general, y aplicando la inducción matemática, se tiene: S(n) =
S(n-1) + n

¿Cómo sabe el algoritmo cuándo debe detenerse?

146
RECURSIVIDAD
EJEMPLO 1

Algoritmo recursivo de la función matemática que suma los n primeros números enteros positivos.

Como punto de partida, se puede afirmar que para n = 1 se tiene que la suma S(1) = 1. Para n = 2
se puede escribir S(2) = S(1) + 2; en general, y aplicando la inducción matemática, se tiene: S(n) =
S(n-1) + n

El algoritmo que determina la suma de modo recursivo ha de tener presente una condición de salida o una
condición de parada. Así, en el caso del cálculo de S(6); la definición es S(6)= 6 + S(5), a su vez S(5)=
5 + S(4), este proceso continúa hasta S(1) = 1

El caso base S(1) = 1 es esencial dado que se detiene, potencialmente, una cadena de llamadas
recursivas. Este caso base o condición de salida debe fijarse en cada solución recursiva.

147
RECURSIVIDAD
EJEMPLO 1

Algoritmo recursivo de la función matemática que suma los n primeros números enteros positivos.

¿Cuál es el caso base?

148
RECURSIVIDAD
EJEMPLO 2

Definir la naturaleza recursiva de la serie de Fibonacci: 0, 1, 1, 2, 3, 5, 8 ,13, 21 ...

Se observa en esta serie que comienza con 0 y 1, y tiene la propiedad de que cada elemento es la suma de
los dos elementos anteriores, por ejemplo:
0 + 1 = 1
1 + 1 = 2
2 + 1 = 3
3 + 2 = 5
5 + 3 = 8 ...

149
RECURSIVIDAD
EJEMPLO 2

Definir la naturaleza recursiva de la serie de Fibonacci: 0, 1, 1, 2, 3, 5, 8 ,13, 21 ...

Se observa en esta serie que comienza con 0 y 1, y tiene la propiedad de que cada elemento es la suma de
los dos elementos anteriores, por ejemplo:
0 + 1 = 1
1 + 1 = 2 Entonces se puede establecer que :
2 + 1 = 3 fibonacci(0) = 0
3 + 2 = 5 fibonacci(1) = 1
5 + 3 = 8 ... ...
fibonacci(n) = fibonacci(n - 1) + fibonacci(n - 2)

150
RECURSIVIDAD
EJEMPLO 2

Definir la naturaleza recursiva de la serie de Fibonacci: 0, 1, 1, 2, 3, 5, 8 ,13, 21 ...

Se observa en esta serie que comienza con 0 y 1, y tiene la propiedad de que cada elemento es la suma de
los dos elementos anteriores, por ejemplo:
0 + 1 = 1
1 + 1 = 2 Entonces se puede establecer que :
2 + 1 = 3 fibonacci(0) = 0
3 + 2 = 5 fibonacci(1) = 1
5 + 3 = 8 ... ...
fibonacci(n) = fibonacci(n - 1) + fibonacci(n - 2)

151
RECURSIVIDAD
EJEMPLO 2

Definir la naturaleza recursiva de la serie de Fibonacci: 0, 1, 1, 2, 3, 5, 8 ,13, 21 ...

Obsérvese que la definición recursiva de los números de Fibonacci es diferente de las definiciones recursivas del
factorial de un número y del producto de dos números. Así:

fibonacci(6) = fibonacci(5) + fibonacci(4)

o, lo que es igual, fibonacci(6) ha de aplicarse en modo recursivo dos veces, y así sucesivamente.

152
RECURSIVIDAD
EJEMPLO 2

Definir la naturaleza recursiva de la serie de Fibonacci: 0, 1, 1, 2, 3, 5, 8 ,13, 21 ...

¿Cuál es el caso base?

153
RECURSIVIDAD
EJEMPLO 2

Definir la naturaleza recursiva de la serie de Fibonacci: 0, 1, 1, 2, 3, 5, 8 ,13, 21 ...

154
RECURSIVIDAD

Como se puede ver, hay muchas llamadas recursivas duplicadas. Por ejemplo, fib(2) se llama dos veces, fib(1)
tres veces y fib(0) dos veces. En general, el cálculo de fib(índice) requiere aproximadamente el doble de
llamadas recursivas que el cálculo de fib(índice - 1).
155
RECURSIVIDAD

Un método recursivo es un método que se invoca a sí mismo de forma directa o indirecta. En recursión directa,
el código del método f() contiene una sentencia que invoca a f(), mientras que en recursión indirecta, el método
f() invoca a un método g() que a su vez invoca al método p(), y así sucesivamente hasta que se invoca de nuevo
al método f().

Un requisito para que un algoritmo recursivo sea correcto es que no genere una secuencia infinita de llamadas
sobre sí mismo. Cualquier algoritmo que genere una secuencia de este tipo no puede terminar nunca.

En consecuencia la definición recursiva debe incluir una condición de salida, que se denomina componente
base, en el que f(n) se defina directamente (es decir, no recursivamente) para uno o más valores de n.

156
RECURSIVIDAD
Ejercicio 1. Escribir un método recursivo que calcule e imprima el factorial de un número n solicitado por
consola/pantalla.

Ejercicio 2. Muestre la salida de los siguientes programas e identifique los casos base y los llamados
recursivos. Por favor, use lapiz y hoja.

157
RECURSIVIDAD
Ejercicio 4: Escriba un método para calcular el valor de la potencia 2n, siendo n un número positivo.

Ejercicio 5: Escriba un método para calcular el resultado de 1 + 2 + 3 + ... + n, siendo n un número positivo.

Ejercicio 6: Muestre la salida de los siguientes programas (lapiz y papel):

158
RECURSIVIDAD
Ejercicio 7: ¿Qué está mal con los siguientes programas?

Ejercicio 8: Diseñe un programa que calcule y retorne el tamaño de una carpeta (tenga o no subcarpetas).
Implemente la solución usando recursión y sin recursión.
Busque e investigue la clase File()

159
RECURSIVIDAD
Ejercicio 9.

Ejercicio 10.

160
RECURSIVIDAD
Ejercicio 11.

Ejercicio 12. Crea un método que compruebe si un número es binario. Un número binario está formado
únicamente por ceros y unos.

Ejercicio 13. Genere un programa recursivo que indique si un String posee paréntesis balanceados

161

También podría gustarte