algoritmos y estructuras de datos carrera t.u · algoritmos y estructuras de datos – carrera...
TRANSCRIPT
UNSA. Sede Orán. Año 2016
Asignatura:
Algoritmos y Estructuras de Datos – Carrera T.U.P
Clases Teóricas: Lic. Jaquelina Jallés (Lunes y Miércoles de 8 a 10:30 hs )
Clases Prácticas: C.U. Daniela Alvarez (Martes y Jueves de 10 a 13hs )
Lugar: Aula de Seminario
Sitio web: www.algoritmossedeoran.wordpress.com
Cronograma – parciales y recup Crono clases 2016 ALGORITMOS Y ED.xls
Programa analítico RESCD-EXA 179-2011-Algoritmos-estr-datos.PDF
1
TEMA:
NOTACION ALGORITMICA MATEMATICA
RECURSION
(APUNTES DE APOYO A CLASES TEÓRICAS)
(TIEMPO DE EXPOSICIÓN 2:30 HS)
.
2
Bibliografía:
6. Knuth D. El Arte de programar ordenadores. Vol 1: Algoritmos Fundamentales.
Ed Reverté SA. Edición en Español 1995.
3. Galvé Javier y otros. Diseño y Análisis de Algoritmos Funcionales e
Imperativos. Ed. Rama. 1993.
4. Lipschutz. Estructuras de Datos. Ed. Mc Graw Hill. 1996.
5. Brassard G. Fundamentos de Algoritmia. Ed. Prentice Hall. 1997.
1. T. Hibbard. Apuntes de Cátedra Algorítmica U.Nsa Sede Salta. Año
2000.
2. J. Yazlle. Apuntes de Cátedra: Aritmética Elemental. U.N.Sa. Marzo 2006.
3
Objetivos:
1. Proponer la notación algorítmica que se utilizará en la materia.
2. Conceptualizar a un algoritmo como una función
3. Definir la recursión como una técnica de resolución de problemas
computacionales
4. Definir función recursiva.
5. Identificar los casos base y general o recursivo en toda fc. recursiva.
6. Identificar las distintas etapas en el proceso de diseño de algoritmos
recursivos.
7. Desarrollar ejemplos de aplicación.
8. Sugerir criterios para usar o no recursión
4
Campo de aplicación:
La técnica de la recursión es ampliamente utilizada en Ciencias de la
Computación, principalmente en el diseño de algoritmos y
lenguajes de programación.
5
Repasemos algunos conceptos:
Algoritmo:
Conjunto finito y no ambiguo de pasos expresados en cierto orden que
permiten resolver un problema en un tiempo finito.
Características de un algoritmo:
1. Finitud:
El algoritmo debe finalizar luego de un n° finito de pasos.
2. Definibilidad:
Cada paso del algoritmo debe definirse de modo preciso. Las acciones deben
estar especificadas rigurosamente y sin ambigüedad.
6
Repasemos algunos conceptos…
Características de un algoritmo …
3. Entrada:
Un algoritmo tiene entradas, que son cantidades dadas al iniciar el
algoritmo.
4. Salida:
Un algoritmo tiene siempre 1 o más salidas.
5. Efectividad:
Todas las acciones del algoritmo deben ser lo bastante básicas para
efectuarse de un modo exacto y en un tiempo finito.
7
La notación algorítmica:
Las acciones que realiza un algoritmo son especificadas mediante: notación algorítmica: La notación algorítmica: Conjunto de convenciones que describen de forma no ambigua un algoritmo. a) Comentarios: dos barras inclinadas y porción de texto. No tiene ningún
efecto Ejemplo: // Caso base b) Identificadores: nombre que se da a un objeto que aparece en la
especificación. Puede ser simbólico, ej signo +, ó alfanumérico: ej: buscar1. c) Tipos de datos: naturales, enteros, reales, caracteres, cadenas, vectores,
tuplas (pares, ternas, etc.), conjuntos, funciones.
8
La notación algorítmica…
d) Instrucciones de asignación: Sea vble = expresión ó vble := expresión Ejemplo: Sea a = a div 10 ó a := a div 10 No debe interpretarse como ecuación e) Instrucciones de retorno: es lo que devuelve un algoritmo . contestar(identificador) ó luego (identificador) contestar(expresión) ó luego(expresión) Ejemplo: contestar(x) ó contestar(Verdadero)
f) Instrucciones condicionales: Si (condición) luego lista1_de_acciones Sino lista2_de_acciones Ejemplo: Si (a > b) luego contestar(a) Sino contestar(b)
9
La notación algorítmica matemática… 10
g) Estructuras de control repetitivas:
g.1) Ciclo Para Escribimos: Para vble: = valor_inicial hasta valor_final Hacer lista_de_Instrucciones Fin_Para g.2) Ciclo Mientras: Escribimos: Mientras (Condición=Verdadera) Hacer Lista_de_Instrucciones Fin_Mientras
La notación algorítmica…
En notación algorítmica:
nombre_funcion ( argumentos ) = expresión
donde : expresión = formada por instrucciones, una de las cuales debe ser “de retorno” Ejemplo:
cubo(x) = contestar( x * x * x)
11
x f f(x)
Función: Podemos pensar en una función como un algoritmo, el cual provee un
esquema para obtener un valor.
La notación matemática y la notación algorítmica
Ejemplo 1: f(x) = x
12
x =
En notación matemática:
-x si x < 0
x si x 0
En notación algorítmica:
abs(x) = si (x < 0) luego contestar(-x)
sino contestar (x)
Ejemplo 2: menor(x, y)
menor(x,y)=
En notación matemática:
x si x < y
y si x y
En notación algorítmica:
menor(x, y) = Si (x < y) luego contestar(x)
Sino contestar (y)
La notación algorítmica…
Aplicación de la función: es la evaluación de la función en el valor del argumento. nombre_funcion ( valor_argumentos )
Ejemplos de aplicación de fc:
1) En la fc: cubo(x) = contestar(x * x* x)
la evaluación de cubo(2) retorna 8
2) En la fc: menor(x,y) = si (x < y) luego contestar(x) sino contestar(y) La evaluación de menor(2, 5) retorna 2
13
La notación algorítmica…
Invocación de funciones en el cuerpo de una función: a) Una función puede invocar a otra función: Ej. Redefinimos cubo(x):
cubo(x) = contestar(x * cuadrado(x))
donde // inicio de definición de cuadrado
cuadrado(x) = contestar(x * x)
b) Una función puede invocarse a sí misma: Llamamos a esta función, función recursiva
14
Recursión:
Definición:
Es una técnica de diseño de algoritmos, mediante la cual una función se define
en términos de sí misma.
En el cuerpo de función aparece alguna aplicación suya.
15
f(x) = …………
………...
..f(x-1) ..
…………
Esquemáticamente:
Recursión:
Ejemplo: Queremos calcular x n , x 0 y n 0
x n =
1 Si n = 0
x * x (n-1) Si n > 0
En notación algorítmica:
Ej: 2 4 = 2 * 2 3
2 3 = 2 * 2 2
2 2 = 2 * 2 1
2 1= 2 * 2 0
2 0= 1
= 2 * 1 = 2
= 2 * 2 = 4
= 2 * 4 = 8
= 2 * 8 = 16 Resultado
La definición de potencia en notación matemática es:
potencia(x, n) = Si (n >0) luego contestar (x * potencia(x,n-1) )
Sino contestar (1)
16
Recursión …
potencia(x, n) = Si (n >0) luego contestar (x * potencia(x, n-1))
Sino contestar (1)
Ejemplo:
Potencia(2, 4) = contestar (2 * potencia(2, 3))
Potencia(2, 3) = contestar (2 * potencia(2, 2))
Potencia(2, 2) = contestar (2 * potencia(2, 1))
Potencia(2, 1) = contestar (2 * potencia(2, 0))
Potencia(2, 0) = contestar (1)
2 * 1 = 2
2 * 2 = 4
2 * 4 = 8
2 * 8 = 16 Retorna 16
Caso base:
La función
no recurre
Caso general o
recursivo: con
parámetros más
pequeños 17
Recursión:
Etapas en el diseño de algoritmos recursivos
1) Dado un problema, entenderlo:
Ejemplificarlo, distinguir datos de entrada y de salida
2) Expresar el problema mediante un modelo (matemático cuando sea
posible):
Identificar: Caso base ( la función no recurre)
Caso general o recursivo: la función se invoca con
argumentos más pequeños
3) Traducir el modelo a un algoritmo en notación algorítmica
4) Diseñar casos de prueba
5) Realizar la traza de ejecución
6) Traducir el algoritmo a un programa en un lenguaje de programación
funcional (clase práctica)
7) Probar el programa (clase práctica)
18
Ejemplo: cociente(a, b), algoritmo muy utilizado en la materia
Dados a y b números naturales positivos, escribir un algoritmo recursivo que devuelva el cociente natural entre a y b utilizando sumas y restas solamente.
19
Ejemplificamos con caramelos y alumnos:
Repartir (10 caramelos, 4 alumnos) =
como 10 caramelos es mayor o igual a 4 entonces doy 1 caramelo a cada alumno y
vuelvo a Repartir((10-4) caramelos, 4 alumnos)
Repartir (6 caramelos, 4 alumnos) =
como 6 caramelos es mayor o igual a 4 entonces doy 1 caramelo más a cada alumno y
vuelvo a Repartir((6-4) caramelos, 4 alumnos)
Repartir (2 caramelos, 4 alumnos) =
como 2 caramelos NO es mayor o igual a 4 entonces doy 0 caramelo a cada alumno y
No vuelvo a Repartir
Cuántas veces pude repartir? 2 , ese es el cociente (10, 4) , las veces que pude repartir
Veremos en forma general: cociente (a, b) …
Ejemplo: cociente(a, b), algoritmo muy utilizado en la materia
Generalizamos:
Dados a y b números naturales positivos, escribir un algoritmo recursivo que devuelva el cociente natural entre a y b utilizando sumas y restas solamente. Etapa 1) Entender el problema:
Ejemplo: si a = 15 y b = 4 las entradas son 15 y 4 ; la salida será 3
Etapa 2) Proceso de calcular el cociente natural entre a y b, es contar las veces
que puedo restar b de a; es decir mientras a sea b.
15 - 4 = 11 ; contaremos 1 vez. (1)
11 - 4 = 7, aumentaremos el contador de veces (2)
7 – 4 = 3, aumentaremos el contador de veces (3)
3 – 4 no lo hacemos ya que 3 es menor que 4, lo que indica la finalización del proceso y no contamos. Luego el contador (contiene 3) es el resultado buscado
20
Ejemplo: cociente(a, b)
Etapa 3) Obtener un algoritmo:
- Versión iterativa (sin recursión):
cociente(a, b) =
c := 0; // contador
Mientras (a b) Hacer
a := a - b;
c := c + 1;
Fin_Mientras
contestar(c)
Etapa 3) Obtener un algoritmo:
- Versión recursiva
cociente(a, b) =
Si (a b) luego
contestar( 1 + cociente(a-b, b) )
sino contestar (0)
Caso base: no se puede restar
b de a
Caso general: argumento más
pequeño
21
Etapa 4) Diseñar casos de prueba: Caso 1: a = 3, b= 4; Caso 2: a = 15, b = 4
Etapa 5) Realizar la traza de ejecución:
cociente(3,4) = contestar (0) Retorna 0 ; cociente(3,4) = 0
cociente(15,4) = contestar (1 + cociente(15 - 4, 4))
cociente(11,4) = contestar (1 + cociente(11-4, 4))
Retorna 3
cociente(7, 4) = contestar (1 + cociente(7-4, 4))
cociente(3, 4) = contestar (0)
0
1
2
cociente(a, b) = Si (a b) luego contestar( 1 + cociente(a-b, b) ) sino contestar (0)
cociente(15,4) = 3
22
Caso 1: a = 3, b= 4
Caso 2: a = 15, b= 4
1 + 0 = 1
1 + 1 = 2
1 + 2 = 3
Pruebas con los alumnos:
• Cociente (13, 4)
• Cociente (21, 7)
cociente(a, b) = Si (a b) luego contestar( 1 + cociente(a-b, b) ) sino contestar (0)
23
cociente(a, b) = c := 0; // contador Mientras (a b) Hacer a := a - b; c := c + 1; Fin_Mientras contestar(c)
cociente(a, b) Versión iterativa y recursiva
Otro ejemplo: Búsqueda Secuencial
Dado un vector v de n números, realizar la búsqueda de un elemento t.
Etapa 1) Entender el problema: Buscar un elemento que esté en el vector: Ejemplo: si v=[12,25,7,19,23] , n = 5, t =7 la salida será Verdadero
12 25 7 19 23 v t = 7
i=1
24
¿ t = v[i] ? ¿ 7 = v[1]= 12 => => NO
12 25 7 19 23 v
i=2
¿ t = v[i] ? ¿ 7 = v[2]= 25 => => NO Incrementar i
12 25 7 19 23 v
i=3
¿ t = v[i] ? ¿ 7 = v[3]= 7 => SI Verdadero
Incrementar i
Ejemplo: Búsqueda Secuencial
Etapa 1) Entender el problema … Buscar un elemento que NO esté en el vector: Ejemplo: si v=[12,25,7,19,23] , n = 5, t =1 la salida será Falso
12 25 7 19 23 v
i=1
25
¿ t = v[i] ? ¿ 1 = v[1]= 12 => => NO,
Incrementar i
12 25 7 19 23 v
i=2
¿ t = v[i] ? ¿ 1 = v[2]= 25 => => NO,
Incrementar i
12 25 7 19 23 v
i=3
¿ t = v[i] ? ¿ 1 = v[3]= 7 => No,
Incrementar i
12 25 7 19 23 v
i=4
¿ t = v[i] ? ¿ 1 = v[4]=19 => No,
Incrementar i
12 25 7 19 23 v
i=5
¿ t = v[i] ? ¿ 1 = v[5]=23 => No,
Incrementar i i = 6 > n => Falso
Ejemplo: Búsqueda Secuencial
Versión iterativa: Recordar cómo lo hacíamos en Programación
26
Inicializar variables: i =1
Mientras ((i n) y t v[i]) Hacer i=i+1
Buscar(v,n,t) =
Fin-Mientras
Si (i> n) Contestar (Falso) Sino contestar(Verdadero)
Ejemplo: Búsqueda Secuencial
Etapa 2) Expresar el problema mediante un modelo, para ello debemos Identificar:
27
Caso base: 1. NO Encontrado 2. Encontrado
i > n
v[i] = t
Si (i n) y t v[i] entonces buscar(v, i+1, n) Caso general o recursivo:
buscar(v, n, t) =
Si (n=0) luego contestar(“V Vacío”)
Sino buscar1(v, 1, n, t)
donde
buscar1(v, i, n, t) =
Si (i n) luego
Si (v[i] = t) luego contestar (Verdadero)
Sino buscar1(v, i+1, n, t)
Sino contestar(Falso)
Caso General
Caso Base
Etapa 3) Obtener un algoritmo:
- Versión recursiva
Ejemplo: Búsqueda Secuencial
Etapa 4) Diseñar casos de prueba: Caso1: t = 7 (Verdadero) , Caso 2: t =1 (Falso)
Etapa5) Realizar la traza de ejecución: Caso 1 ( t = 7)
buscar([12, 25, 7, 19, 23], 5, 7) = buscar1([12, 25, 7, 19, 23], 1, 5, 7) buscar1([12, 25, 7, 19, 23], 1, 5, 7) // i= 1; i 5; 12 7 => buscar1([12, 25, 7, 19, 23], 2, 5, 7) // i= 2; i 5; 25 7 => buscar1([12, 25, 7, 19, 23], 3, 5, 7) = // i= 3; i 5; 7 = 7 => Verdadero
28
buscar(v, n, t) = Si (n=0) luego contestar(“V Vacío”) Sino buscar1(v, 1, n, t) donde buscar1(v, i, n, t) = Si (i n) luego Si (v[i] = t) luego contestar (Verdadero) Sino buscar1(v, i+1, n, t) Sino contestar(Falso)
Ejemplo: Búsqueda Secuencial
Etapa5) Realizar la traza de ejecución: Caso 2 ( t = 1)
buscar([12, 25, 7, 19, 23], 5, 1) = buscar1([12, 25, 7, 19, 23], 1, 5, 1) buscar1([12, 25, 7, 19, 23], 1, 5, 1) = // i= 1; i 5; 12 1 => buscar1([12, 25, 7, 19, 23], 2, 5, 1)= // i= 2; i 5; 25 1 => buscar1([12, 25, 7, 19, 23], 3, 5, 1) = // i= 3; i 5; 7 1 => buscar1([12, 25, 7, 19, 23], 4, 5, 1) = // i= 4; i 5; 19 1 => buscar1([12, 25, 7, 19, 23], 5, 5, 1) = // i= 5; i 5; 23 1 => buscar1([12, 25, 7, 19, 23], 6, 5, 1) = // i= 6; i > n => Falso
29
buscar(v, n, t) = Si (n=0) luego contestar(“V Vacío”) Sino buscar1(v, 1, n, t) donde buscar1(v, i, n, t) = Si (i n) luego Si (v[i] = t) luego contestar (Verdadero) Sino buscar1(v, i+1, n, t) Sino contestar(Falso)
Ejemplo: Búsqueda Secuencial
Prueba con los alumnos: buscar([12, 25, 7, 19, 23], 5, 12)
buscar([12, 25, 7, 19, 23], 5, 23) buscar([12, 25, 7, 19, 23], 5, 15)
30
buscar(v, n, t) = Si (n=0) luego contestar(“V Vacío”) Sino buscar1(v, 1, n, t) donde buscar1(v, i, n, t) = Si (i n) luego Si (v[i] = t) luego contestar (Verdadero) Sino buscar1(v, i+1, n, t) Sino contestar(Falso)
Ejemplo: Búsqueda Secuencial
Prueba con los alumnos: buscar([12, 25, 7, 19, 23], 5, 12)
buscar([12, 25, 7, 19, 23], 5, 23) buscar([12, 25, 7, 19, 23], 5, 5)
31
buscar(v, n, t) = Si (n=0) luego contestar(“V Vacío”) Sino buscar1(v, 1, n, t) donde buscar1(v, i, n, t) = Si (i n) luego Si (v[i] = t) luego contestar (Verdadero) Sino buscar1(v, i+1, n, t) Sino contestar(Falso)
Inicializar variables: i =1
Mientras ((i n) y t v[i]) Hacer i=i+1
Buscar(v,n,t) =
Fin-Mientras
Si (i> n) Contestar (Falso) Sino contestar(Verdadero)
Criterios: Cuándo usar recursión ?
• Cuando el dato está definido recursivamente:
Ejemplo: las listas o vectores, árboles.
• Cuando el algoritmo sea repetitivo y trata valores cada vez más
pequeños:
Ejemplo: invertir un entero, cantidad de dígitos de un número.
• Cuando obtener una solución iterativa sea mucho más complicado que
una solución recursiva.
Ejemplo: búsqueda secuencial
32
Criterios: Cuándo No usar recursión ?
• Cuando el lenguaje de programación no lo permita:
Ejemplo: Fortran, Cobol
• Cuando la solución iterativa sea clara a simple vista.
33
• Cuando el tamaño de los argumentos sea muy grande.
El Lenguaje de Programación: Haskell
Breve historia
Compiladores y EDI.
El lenguaje
Bibliografía Haskell
Comandos mas utilizados en los compiladores.
Demo: Haskell
34
El Lenguaje de Programación: Haskell
Breve historia es un lenguaje de programación multi-propósito puramente funcional con fuerte tipificación.
Su nombre se debe al lógico estadounidense Haskell Curry.
1987: Comienza a diseñarse Lenguaje Haskell .
1990: Haskell 1.0
1995: Haskell 1.3
1998: Haskell98: Vesión estable de Haskell y GOFER como subconjunto de Haskell
Implementaciones :
HUG 98 versión Libre de Haskell : Intérprete de Haskell (2006 última versión).
http://www.haskell.org/hugs/
WinGHC: Ultima versión 2015: 7.10.3. para 32 y 64 bits
https://www.haskell.org/platform/windows.html
35
El Lenguaje de Programación: Haskell
Es un lenguaje funcional puro.
Todos los cómputos vienen descritos a través de la evaluación
de expresiones (términos sintácticos) para producir valores (entidades abstractas
que son vistas como respuestas).
Todo valor tiene asociado un tipo.
Ejemplos de expresiones de tipo son los tipos atómicos:
Integer (enteros con precisión ilimitada), es el conjunto de los enteros {…, -3; -2; -1; 0; 1; 2;
3;…}
Int: enteros de rango limitado que cubren al menos el intervalo -229 .. 229
Float y Double: reales de menor a mayor precisión
Char : representa un carácter. Se escribe entre comillas simples: ‘a’
Integer->Integer (funciones que aplican Integer sobre Integer),
Bool : True y False
36
El Lenguaje de Programación: Haskell
Los tipos estructurados:
Listas:
[Integer] lista homogénea de enteros
[Char] lista de caracteres ó strings
Tuplas:
(Char, Integer) (una tupla formada por un carácter y un entero).
37
El Lenguaje de Programación: Haskell
Sintáxis:
Los nombres de función comienzan por minúscula: f , suma, mayor
Los nombres de argumentos comienzan por minúscula: x, y, a, b
Los nombres de tipos: comienzan por mayúscula: Integer, Bool, Char, etc
38
El Lenguaje de Programación: Haskell
Funciones
Ya que Haskell es un lenguaje funcional, podemos esperar que las funciones
jueguen un papel esencial.
Consideremos la siguiente definición de función que suma sus dos argumentos:
suma :: Integer -> Integer -> Integer --Declaración de la fc
tipo 1er arg tipo 2do arg tipo resultado
suma x y = x + y -- Definición de la fc
Este es un ejemplo de función parcializada o currificada (curried).
El origen del nombre curry proviene de la persona que popularizó el uso de la
parcialización: Haskell Curry.
39
El Lenguaje de Programación: Haskell
Funciones
La función anterior en forma no parcializada o no currificada (uncurried), podemos
usar una tupla:
suma :: (Integer, Integer) -> Integer -- Declaración de la fc
tipo del arg tipo del resultado
suma (x,y) = x + y
40
Compilador Hugs 98: 41
Compilador WinGHC: 42
Bibliografía Lenguaje Haskell:
Introducción Agradable al Haskell:
http://www.lcc.uma.es/~blas/pfHaskell/gentle/
http://www.lcc.uma.es/~pepeg/mates/tema1.pdf al tema 3. Universidad
de Málaga
Libro electrónico Razonando con Haskell de Richard Bird (en S.R.O)
http://books.google.com.ar/books?id=xIlyOiGOC6EC&printsec=frontcover&d
q=haskell&hl=es&ei=5NFaTpmfG8bY0QHDr4mVCQ&sa=X&oi=book_result
&ct=result&resnum=2&ved=0CDEQ6AEwA#v=onepage
43
Comandos más utilizados en los
compiladores: 44
:edit nombre.hs edita el archivo
:e nombre.hs edita el archivo
:e edita el último archivo
:? muestra la lista de comandos
:load “archivo.hs” carga el archivo.hs
:quit exit GHCi
:q exit GHCi
:l “archivo.hs” carga el archivo.hs
carácter ` (por ejemplo en `mod`) alt 96
/= distinto
== igual de comparación
&& y (conjunción)
|| o (disyunción)
Aclaraciones de Sintáxis Haskell:
Ejemplo: 45
Determinar el mayor de dos números a y b.
Ejemplo de Código Haskell: (si … sino) (if … then)
función mayor:
may(a,b) = if (a > b) then a
else b
1) Escribimos en el EDI de WinGHCi: *Main> :e tp0recursion.hs
Como es un archivo nuevo, se abre el Block de Notas:
2) Escribimos el código del algoritmo:
46
4.1) Cargamos a memoria el archivo .hs: *Main> :l "tp0recursion.hs"
4.2) Ejecutamos el algoritmo: *Main> may(39,69)
69
Ejemplo: Determinar el mayor de dos números a y b.
3) Guardamos el algoritmo : Archivo/Guardar como …:
4) Probamos el algoritmo:
47
Ejemplo: Funciones cuadrado(x), minimo(x,y), otras
Para resumir la clase de hoy ….
Algoritmo - Características
Comentarios
Identificadores
Notación
Algorítmica -
Matemática
Instrucciones
Función
=
Algoritmo
Notación para definirla
Aplicación A otra función
Invocación A sí misma (Recursión)
Asignación
Retorno
Condicionales
Definición
Etapas del diseño
Ejemplos
Criterios
Tipos de datos
48
Implementación
Haskell