Vous êtes sur la page 1sur 70

UNIVERSIDAD NACIONAL DEL ALTIPLANO PUNO

Facultad de Ingeniería Mecánica, Electrónica y Sistemas


Escuela Profesional de Ingeniería de Sistemas

Análisis y Diseño de
Algoritmos

Ing. Alodia Flores Arnao

1
Capítulo 1

2
Parte 1

• El curso
– Información general
• Introducción a los algoritmos
• Conceptos básicos de análisis de algoritmos
• Notación asintótica
El curso

• Propósito: el estudio teórico del diseño y análisis de algoritmos


– No es un curso de programación
– No es un curso de matemáticas, tampoco
• Libro de Texto: Introducción a Algoritmos, Cormen, Leiserson,
Rivest, Stein
– Segunda edición
– Una referencia excelente que debes tener
• Otros:
– Introduction to the Design and Analysis of Algorithms, Anany Levitin.
– Los que están en el sílabo.
• Nombre : Análisis y Diseño de Algoritmos
• Profesora : Ing. Alodia Flores Arnao
• Email : flores.alodia@gmail.com
• Horario : Miércoles y Jueves 5:00 pm – 7 pm
• Aula N° 103 y laboratorio N° 2 de la EPIS.
• Sitio Web : http://www.huajsapata.com/moodle
• (Tareas, bibliografía, etc.)

• Contraseña: E6eJ2u
Normas del curso

• Celulares en silencio.
• Durante la clase Teórica no salir de la clase, a menos que sea una
emergencia.
• Participación constante del alumno (habrán puntos complementarios
por participación activa en los exámenes o prácticas calificadas).
• Pasión por aprender, responsabilidad, trabajo en equipo y respeto.
• Toda tarea será entregada a través del Aula Virtual.
• Las tareas presentadas con retraso tendrán una penalidad del 15%
por día de retraso (Máximo 3 días).
• Las fechas de examen por unidad están programadas y publicadas
en el Aula Virtual.

6
Calificación

• El estudiante deberá cumplir con los siguientes requisitos:


– Haber participado en todas las evaluaciones y/o presentación de avances
de proyecto programados con fecha previamente anticipada.
– Haber asistido regularmente a las sesiones de clase teórico y prácticas
programadas al 70 %.
– El estudiante, para aprobar la asignatura debe obtener una nota final que
sea mayor o igual a 10,5.
• Ponderado de calificación:
– Conocimiento: 30%
– Desempeño: 30%
– Producto: 40%
Introducción

• Introducción a los algoritmos


– ¿Qué son Algoritmos?
– Análisis vs. Diseño
– RAM
• Conceptos básicos de análisis de algoritmos
• Notación asintótica
¿Qué son algoritmos?

• Definición de Webster: un procedimiento para resolver un


problema matemático (como encontrar el mayor divisor común)
en un número finito de pasos que con frecuencia implica la
repetición de una operación;
• Ampliamente: un procedimiento paso a paso para resolver un
problema o lograr algún fin, especialmente con una
computadora.

• ¿Alguna otra definición?


Conceptos básicos de algoritmos

• Procedimiento computacional bien definido


• Toma valores de entrada
• Produce valores de salida
• Los resultados son siempre correctos para cualquier evento de
entrada
• Siempre termina
Analogía musical
Computación Música

Software Música

Hardware Instrumentos musicales

Algoritmos Progresiones de acordes

Código Fuente Notación musical

Programación Composición
Objetivos básicos para un algoritmo

• Siempre correcto
• Siempre termina
• En esta clase: performance (rendimiento)
– El performance (rendimiento) a menudo traza la línea entre lo que es
posible y lo que es imposible.
Análisis vs. Diseño

• Análisis: predecir el costo de un algoritmo en términos de


recursos y rendimiento.

• Diseño: algoritmos de diseño que minimizan el costo.


Modelo de máquina: máquina genérica de acceso aleatorio (RAM)

• Ejecuta operaciones secuencialmente


• Conjunto de operaciones primitivas:
– Aritmética. Lógico, comparaciones, llamadas a funciones

• Todas las operaciones cuestan 1 unidad


– Elimina la dependencia de la velocidad de nuestra computadora, de lo
contrario es imposible verificar y comparar
Parte 2

• Introducción a los algoritmos


• Conceptos básicos de análisis de algoritmos
– Ordenamiento
– Ordenamiento de inserción
• Notación asintótica
El problema del ordenamiento

Entrada: secuencia a1, a2, …, an de números.

Salida: permutacion a'1, a'2, …, a'n tal


que a'1  a'2 …  a'n .

Ejemplo:
Entrada: 8 2 4 9 3 6
Salida: 2 3 4 6 8 9
Ordenamiento por inserción

INSERTION-SORT (A, n) ⊳ A[1 . . n]


for i ← 2 to n
do key ← A[i]
j←i–1
“pseudocódigo” while j > 0 and A[j] > key
do A[j+1] ← A[j]
j←j–1
A[j+1] ← key
1 j i n
A:
key
ordenado
Un ejemplo: Ordenamiento de inserción

30 10 40 20 i =  j =  key = 
A[j] =  A[j+1] = 
1 2 3 4

InsertionSort(A, n)
for i ← 2 to n
do key ← A[i]
j ← i - 1
while j > 0 and A[j] > key
do A[j+1] ← A[j]
j ← j - 1

A[j+1] ← key
Un ejemplo: Ordenamiento de inserción

30 10 40 20 i=2 j=1 key = 10


A[j] = 30 A[j+1] = 10
1 2 3 4

InsertionSort(A, n)
for i ← 2 to n
do key ← A[i]
j ← i - 1
while j > 0 and A[j] > key
do A[j+1] ← A[j]
j ← j - 1

A[j+1] ← key
Un ejemplo: Ordenamiento de inserción

30 30 40 20 i=2 j=1 key = 10


A[j] = 30 A[j+1] = 30
1 2 3 4

InsertionSort(A, n)
for i ← 2 to n
do key ← A[i]
j ← i - 1
while j > 0 and A[j] > key
do A[j+1] ← A[j]
j ← j - 1

A[j+1] ← key
Un ejemplo: Ordenamiento de inserción

30 30 40 20 i=2 j=1 key = 10


A[j] = 30 A[j+1] = 30
1 2 3 4

InsertionSort(A, n)
for i ← 2 to n
do key ← A[i]
j ← i - 1
while j > 0 and A[j] > key
do A[j+1] ← A[j]
j ← j - 1

A[j+1] ← key
Un ejemplo: Ordenamiento de inserción

30 30 40 20 i=2 j=0 key = 10


A[j] =  A[j+1] = 30
1 2 3 4

InsertionSort(A, n)
for i ← 2 to n
do key ← A[i]
j ← i - 1
while j > 0 and A[j] > key
do A[j+1] ← A[j]
j ← j - 1

A[j+1] ← key
Un ejemplo: Ordenamiento de inserción

10 30 40 20 i=2 j=0 key = 10


A[j] =  A[j+1] = 10
1 2 3 4

InsertionSort(A, n)
for i ← 2 to n
do key ← A[i]
j ← i - 1
while j > 0 and A[j] > key
do A[j+1] ← A[j]
j ← j - 1

A[j+1] ← key
Un ejemplo: Ordenamiento de inserción

10 30 40 20 i=3 j=0 key = 10


A[j] =  A[j+1] = 10
1 2 3 4

InsertionSort(A, n)
for i ← 2 to n
do key ← A[i]
j ← i - 1
while j > 0 and A[j] > key
do A[j+1] ← A[j]
j ← j - 1

A[j+1] ← key

3101 3.0A

Lecture 1 - 24
Un ejemplo: Ordenamiento de inserción

10 30 40 20 i=3 j=0 key = 40


A[j] =  A[j+1] = 10
1 2 3 4

InsertionSort(A, n)
for i ← 2 to n
do key ← A[i]
j ← i - 1
while j > 0 and A[j] > key
do A[j+1] ← A[j]
j ← j - 1

A[j+1] ← key
Un ejemplo: Ordenamiento de inserción

10 30 40 20 i=3 j=0 key = 40


A[j] =  A[j+1] = 10
1 2 3 4

InsertionSort(A, n)
for i ← 2 to n
do key ← A[i]
j ← i - 1
while j > 0 and A[j] > key
do A[j+1] ← A[j]
j ← j - 1

A[j+1] ← key
Un ejemplo: Ordenamiento de inserción

10 30 40 20 i=3 j=2 key = 40


A[j] = 30 A[j+1] = 40
1 2 3 4

InsertionSort(A, n)
for i ← 2 to n
do key ← A[i]
j ← i - 1
while j > 0 and A[j] > key
do A[j+1] ← A[j]
j ← j - 1

A[j+1] ← key
Un ejemplo: Ordenamiento de inserción

10 30 40 20 i=3 j=2 key = 40


A[j] = 30 A[j+1] = 40
1 2 3 4

InsertionSort(A, n)
for i ← 2 to n
do key ← A[i]
j ← i - 1
while j > 0 and A[j] > key
do A[j+1] ← A[j]
j ← j - 1

A[j+1] ← key
Un ejemplo: Ordenamiento de inserción

10 30 40 20 i=3 j=2 key = 40


A[j] = 30 A[j+1] = 40
1 2 3 4

InsertionSort(A, n)
for i ← 2 to n
do key ← A[i]
j ← i - 1
while j > 0 and A[j] > key
do A[j+1] ← A[j]
j ← j - 1

A[j+1] ← key
Un ejemplo: Ordenamiento de inserción

10 30 40 20 i=4 j=2 key = 40


A[j] = 30 A[j+1] = 40
1 2 3 4

InsertionSort(A, n)
for i ← 2 to n
do key ← A[i]
j ← i - 1
while j > 0 and A[j] > key
do A[j+1] ← A[j]
j ← j - 1

A[j+1] ← key
Un ejemplo: Ordenamiento de inserción

10 30 40 20 i=4 j=2 key = 20


A[j] = 30 A[j+1] = 40
1 2 3 4

InsertionSort(A, n)
for i ← 2 to n
do key ← A[i]
j ← i - 1
while j > 0 and A[j] > key
do A[j+1] ← A[j]
j ← j - 1

A[j+1] ← key
Un ejemplo: Ordenamiento de inserción

10 30 40 20 i=4 j=2 key = 20


A[j] = 30 A[j+1] = 40
1 2 3 4

InsertionSort(A, n)
for i ← 2 to n
do key ← A[i]
j ← i - 1
while j > 0 and A[j] > key
do A[j+1] ← A[j]
j ← j - 1

A[j+1] ← key
Un ejemplo: Ordenamiento de inserción

10 30 40 20 i=4 j=3 key = 20


A[j] = 40 A[j+1] = 20
1 2 3 4

InsertionSort(A, n)
for i ← 2 to n
do key ← A[i]
j ← i - 1
while j > 0 and A[j] > key
do A[j+1] ← A[j]
j ← j - 1

A[j+1] ← key
Un ejemplo: Ordenamiento de inserción

10 30 40 20 i=4 j=3 key = 20


A[j] = 40 A[j+1] = 20
1 2 3 4

InsertionSort(A, n)
for i ← 2 to n
do key ← A[i]
j ← i - 1
while j > 0 and A[j] > key
do A[j+1] ← A[j]
j ← j - 1

A[j+1] ← key
Un ejemplo: Ordenamiento de inserción

10 30 40 40 i=4 j=3 key = 20


A[j] = 40 A[j+1] = 40
1 2 3 4

InsertionSort(A, n)
for i ← 2 to n
do key ← A[i]
j ← i - 1
while j > 0 and A[j] > key
do A[j+1] ← A[j]
j ← j - 1

A[j+1] ← key
Un ejemplo: Ordenamiento de inserción

10 30 40 40 i=4 j=3 key = 20


A[j] = 40 A[j+1] = 40
1 2 3 4

InsertionSort(A, n)
for i ← 2 to n
do key ← A[i]
j ← i - 1
while j > 0 and A[j] > key
do A[j+1] ← A[j]
j ← j - 1

A[j+1] ← key
Un ejemplo: Ordenamiento de inserción

10 30 40 40 i=4 j=3 key = 20


A[j] = 40 A[j+1] = 40
1 2 3 4

InsertionSort(A, n)
for i ← 2 to n
do key ← A[i]
j ← i - 1
while j > 0 and A[j] > key
do A[j+1] ← A[j]
j ← j - 1

A[j+1] ← key
Un ejemplo: Ordenamiento de inserción

10 30 40 40 i=4 j=2 key = 20


A[j] = 30 A[j+1] = 40
1 2 3 4

InsertionSort(A, n)
for i ← 2 to n
do key ← A[i]
j ← i - 1
while j > 0 and A[j] > key
do A[j+1] ← A[j]
j ← j - 1

A[j+1] ← key
Un ejemplo: Ordenamiento de inserción

10 30 40 40 i=4 j=2 key = 20


A[j] = 30 A[j+1] = 40
1 2 3 4

InsertionSort(A, n)
for i ← 2 to n
do key ← A[i]
j ← i - 1
while j > 0 and A[j] > key
do A[j+1] ← A[j]
j ← j - 1

A[j+1] ← key
Un ejemplo: Ordenamiento de inserción

10 30 30 40 i=4 j=2 key = 20


A[j] = 30 A[j+1] = 30
1 2 3 4

InsertionSort(A, n)
for i ← 2 to n
do key ← A[i]
j ← i - 1
while j > 0 and A[j] > key
do A[j+1] ← A[j]
j ← j - 1

A[j+1] ← key
Un ejemplo: Ordenamiento de inserción

10 30 30 40 i=4 j=2 key = 20


A[j] = 30 A[j+1] = 30
1 2 3 4

InsertionSort(A, n)
for i ← 2 to n
do key ← A[i]
j ← i - 1
while j > 0 and A[j] > key
do A[j+1] ← A[j]
j ← j - 1

A[j+1] ← key
Un ejemplo: Ordenamiento de inserción

10 30 30 40 i=4 j=1 key = 20


A[j] = 10 A[j+1] = 30
1 2 3 4

InsertionSort(A, n)
for i ← 2 to n
do key ← A[i]
j ← i - 1
while j > 0 and A[j] > key
do A[j+1] ← A[j]
j ← j - 1

A[j+1] ← key
Un ejemplo: Ordenamiento de inserción

10 30 30 40 i=4 j=1 key = 20


A[j] = 10 A[j+1] = 30
1 2 3 4

InsertionSort(A, n)
for i ← 2 to n
do key ← A[i]
j ← i - 1
while j > 0 and A[j] > key
do A[j+1] ← A[j]
j ← j - 1

A[j+1] ← key
Un ejemplo: Ordenamiento de inserción

10 20 30 40 i=4 j=1 key = 20


A[j] = 10 A[j+1] = 20
1 2 3 4

InsertionSort(A, n)
for i ← 2 to n
do key ← A[i]
j ← i - 1
while j > 0 and A[j] > key
do A[j+1] ← A[j]
j ← j - 1

A[j+1] ← key
Un ejemplo: Ordenamiento de inserción

10 20 30 40 i=4 j=1 key = 20


A[j] = 10 A[j+1] = 20
1 2 3 4

InsertionSort(A, n)
for i ← 2 to n
do key ← A[i]
j ← i - 1
while j > 0 and A[j] > key
do A[j+1] ← A[j]
j ← j - 1

A[j+1] ← key

Listo!
Ejemplo de Ordenamiento de inserción

8 2 4 9 3 6
2 8 4 9 3 6
2 4 8 9 3 6
2 4 8 9 3 6
2 3 4 8 9 6
2 3 4 6 8 9 done
Tipos de análisis

Peor caso: (generalmente)


• T (n) = tiempo máximo del algoritmo en
cualquier entrada de tamaño n.
Caso promedio: (a veces)
• T (n) = tiempo esperado del algoritmo
sobre todas las entradas de tamaño n.
• Necesidad de asumir la distribución
estadística de las entradas.
Mejor caso: (NUNCA)
• Truco con un algoritmo lento que
funciona rápido en algunas entradas.
Insertion Sort
Sentencia Costo Veces
InsertionSort(A, n)
for i ← 2 to n c1 n
do key ← A[i] c2 n-1
j ← i - 1 c3 n-1
while j > 0 and A[j] > key c4 T
do A[j+1] ← A[j] c5 T-(n-1)
j ← j - 1 c6 T-(n-1)
0
A[j+1] ← key c7 n-1


n
T = t2 + t 3 + … + t n =
while para la iesima
i 2 ti
donde t es el número de evaluaciones de la expresión
iteración del bucle for.
i
Analizando el ordenamiento de inserción

• T(n) = c1n + c2(n-1) + c3(n-1) + c4T + c5(T - (n-1)) + c6(T - (n-1)) + c7(n-1)
= c8T + c9n + c10
• ¿Qué puede ser T?
– Mejor caso – cuerpo de bucle interno que nunca se ejecuta
• ti = 1  T(n) es una función lineal
– Peor caso – cuerpo de bucle interno ejecutado para todos los elementos
previos
• ti = i  T(n) es una función cuadrática
– Caso promedio
• ???
Análisis

• Simplificaciones
– Ignorar los costos de declaración reales y abstractos
– El orden de crecimiento es una medida interesante:
• El término de orden más alto es lo que cuenta
– Recuerde, estamos haciendo un análisis asintótico
– A medida que el tamaño de entrada crece, es el término de mayor orden el que
domina
Parte 3

• Introducción a los algoritmos


• Conceptos básicos de análisis de algoritmos
• Notación asintótica
Complejidad asintótica

• Tiempo de ejecución de un algoritmo para tamaños de entrada


grandes.
• Expresado usando solo el término de orden más alto en la
expresión para el tiempo de ejecución exacto.
– En lugar de tiempo de ejecución exacto, digamos Q(n2).
• Describe el comportamiento de las funciones en el límite.
• Descrito usando la notación asintótica.
Notación asintótica

• Q, O, W, o, w
• Definido en términos de funciones cuyo dominio es
el conjunto de números naturales.
– Ej: f(n) = Q(n2).
– Describes como crece f(n) en comparación a n2.
• Determina el conjunto de funciones, en la práctica,
se usa para comparar dos tamaños de función.
• Las notaciones difieren en la relación de tasa de
crecimiento que describen entre la función de
definición y el conjunto definido de funciones.
Notación Q

Para la función g(n), Q(g(n))


esta dado por:

Q(g(n)) = {f(n):  +ve


constantes c1, c2, y n0 tal que
0  c1g(n)  f(n)  c2g(n),
n  n0 }

Intuitivamente: El conjunto de todas


las funciones que tienen el mismo
nivel de crecimiento como g(n).
g(n) es un límite asintoticamente estrecho para f(n).
Notación O

Para la función g(n), O(g(n))


está dado por:

O(g(n)) = {f(n):  +ve


constantes c and n0 tal que 0 
f(n)  cg(n), n  n0 }

Intuitivamente: El conjunto de todas


las funciones cuyo nivel de crecimiento
es el mismo o menor que g(n).
g(n) es un límite superior asintótico para f(n).
f(n) = Q(g(n))  f(n) = O(g(n)).
Q(g(n))  O(g(n)).
Notación W

Para la función g(n), W(g(n))


está dado por:

W(g(n)) = {f(n):  +ve


constantes c and n0 tal que 0 
cg(n)  f(n), n  n0 }
Intuitivamente : El conjunto de todas
las funciones cuyo nivel de crecimiento
es el mismo o mayor que g(n).
g(n) es un límite inferior asintótico para f(n).
f(n) = Q(g(n))  f(n) = W(g(n)).
Q(g(n))  W(g(n)).
Relaciones entre Q, O, W
Notación del límite superior

• Decimos que el tiempo de ejecución de InsertionSort’s es


O(n2)
– Correctamente deberíamos decir que el tiempo de ejecución está en
O(n2)
– Se lee O como “O-grande”
• En general, una función
– f(n) es O(g(n)) si existen constants positivas c y n0 tal que f(n)  c  g(n)
para todos los n  n0
• Formalmente
– O(g(n)) = { f(n):  constantes positivas c y n0 tal que f(n)  c  g(n)  n 
n0}
Ordenamiento de inserción es O(n2)

• Prueba
– Suponga que el tiempo de ejecución es an2 + bn + c
• Si alguno de a, b, y c son menores que 0 reemplace la constante con su valor
absoluto
an2 + bn + c  (a + b + c)n2 + (a + b + c)n + (a + b + c)
 3(a + b + c)n2 para n  1
Sea c’ = 3(a + b + c) y sea n0 = 1
• Pregunta
– InsertionSort es O(n3)?
– InsertionSort es O(n)?
O grande

• Un polinomio de grado k es O(nk)


• Prueba:
– Suponga f(n) = bknk + bk-1nk-1 + … + b1n + b0
• Sea ai = | bi |
– f(n)  aknk + ak-1nk-1 + … + a1n + a0

i
n
 n  ai k k
 n k
a
i  cn k

n
Notación de límite inferior

• Decimos que el tiempo de ejecución de InsertionSort W(n)


• En general, una función
– f(n) es W(g(n)) si  constantes positivas c y n0 tales que 0  cg(n)  f(n) 
n  n0
• Prueba:
– Suponga que el tiempo de ejecución es an + b
• Asumiendo que a y b son positivos (que pasaría si son negativos?)
– an  an + b
Límite asintóticamente estrecho

• Una función f(n) es Q(g(n)) si  constantes positivas c1, c2, y n0


tales que

c1 g(n)  f(n)  c2 g(n)  n  n0

• Teorema
– f(n) es Q(g(n)) si f(n) es ambos O(g(n)) y W(g(n))
Complejidad práctica

250

f(n) = n
f(n) = log(n)
f(n) = n log(n)
f(n) = n^2
f(n) = n^3
f(n) = 2^n

0
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
Complejidad práctica

500

f(n) = n
f(n) = log(n)
f(n) = n log(n)
f(n) = n^2
f(n) = n^3
f(n) = 2^n

0
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
Complejidad práctica

1000

f(n) = n
f(n) = log(n)
f(n) = n log(n)
f(n) = n^2
f(n) = n^3
f(n) = 2^n

0
1 3 5 7 9 11 13 15 17 19
Complejidad práctica

5000

4000
f(n) = n
f(n) = log(n)
3000
f(n) = n log(n)
f(n) = n^2
2000 f(n) = n^3
f(n) = 2^n

1000

0
1 3 5 7 9 11 13 15 17 19
Otras anotaciones asintóticas

• Una función f(n) es o(g(n)) si  constantes positivas c y n0 tales


que
f(n) < c g(n)  n  n0
• Una función f(n) es w(g(n)) si  constantes positivas c y n0 tales
que
c g(n) < f(n)  n  n0
• Intuitivamente,

 o() es como <  w() es como >  Q() es como =


 O() es como   W() es como 
Revisión: Inducción

• Suponga que
– S(k) es verdadero para constante fija k
• A menudo k = 0
– S(n)  S(n+1) para todos los n >= k
• Entonces S(n) es verdad para todos los n >= k
Prueba por inducción

• Si: S(n) es verdadero para todos los n >= k


• Bases:
– Muestra que la fórmula es verdadero cuando n = k
• Hipótesis inductiva:
– Suponga que la fórmula es verdadera para un n arbitrario
• Paso:
– Muestre que la fórmula es verdadera para n + 1
Ejemplo de inducción: formulario cerrado gaussiano

• Probar que 1 + 2 + 3 + … + n = n(n+1) / 2


– Base:
• Si n = 0, entonces 0 = 0(0+1) / 2
– Hipótesis inductiva:
• Asuma que 1 + 2 + 3 + … + n = n(n+1) / 2
– Paso (muestra verdadero para n+1):
1 + 2 + … + n + n+1 = (1 + 2 + …+ n) + (n+1)
= n(n+1)/2 + n+1 = [n(n+1) + 2(n+1)]/2
= (n+1)(n+2)/2 = (n+1)(n+1 + 1) / 2

Vous aimerez peut-être aussi