32
ESTALMAT -Andalucía Oriental Actividades 07/08 Sesión: 20 Fecha: 26-04-2008 Título: Programación Matemática: Aplicaciones. _____________________________________________________________________________ En esta segunda sesión vamos a trabajar los siguientes contenidos: - Procedimientos. - Programación Matemática: Aplicaciones. Actividades: Actividad 1: Procedimientos. Proyecto “Visor de Imágenes” Mejora el Visor de Imágenes. Agrega un módulo que vas a llamar “mdlDibujando” al proyecto para escribir los procedimientos AbrirImagen y el procedimiento “DibujaBorde ” y sustituye el código que se repite de Visor de Imagen por llamadas a estos procedimientos. Termina de programar las opciones del formulario frmOpciones. Solución: Recuerda que un Objeto es una estructura de programación que encapsula datos y funciones en una sola unidad y a la que solo se puede acceder a través de sus interfaces (propiedades, métodos y eventos). Las Propiedades son atributos que describen al Objeto. Los métodos acciones que el objeto es capaz de realizar. Los eventos son métodos que se ejecutan de un modo especial provocados por el usuario al interactuar con los controles de un formulario. Recuerda también que un procedimiento es un conjunto discreto de código que puede ser ejecutado desde otros bloques de código. Existen dos tipos de procedimientos: Que devuelven un valor (denominados funciones). Que no devuelven un valor(denominados subrutinas o simplemente procedimientos) Funciones Public Function Nombre( ByVal o ByRef variable As …) As … Código… End Function Subrutinas o procedimientos Public Sub Nombre( ByVal o ByRef variable As …) Código… End Sub Página 1 Paco Villegas & Luis Cabello

ESTALMAT -Andalucía Oriental Actividades 07/08thales.cica.es/geogebra/sites/thales.cica.es.estalmat.oriental/files/s... · Actividad 1: Procedimientos. Proyecto “Visor de Imágenes”

  • Upload
    others

  • View
    2

  • Download
    0

Embed Size (px)

Citation preview

Page 1: ESTALMAT -Andalucía Oriental Actividades 07/08thales.cica.es/geogebra/sites/thales.cica.es.estalmat.oriental/files/s... · Actividad 1: Procedimientos. Proyecto “Visor de Imágenes”

ESTALMAT -Andalucía Oriental Actividades 07/08Sesión: 20 Fecha: 26-04-2008 Título: Programación Matemática: Aplicaciones. _____________________________________________________________________________ En esta segunda sesión vamos a trabajar los siguientes contenidos:

- Procedimientos. - Programación Matemática: Aplicaciones.

Actividades:Actividad 1: Procedimientos.Proyecto “Visor de Imágenes” Mejora el Visor de Imágenes. Agrega un módulo que vas a llamar “mdlDibujando” al proyecto para escribir los procedimientos AbrirImagen y el procedimiento “DibujaBorde” y sustituye el código que se repite de Visor de Imagen por llamadas a estos procedimientos. Termina de programar las opciones del formulario frmOpciones.

Solución: Recuerda que un Objeto es una estructura de programación que encapsula datos y funciones en una sola unidad y a la que solo se puede acceder a través de sus interfaces (propiedades, métodos y eventos).Las Propiedades son atributos que describen al Objeto. Los métodos acciones que el objeto es capaz de realizar. Los eventos son métodos que se ejecutan de un modo especial provocados por el usuario al interactuar con los controles de un formulario.

Recuerda también que un procedimiento es un conjunto discreto de código que puede ser ejecutado desde otros bloques de código.Existen dos tipos de procedimientos:

• Que devuelven un valor (denominados funciones).• Que no devuelven un valor(denominados subrutinas o simplemente

procedimientos)FuncionesPublic Function Nombre(ByVal o ByRef variable As …) As … Código…End Function

Subrutinas o procedimientosPublic Sub Nombre(ByVal o ByRef variable As …) Código…End Sub

Página 1 Paco Villegas & Luis Cabello

Page 2: ESTALMAT -Andalucía Oriental Actividades 07/08thales.cica.es/geogebra/sites/thales.cica.es.estalmat.oriental/files/s... · Actividad 1: Procedimientos. Proyecto “Visor de Imágenes”

ESTALMAT -Andalucía Oriental Actividades 07/08Sesión: 20 Fecha: 26-04-2008 Título: Programación Matemática: Aplicaciones. _____________________________________________________________________________ Carga el proyecto VisorImagen que está en la carpeta sesion20 del escritorio.Pincha en Proyecto>Agregar Módulo… y ponle el nombre dibujando. Escribe el siguiente código:Public Sub AbrirImagen() 'Mostrar el cuadro de diálogo abrir If frmVisor.ofdSeleccionaImagen.ShowDialog = Windows.Forms.DialogResult.OK Then 'Cargar la Imagen en el cuadro de Imagen frmVisor.PicAlojoImagen.Image = _ Image.FromFile(frmVisor.ofdSeleccionaImagen.FileName) 'Mostrar el nombre del archivo en el titulo del formulario frmVisor.sbrBarraEstado.Items(0).Text = _ frmVisor.ofdSeleccionaImagen.FileName End If End Sub Public Sub DibujaBorde(ByRef objcajadibujo As PictureBox) Dim objGraphics As Graphics objGraphics = objcajadibujo.Parent.CreateGraphics objGraphics.Clear(System.Drawing.SystemColors.Control) objGraphics.DrawRectangle(Pens.Blue, _ objcajadibujo.Left - 1, objcajadibujo.Top - 1, _ objcajadibujo.Width + 1, objcajadibujo.Height + 1) objGraphics.Dispose() End Sub

Observa que el código de AbrirImagen() coincide casi exactamente con el código asociado a los eventos del botón Imagen del Ítem del Menú Fichero Abrir Imagen y del icono de Barra de la barra de herramientas. Explica cuál es la diferencia.Repitamos y veamos las diferencias del trozo de código que dibuja el borde con el procedimiento DibujaBorde.Ahora sustituimos los trozos de códigos por llamadas a los procedimientos AbrirImagen () y DibujaBorde(picAlojoImagen)¿Es mejor el procedimiento DibujaBorde que AbrirImagen? ¿Por

qué motivo? Trata de mejorar el procedimiento AbrirImagen

Actividad 2: Programación Matemática.Programa: Criba.

Página 2 Paco Villegas & Luis Cabello

Page 3: ESTALMAT -Andalucía Oriental Actividades 07/08thales.cica.es/geogebra/sites/thales.cica.es.estalmat.oriental/files/s... · Actividad 1: Procedimientos. Proyecto “Visor de Imágenes”

ESTALMAT -Andalucía Oriental Actividades 07/08Sesión: 20 Fecha: 26-04-2008 Título: Programación Matemática: Aplicaciones. _____________________________________________________________________________ Diseña una solución que simule la criba de Eratóstenes para buscar los números enteros y positivos primos que hay hasta un número entero positivo dado de antemano.Solución: Vamos a programar un método propuesto por Eratóstenes para obtener la lista de todos los primos menores, hasta cierto valor.Los pasos del método son:

• Primero hacemos una lista de todos los números desde 1 hasta n.• Tachamos el 1. • Tomamos el 2 y tachamos todos los múltiplos de 2 en la lista. • Buscamos el primer número sin tachar y tachamos todos sus múltiplos mayores. • Repetimos el paso anterior hasta que se acaben los números. • Los que quedaron sin tachar son los que no tienen divisores (propios) o sea los primos.

Monta el formulario como el que tienes en la imagen y programa los botones lista y criba, para ello escribe las líneas de programación oportunas e introduce los comentarios que creas necesarios para que aclaren el funcionamiento del código.

Utilizamos el control ListView para mostrar la lista de todos los números cuando se pulse el

botón y ponga en azul los múltiplos cuando se pulse el botón

Utilizaremos una matriz en este ejercicio. Una matriz se declara de forma parecida a como se hace con una variable:Dim lista(n) as Integer. lista(n) es una caja con n+1 elementos.Para almacenar un valor lista(2)=3, el tercer elemento de la matriz es un 3. Una Matriz se puede llenar mediante un bucle.La idea es llenar una matriz con n+1 elementos. Colocamos en lista(0) un cero, en todos los demás elementos de la matriz un -1 ¿Con que bucle?.Un -1 en lista(i) indica que i está sin tachar (primo).Un 0 en lista (i) indica que i está tachado (no primo).Hacemos lista(1)=0 y lo ponemos azul.Y viene el bucle anidado milagroso que busca el primer número sin tachar y tachamos todos sus múltiplos mayores. Así sucesivamente.For p = 2 To n If lista(p) = -1 Then MsgBox("Tachamos mútiplos de " & p)

Página 3 Paco Villegas & Luis Cabello

Page 4: ESTALMAT -Andalucía Oriental Actividades 07/08thales.cica.es/geogebra/sites/thales.cica.es.estalmat.oriental/files/s... · Actividad 1: Procedimientos. Proyecto “Visor de Imágenes”

ESTALMAT -Andalucía Oriental Actividades 07/08Sesión: 20 Fecha: 26-04-2008 Título: Programación Matemática: Aplicaciones. _____________________________________________________________________________ For j = p * p To n Step p lista(j) = 0 ListView1.Items.Item(j - 1).BackColor = Color.Blue Next j End If Next p

Actividad 3: Programación matemática: AplicacionesPrograma: SuperCriba.Para cada primo p, el múltiplo (propio) más chico que no esta tachado es p2. Así que los primos menores que la raíz cuadrada de n pueden tener múltiplos sin tachar en la tabla, pero los mayores no. ¿Es cierto esto? ¿Porqué?.Basándote en el razonamiento anterior mejora el programa Criba (llámalo SuperCriba) para que sea más rápido.Puedes crear otra versión donde la salida sean los primos menores o iguales que el número de entrada.

Actividad 4: Programación matemática: Aplicaciones.Programa: Descomposición en factores primos.A veces para factorizar un número lo escribimos como producto de dos factores de forma fácil y repetimos el mismo proceso para cada parte hasta que lo descomponemos totalmente.Ejemplo:140= 10*14 = (2*5)*(7*2). También puede ser 140 = 2*(70)=2*(7*10)=2*(7*(2*5)). Se podría hacer de muchas maneras pero el resultado siempre es el mismo aunque los factores no estén el mismo orden. Diseña un programa que descomponga de esta manera. SoluciónObserva como podríamos hacer para que el ordenador encontrara algún factor. Dim Raiz, otro, i, factor As Integer Raiz = Int(Math.Sqrt(Numero)) - 1 'Prueba solo hasta la raiz cuadrada por la que ya sabemos 'Pero no con 1 otro = 1 For i = 1 To ParaProbar * Raiz 'Prueba muchas veces a factorizarlo buscando un posible factor aleatorio menor que la raíz del número factor = 2 + Int(Rnd() * Raiz) If Numero Mod factor = 0 Then

Página 4 Paco Villegas & Luis Cabello

Page 5: ESTALMAT -Andalucía Oriental Actividades 07/08thales.cica.es/geogebra/sites/thales.cica.es.estalmat.oriental/files/s... · Actividad 1: Procedimientos. Proyecto “Visor de Imágenes”

ESTALMAT -Andalucía Oriental Actividades 07/08Sesión: 20 Fecha: 26-04-2008 Título: Programación Matemática: Aplicaciones. _____________________________________________________________________________ otro = Numero \ factor Exit For End If NextParaProbar es una constante para que intente encontrar el factor las veces que se quiera.Si no encuentra un factor podría ser primo. El siguiente código es para comprobar si es primo. If otro = 1 Then 'No ha encontrdo factor, quizas Numero es primo For factor = 2 To Raiz + 1 If Numero Mod factor = 0 Then otro = Numero \ factor Exit For End If Next factor End If Lo puedes ver en la carpeta de la sesion 20. En general ver si un número muy grande es primo o no, es un problema difícil aunque hay algoritmos rápidos, pero basados en matemática más avanzada. Si tratamos de utilizar los métodos que vimos antes para ver si 10000000200000001 es primo, utilizando la criba seguro que nos quedamos sin memoria, y si tratamos de probar dividiendo por los anteriores es demasiado lento.

Tremendamente más difícil es factorizar un número si es muy grande, aunque sepamos que nos es primo. En esta dificultad se basa la seguridad de algunos sistemas de encriptación de clave pública por ejemplo el PGP, en este caso se tienen dos claves:

• La pública: esta clave se da a conocer y permite que cualquiera sea capaza de cifrar un mensaje, pero no se puede usar para descifrarlo.

• La privada: Es secreta y con ella se pueden descifrar los mensajes que se cifraron utilizando la clave pública.

Resulta que la clave privada son dos números primos grandes y la pública es el producto de los dos primos grandes que componen la privada.

Actividad 5: Programación matemática: Aplicaciones.Programa: ContarFactorizaciones.Diseña un solución en visual Basic que averigüe cuántos números enteros positivos menores que un cierto numero p, entero positivo dado de antemano, tienen como únicos factores primos al 2, 3 ó 5. (Por ejemplo: 2, 8, 15, 30, 60, ...)

Página 5 Paco Villegas & Luis Cabello

Page 6: ESTALMAT -Andalucía Oriental Actividades 07/08thales.cica.es/geogebra/sites/thales.cica.es.estalmat.oriental/files/s... · Actividad 1: Procedimientos. Proyecto “Visor de Imágenes”

ESTALMAT -Andalucía Oriental Actividades 07/08Sesión: 20 Fecha: 26-04-2008 Título: Programación Matemática: Aplicaciones. _____________________________________________________________________________

Solución.

El enunciado pide contar cuántos enteros n cumplen n >= 1, n < p, y n = 2a·3b·5c. Como el 1 no sirve, lo descartamos.Lo que vamos a hacer es un programa que pruebe todos los números enteros desde 2 hasta p, y los cuente cuando el número sólo tiene como factores primos al 2, 3 ó 5.

Primero hacemos una copia del valor del número en la variable Vaquedando.

Eliminamos todos los doses de la factorización de Vaquedando. Para ello utilizamosSi tiene de factor al 2 Vaquedando lo dividimos por 2.Se repite este proceso hasta que estemos seguros de eliminar a todos los 2. Para ello utilizamos el bucle: Do While (Vaquedando Mod 2 = 0) Vaquedando = Vaquedando / 2 LoopHacemos lo mismo con 3 y 5Si al final Vaquedando es 1 hemos encontrado una factorización válida, la contabilizamos y pasamos al siguiente número.Se podría mejorar el programa para que el usuario eligiera los tres primos de la descomposición.El programa lo tienes en la carpeta sesión20.

Página 6 Paco Villegas & Luis Cabello

Page 7: ESTALMAT -Andalucía Oriental Actividades 07/08thales.cica.es/geogebra/sites/thales.cica.es.estalmat.oriental/files/s... · Actividad 1: Procedimientos. Proyecto “Visor de Imágenes”

Programación matemática. Aplicaciones

Recursividad

Luis Cabello & Paco Villegas

26 de abril de 2008

ESTALMAT - ANDALUCÍA

Índice1. Introducción: algoritmos 2

1.1. El coste de los algoritmos: . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21.1.1. El problema del viajante . . . . . . . . . . . . . . . . . . . . . . . . . 2

2. Funciones recursivas 5

3. Ejemplos 63.1. Factorial de un número . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63.2. Sucesión de Fibonacci . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73.3. Torres de Hanoi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

3.3.1. Un poco de historia: . . . . . . . . . . . . . . . . . . . . . . . . . . . 93.3.2. Resolución . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

Page 8: ESTALMAT -Andalucía Oriental Actividades 07/08thales.cica.es/geogebra/sites/thales.cica.es.estalmat.oriental/files/s... · Actividad 1: Procedimientos. Proyecto “Visor de Imágenes”

Introducción: algoritmos Estalmat-Andalucía 07/08

1. Introducción: algoritmosLa palabra algoritmo proviene del nombre de un matemático árabe del siglo IX llamado

Muhammad ibn Musã al-Khwãrizmı (es decir, Muhannmad, hijo de Musã, nacido en Khwã-rezm), se trata de unos de los “padres” del Álgebra. Entre sus aportaciones destacar que fue unolos culpables de la introducción del sistema árabe de numeración. Pero ¿qué es un algoritmo?

Conjunto de reglas que, aplicadas sistemáticamente a unos datos de entradaadecuados, resuelven un cierto problema en un número finito de pasos elementales[1]

En el instituto y en el colegio se os han enseñado bastantes algoritmos (algunos que segurose han olvidado ya), por ejemplo el del cálculo de la parte entera de la raíz cuadrada de unnúmero natural, el algoritmo de Euclides para calcular el máximo común divisor, o por ejem-plo, el algoritmo de la multiplicación (no confundirlo con las tablas de multiplicar, no son unalgoritmo):

Para multiplicar 4 ·3, se suma 4 tres veces (claro antes tengo que saber sumar), es decir:4 ·3 = 4+4+4 = 8+4 = 12

NOTA: No penséis que multiplicar dos números es tan simple a nivel informático. Cuando setrabaja con números enteros muy grandes, puede ocurrir que los operandos se vuelvan tangrandes que no se puedan operar de forma directa (a partir del tamaño de palabra de lacomputadora). En este caso se usan algoritmos “especiales” (del tipo divide y vencerás)que permitan hacer los cálculos.

Cuestiones antes de seguir:

¿Qué algoritmos conocéis más?

Una receta de cocina ¿es un algoritmo?

¿Podemos encontrar un algoritmo para calcular de forma exacta el valor decimal del nú-mero π?

1.1. El coste de los algoritmos:En informática (y matemáticas) uno de los mayores problemas

que nos encontramos es el de medir la eficiencia de un algoritmo.Surge entonces la necesidad de estudiar qué recursos (en tiempo decálculo y cantidad de memoria) se necesitan para conocer de ante-mano unos indicadores que, de alguna manera, nos permitan saber siel algoritmo encontrado es viable o no.

Veamos esto con un ejemplo:

1.1.1. El problema del viajante

Supongamos que tenemos una empresa de panadería que tiene 20puntos de venta repartidos por la ciudad. Todas las mañanas, el furgón de reparto tiene quesalir desde la panificadora y dejar en cada punto el pan y pasteles necesarios. El chófer de lafurgoneta se plantea entonces el siguiente problema:

Página 2 Luis Cabello & Paco Villegas

Page 9: ESTALMAT -Andalucía Oriental Actividades 07/08thales.cica.es/geogebra/sites/thales.cica.es.estalmat.oriental/files/s... · Actividad 1: Procedimientos. Proyecto “Visor de Imágenes”

Introducción: algoritmos Estalmat-Andalucía 07/08

¿Cuál el el camino más corto para pasar por todos lospuntos de venta?

Como es aficionado a las mates, piensa que esto es fácil:Sólo tengo que saber qué caminos hay disponibles, ob-

tengo su suma de distancias y me quedo con las más corta,así que manos a la obra. Lo primero es saber cuántos cami-nos diferentes tengo:

Veamos, si hay un sólo punto de reparto: el viaje de iday vuelta, no hay problema

Si son dos: casi que da igual, son dos caminos diferentes,pero en realidad es uno solo, le da igual

Si son tres: tenemos 6 rutas (notar que el punto de partida no influye), pero se repiten dos ados (podemos optar por hacer la ruta P123P o P321P, aunque son rutas diferentes a efectos decómputo suponen el mismo tiempo. Es decir 3!

2 = 3¿Con cuatro?: número de rutas 4!, pero caminos “diferentes” 4!

2Esto va bien, nuestro chófer concluye, para 20 punto de venta será (abre su wxMaxima y

obtiene):

20!2

=2432902008176640000

2= 1216451004088320000

Conoce las distancias entre los puntos de venta y el tiempo que tarda en cada uno, así quesólo tiene que hacer esas “pocas de multiplicaciones y sumas” y listo, se queda con la máscorta. Como además es aficionado a la informática, sabe que cada una de esas operaciones, enun ordenador actual, puede tardar 100 microsegundos (hay que hacer 20 multiplicaciones y unasuma), así que el tiempo que tardará su ordenador será de:

1216451004088320000 ·100 ·10−6s60 ·60 ·24 ·365

anos = 3857340,829808219anos

¿Cómo? ¡más de 3 millones de años!, esto es fácil cambiará de ordenador y listo, pero claro,la mejora de capacidad de cálculo en un equipo de último modelo es de 1000 veces el que él

Página 3 Luis Cabello & Paco Villegas

Page 10: ESTALMAT -Andalucía Oriental Actividades 07/08thales.cica.es/geogebra/sites/thales.cica.es.estalmat.oriental/files/s... · Actividad 1: Procedimientos. Proyecto “Visor de Imágenes”

Introducción: algoritmos Estalmat-Andalucía 07/08

tiene, así que sólo consigue saber que podrá resolver el problema (qué seguro es computable yaque sólo hay que hacer un número finito de cuentas) en poco más de 3000 años.

Para pensar después:

Si le aumentan el número de puntos de venta en tres más, ¿cuánto tiempo tardará el nuevoordenador que se ha comprado? ¿Crees que la solución es cambiar de ordenador pararesolver este tipo de problemas?

Está claro que la forma de resolver el problema no es la adecuada, hay que buscar un algoritmoque permita resolver el problema en un tiempo real.

A partir de problemas como este, surge la necesidad de intentar clasificar los problemas des-de una perspectiva del tiempo de cómputo, y surge lo que se llama el análisis de la complejidadde los algoritmos. En informática se usa la notación O (grande) para intentar clasificar el costeteórico en tiempo de un algoritmo, algunas clases de complejidad, ordenadas de menor a mayorcoste son:

O(1), O(logn), O(n), O(n logn), O(n2), O(n3), O(2n), O(n!), O(nn)

En general, los algoritmos de búsqueda son de orden O(n) (si buscamos una persona en unlistado no ordenado de n personas, lo más “malo” que nos puede pasar es que esté la última).Los algoritmos estándar de ordenación, en general están en O(n2), los “buenos” en O(n logn).

Ejemplo: con un algoritmo de tipo cuadrático, el tiempo empleado en ordenar un vector de100,000 números enteros es unas 6,000 veces más lento que un algoritmo de los “buenos”.Es decir, el “bueno” tarda un minuto, el cuadrático tardaría ¡10 minutos!

Para pensar después: busca en Internet algún algoritmo de ordenación de los costesanteriores

Los algoritmos cuyo coste sea como máximo del tipo O(nk)k ∈ Z se denominan polinomialesy son computables en un tiempo “razonable” (son tratables1). En la tabla que sigue hemoscalculado de forma aproximada (en horas) el tiempo que tardaría cada uno de ellos si suponemosque el coste de una instrucción elemental en tiempo es un nanosegundo (10−9s)

Clase n = 10 n = 100 n = 200 n = 500n 2,7 ·10−12 2,7 ·10−11 5,5 ·10−11 1,38 ·10−10

n logn 2,7 ·10−12 5,5 ·10−11 1,28 ·10−10 3,8 ·10−10

n2 2,7 ·10−11 2,7 ·10−9 1,1 ·10−8 6,94 ·10−8

n3 2,7 ·10−10 2,7 ·10−7 2,2 ·10−6 3,47 ·10−5

2n 2,84 ·10−10 3,52 ·10+17 4,46 ·1047 9,02 ·10137

n! 1,008 ·10−6 2,59 ·10145 2,18 ·10362 3,38 ·101129

nn 2,7 ·10−1 2,7 ·10187 4,46 ·10447 8,48 ·101345

Está claro por qué a los algoritmos de coste mayor a los polinomiales se les llama intratables¿a qué sí?

Moraleja: no basta con encontrar el algoritmo que permita resolver un problema informático,además tiene que ser un buen algoritmo.

1En caso de coste mayor, se denominan intratables

Página 4 Luis Cabello & Paco Villegas

Page 11: ESTALMAT -Andalucía Oriental Actividades 07/08thales.cica.es/geogebra/sites/thales.cica.es.estalmat.oriental/files/s... · Actividad 1: Procedimientos. Proyecto “Visor de Imágenes”

Funciones recursivas Estalmat-Andalucía 07/08

2. Funciones recursivasYa sabemos que ante un problema, no sólo hay que encontrar la forma de resolverlo, además

hay que buscar un algoritmo que lo haga antes de que desesperemos (o algo peor). Cuandopara resolver un problema, tenemos que repetir una serie de cálculos (muy parecidos) variasveces, los mecanismos que nos permiten los lenguajes de programación son la recursividad yla iteración (ya la habéis visto). La recursividad sólo es posible si un procedimiento o funciónpueden hacer referencia a sí mismos dentro de su propia definición:

Siendo un poco más precisos, y para evitar el aparente círculo sin fin en esta definición, lasinstancias complejas de un proceso se definen en términos de instancias más simples, estandolas finales más simples definidas de forma explícita. [5]

Un ejemplo clásico (otro pueden ser los propios número naturales) para explicar en quéconsiste una función recursiva, es el de la la función potencia de base entera y exponente natural,por ejemplo:

74 = 71 ·73

¿qué significa esto? que, el problema de calcular una potencia de exponente 4 lo podemosreducir a calcular una de exponente 3, pero ¿cómo puedo calcular la de exponente 3, ¡pues!

73 = 71 ·72

Qué lío, pero ahora ¿cómo hago lo que me falta?,

72 = 71 ·71

Bien, pero el "ordenata" no es muy listo y ni siquiera sabe cuánto vale eso de 71, no nosqueda mas remedio que avisarle de que 70 = 1 (porque sí) y entonces, él sigue:

71 = 71 ·70 = 7 ·1 = 7

Ya está, deshaciendo el camino tenemos:

72 = 71 ·71 = 49

73 = 71 ·72 = 7 ·49 = 343

74 = 71 ·73 = 7 ·343 = 2401

Si formalizamos esto en lenguaje matemático tendríamos:

7n ={

1 si n = 07 ·7n−1 si n≥ 1

¿Cuál sería la formula “recursiva” de la función potencia para cualquier base?

xn ={

1 si n = 0x · xn−1 si n≥ 1

Página 5 Luis Cabello & Paco Villegas

Page 12: ESTALMAT -Andalucía Oriental Actividades 07/08thales.cica.es/geogebra/sites/thales.cica.es.estalmat.oriental/files/s... · Actividad 1: Procedimientos. Proyecto “Visor de Imágenes”

Ejemplos Estalmat-Andalucía 07/08

Y usando la nomenclatura matemática para las funciones (con dos letras2, ¡qué fuerte!):

f (x,n) ={

1 si n = 0x · f (x,n−1) si n≥ 1

En Visual Basic, podría ser:

Function Potencia(ByVal x As Integer, ByVal n As Integer) As Long

If n = 0 Then

Return 1 ' Si ya hemos llegado a exponente cero, devuelve 1

Else

Return x*Potencia(x,n-1)

End If

End Function

Otro ejemplo que ya hemos visto es el de la criba de Eratóstenes (275-195 a.C.): algoritmo paralistar todos todos los números primos comprendidos entre el número 2 y un numero n

1. Escribir todos los números naturales comprendidos entre 2 y n

2. El primer número no tachado de la lista, y no contabilizado todavía es primo. Tachar todossus múltiplos. Si no queda ningún múltiplo, terminar.

3. Volver al paso 2

Pero, como ya se ha visto, sigamos nosotros con otros ejemplos.

3. Ejemplos

3.1. Factorial de un númeroRecordemos que la función factorial se escribe en lenguaje matemático como sigue

n! ={

1 si n = 0n · (n−1)! si n≥ 1

Así, para calcular 4! lo haremos así:

4! = 4 ·3!

3! = 3 ·2!

2! = 2 ·1!

1! = 1 ·0!2de dos variables

Página 6 Luis Cabello & Paco Villegas

Page 13: ESTALMAT -Andalucía Oriental Actividades 07/08thales.cica.es/geogebra/sites/thales.cica.es.estalmat.oriental/files/s... · Actividad 1: Procedimientos. Proyecto “Visor de Imágenes”

Ejemplos Estalmat-Andalucía 07/08

0! = 1

Y escrita en forma de función sería

f (x) ={

1 si n = 0x · f (x−1) si n≥ 1

Por fin, ya sabemos que 4! = 4 ·3 ·2 ·1 ·1 = 12. ¿por qué complicar esto tanto? pues porqueasí lo hacen los ordenadores. Y para que puedan hacerlo nosotros hemos de “programar” bienel algoritmo.

¿Serías capaz de programarlo? ¡seguro que sí!. Para facilitarte el trabajo te damos algunaspistas.

Function Factorial(ByVal N As Integer) As Long

If N = 0 Then ' El factorial de 0 es 1

Return 1 ' No hacer más llamadas

ElseIf N > 0 Then

Return N * Factorial(N-1) ' Llamadas con N-1

End If

End Function

Cuando tengas el programa calcula

10! =

20! =

25! =

3.2. Sucesión de Fibonacci

La sucesión de FIBONACCI es la sucesión infinita de números naturales

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, . . .

donde el primer elemento es 0, el segundo es 1 y cada elemento restante es la suma de losdos anteriores. A cada elemento de esta sucesión se le llama número de Fibonacci. Se debea Leonardo de Pisa, matemático italiano del siglo XIII también conocido como Fibonacci. Laideó como la solución a un problema de la cría de conejos:

Cierto hombre tenía una pareja de conejos juntos en un lugar cerrado y uno desea sabercuántos son creados a partir de este par en un año cuando es su naturaleza parir otro par enun simple mes, y en el segundo mes los nacidos parir también. [3]

Página 7 Luis Cabello & Paco Villegas

Page 14: ESTALMAT -Andalucía Oriental Actividades 07/08thales.cica.es/geogebra/sites/thales.cica.es.estalmat.oriental/files/s... · Actividad 1: Procedimientos. Proyecto “Visor de Imágenes”

Ejemplos Estalmat-Andalucía 07/08

¿Cómo se construye?Se tienen que conocer los dos primeros valores, en este caso:

f1 = 0

f2 = 1

y a partir de ellos obtenemos los demás teniendo en cuenta que el siguiente término es lasuma de los dos anteriores, es decir:

f3 = f1 + f2 = 0+1 = 1

f4 = f2 + f3 = 1+1 = 2

. . .

fn = fn−2 + fn−1

En notación “más” funcional:

f (x) =

0 si x = 11 si x = 2f (x−2)+ f (x−1) si x≥ 3

Ahora te toca, ¿puedes hacer un programa que calcule f (15)?.

NOTA: Con este algoritmo para calcular términos para la sucesión de Fibonnaci, el númerode sumas (y memoria) que utiliza el ordenador es muy elevado (está en el orden O(Φn),donde Φ = 1+

√5

2 es el número de oro) es decir, es muy lento. Por ejemplo, para calcularf50 este algoritmo requiere efectuar 20365011073 sumas. [3]

En este caso, los algoritmos usados son iterativos o una modificación del algoritmo recur-sivo (más complejo), versión Divide y Vencerás (Complejidad O(log n))

Página 8 Luis Cabello & Paco Villegas

Page 15: ESTALMAT -Andalucía Oriental Actividades 07/08thales.cica.es/geogebra/sites/thales.cica.es.estalmat.oriental/files/s... · Actividad 1: Procedimientos. Proyecto “Visor de Imágenes”

Ejemplos Estalmat-Andalucía 07/08

Podemos modificar los dos primeros valores y obtenemos “otras” sucesiones de Fibonacci (Su-cesiones de Fibonnaci Generalizadas). Por ejemplo, si los dos primeros valores son:

f1 = 2f2 = 2¿Cuanto vale f4?

Práctica: haz un programa que permita obtener un término cualquiera de una Sucesión deFibonnaci Generalizada. El programa te tendrá que pedir tres valores.

Para la sucesión anterior halla f10

3.3. Torres de HanoiLas Torres de Hanoi es un rompecabezas o juego matemático inventado en 1883 por el

matemático francés Éduard Lucas d’Amiens3 . Consiste en tres varillas verticales y una serie dediscos de diferente tamaño, la dificultad a la hora de resolver el juego dependerá del número dediscos con el que juguemos.

No hay dos discos iguales e inicialmente están colocados de mayor a menor en la primeravarilla. El juego consiste en pasar todos los discos a la tercera varilla manteniendo la figuraoriginal. Las reglas para conseguirlo son:

Sólo se puede mover un disco cada vez

Un disco de mayor tamaño no puede descansar sobre uno más pequeño que él.

Sólo se puede mover en cada jugada el disco que se encuentra arriba de alguna de las tresvarillas.

3.3.1. Un poco de historia:

Una leyenda4 cuenta que Dios, después de crear el mundo, puso en la tierra tres barrashechas de diamantes, y 64 anillos de oro en la primera. Estos anillos son todos de diferentetamaño y al colocarlos se cuidó de ordenarlos por tamaño, estando el mayor en la parte inferior

3Lo publicó con el seudónimo de Profesor N. Claus de Siam, mandarín del colegio Li-Sou-Stian (trabajaba enel instituto de Sant Luis). Curioso el juego de letras del profe ¿verdad?

4Esta leyenda fue un invento publicitario del creador del juego. [3]

Página 9 Luis Cabello & Paco Villegas

Page 16: ESTALMAT -Andalucía Oriental Actividades 07/08thales.cica.es/geogebra/sites/thales.cica.es.estalmat.oriental/files/s... · Actividad 1: Procedimientos. Proyecto “Visor de Imágenes”

Ejemplos Estalmat-Andalucía 07/08

y el menor en la parte superior. También creó un monasterio junto a las barras. A los monjesdel monasterio encargó un trabajo: se trataba de que tenían que trasladar todos lo anillos a lasegunda barra, pero con la condición de que la única operación permitida es trasladar un sóloanillo de una barra a la otra de manera que nunca puede situar un anillo sobre otro de menorradio. El trato es que el día que estos monjes consigan terminar el juego, el mundo acabará.

Si la leyenda fuera cierta, ¿cuándo será el fin del mundo?, veamos:

Supongamos que los monjes mueven un anillo por segundo, de día y de noche y sin equi-vocarse, en ese caso tienen que realizar al menos 264− 1 movimientos (¿por qué?), es decir,584.942.417.355,07202 años (poco menos de 585 mil millones de años, más de 25 veces laedad estimada del universo y unas 100 veces la edad de la tierra).

3.3.2. Resolución

Para resolver el problema analicemos un poco qué pasa con:

Un anillo: no hay problema, un sólo movimiento. Es el caso “trivial” (el n=0). Movimien-tos 1 = 2−1

Página 10 Luis Cabello & Paco Villegas

Page 17: ESTALMAT -Andalucía Oriental Actividades 07/08thales.cica.es/geogebra/sites/thales.cica.es.estalmat.oriental/files/s... · Actividad 1: Procedimientos. Proyecto “Visor de Imágenes”

Ejemplos Estalmat-Andalucía 07/08

Con dos: en este caso, ponemos el disco pequeño en el centro y el problema se reduce amover el disco más grande. Movimientos=3 = 2 ·1+1

Con tres: se tata de que primero conseguimos el paso dos (mover dos discos tal cual hemoshecho antes, pero cuidando la posición de las varillas). Movimientos5 7 = 2 ∗ 3 + 1 =23−1

El truco a la hora de resolverlo reside en fijarnos en el disco más pequeño. El primermovimiento de ese disco se realiza hacia la varilla auxiliar (C). El disco número dos, se

5Se demuestra por inducción que si llamamos Mn al número de movimientos para una Torre de Hanoi de ndiscos, entonces:

Mn = 2 ·Mn−1 +1

A partir de ella, se obtiene que Mn = 2n−1

Página 11 Luis Cabello & Paco Villegas

Page 18: ESTALMAT -Andalucía Oriental Actividades 07/08thales.cica.es/geogebra/sites/thales.cica.es.estalmat.oriental/files/s... · Actividad 1: Procedimientos. Proyecto “Visor de Imágenes”

Ejemplos Estalmat-Andalucía 07/08

mueve a la varilla B. Después el disco pequeño se mueve a la varilla B para que quedesobre el disco dos. Es el momento de situar el disco grande, que está aún en la varilla A,en la varilla C. Ya casi, ahora el disco más pequeño regresa de la varilla A, el mediano secoloca ya en su sitio definitivo (varilla C) y finalmente ponemos el disco pequeño en sulugar.

Fijémosnos en que para cuatro discos (o n), de lo que se trata es de que siempre tenemos quellegar a una situación en la que en se queda sólo el disco grande (en la varilla A) y en lavarilla de en medio (B) tenemos una torre de Hanoi de 3 (en general (n− 1)) discos. Es decir,¡recursividad!.

Si numeramos los discos desde 1 hasta n, y llamamos A a la primera varilla, C a la tercera(destino) y B a la intermedia (auxiliar) el algoritmo de la función sería el siguiente:

1. Si n = 1, lleva el disco de la barra A a la C y termina

2. Mueve la torre de (n−1) fichas de la barra Aa la B

3. Lleva el disco grande (que se ha quedado solo en la varilla origen (A)) a la varilla destino(C)

4. Traslada la torre de (n− 1) discos, usando este mismo algoritmo, de (B) a (C), perousando ahora como varilla auxiliar la (A)

En forma de “función”fun Hanoi(origen, destino, auxiliar, n)

si n = 1entonces escribe �Mueve disco de poste origen a poste destino�

si no hacer

Hanoi(origen,auxiliar, destino, n−1)Hanoi(origen,destino, axiliar, 1)Hanoi(auxiliar,destino, origen, n−1)

fsi

ffun

Para pensar después:

1. A partir de la función anterior, ¿podemos calcular ya en nuestro ordenador Ha-noi(64, A, B)?

Página 12 Luis Cabello & Paco Villegas

Page 19: ESTALMAT -Andalucía Oriental Actividades 07/08thales.cica.es/geogebra/sites/thales.cica.es.estalmat.oriental/files/s... · Actividad 1: Procedimientos. Proyecto “Visor de Imágenes”

REFERENCIAS Estalmat-Andalucía 07/08

2. Más cuestiones matemáticas de interés: revisa la Webhttp://descartes.cnice.mecd.es/materiales_didacticos/rompecabezas/

TorresHanoi.htm

y te proponemos que realices las actividades que te propone el autor.

Referencias[1] Peña Marí, R. (2006), De Euclides a Java. Historia de los algoritmos y de los lenguajes de

programación, Madrid, Nivola libros y ediciones, S.L.

[2] Garfunkel, S. y más (1999), Las matemáticas en la vida cotidiana, Madrid, Addison-WesleyIberoamericana españa, S.A.

[3] Wikipedia, http://es.wikipedia.org/wiki/Portada

[4] Brassard, G. y Bratley, P. (1997), Fundamentos de Algoritmia, Madrid, Prentice Hall.

[5] Charte, Francisco (2002), Programación con Visual Basic .NET, Madrid, Anaya Multime-dia.

[6] Gonzalo Arroyo, J. y Rodríguez Artacho, M. (1997), Esquemas algorítmicos: enfoque me-todológico y problemas resueltos, Madrid, UNED.

Página 13 Luis Cabello & Paco Villegas

Page 20: ESTALMAT -Andalucía Oriental Actividades 07/08thales.cica.es/geogebra/sites/thales.cica.es.estalmat.oriental/files/s... · Actividad 1: Procedimientos. Proyecto “Visor de Imágenes”

ESTALMAT -Andalucía Oriental Actividades 07/08

Sesión: 20 Fecha: 26-04-2008 Título: Programación Matemática. Aplicaciones _____________________________________________________________________________

Programación matemática. Aplicaciones

RecursividadSOLUCIONES

Índice de contenidoPotencia de base entera y exponente natural....................................................................................1Factorial de un número.....................................................................................................................5Sucesión de Fibonnacci....................................................................................................................8Torres de Hanoi...............................................................................................................................13

1. POTENCIA DE BASE ENTERA Y EXPONENTE NATURAL

Para crear una aplicación que calcule el factorial de un número crearemos un nuevo proyecto del tipo Aplicación para Windows al que podríamos llamar CalculoPotencias.

Una vez creado el proyecto lo guardaremos con el mismo nombre.

En el formulario que se crea añadiremos varios componentes a través de los cuales el usuario podrá interactuar con la aplicación.

En primer lugar añadiremos desde el cuadro de herramientas dos campos de texto (TextBox) donde se introducirán la base y el exponente. Les daremos un nombre representativo a los dos controles que hemos creado modificando la propiedad Name. Al primer campo de texto le llamaremos cajaTextoBase y al segundo cajaTextoExponente.

Página 1 Luis Cabello y Paco Villegas

Page 21: ESTALMAT -Andalucía Oriental Actividades 07/08thales.cica.es/geogebra/sites/thales.cica.es.estalmat.oriental/files/s... · Actividad 1: Procedimientos. Proyecto “Visor de Imágenes”

ESTALMAT -Andalucía Oriental Actividades 07/08

Sesión: 20 Fecha: 26-04-2008 Título: Programación Matemática. Aplicaciones _____________________________________________________________________________ También añadiremos dos etiquetas (Label) asociadas a cada uno de los campos de texto. Modificaremos la propiedad Text de cada una de ellas y, al igual que hacíamos con los campos de texto, les cambiaremos también el nombre modificando la propiedad Name.

Etiqueta 1:● Name: etiquetaBase● Text : Base

Etiqueta 2:● Name: etiquetaExponente● Text : Exponente

Añadiremos el botón responsable de llamar a la función encargada de realizar el cálculo y, por último, una nueva etiqueta en la que se escribirá el valor de la potencia. A estos dos últimos controles les modificaremos las siguientes propiedades:

Botón:● Name: botonCalcular● Text: Calcular

Etiqueta:● Name: etiquetaPotencia.● Text: POTENCIA

Para terminar cambiaremos la propiedad Text del formulario por Cálculo de potencias.

Una vez creado el formulario tendremos que decirle a nuestra aplicación que responda al hacer clik sobre el botón calculando la potencia y escribiéndola en la etiqueta correspondiente. Para ello haremos doble click sobre el botón, generándose de forma automática el siguiente método:

Private Sub botonCalcular_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles botonCalcular.Click

End Sub

Dentro del método escribiremos:

Private Sub botonCalcular_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles botonCalcular.Click

'definimos las variables que vamos a utilizar Dim base, exponente As Integer 'Enteros de 32 bits [-2^32, (2^32)-1] Dim potencia As Long 'Enteros de 64 bits [-2^64, (2^64)-1]

'obtenemos los números introducidos en las cajas de texto base = CInt(Me.cajaTextoBase.Text) exponente = CInt(Me.cajaTextoExponente.Text)

'calculamos la potencia

Página 2 Luis Cabello y Paco Villegas

Page 22: ESTALMAT -Andalucía Oriental Actividades 07/08thales.cica.es/geogebra/sites/thales.cica.es.estalmat.oriental/files/s... · Actividad 1: Procedimientos. Proyecto “Visor de Imágenes”

ESTALMAT -Andalucía Oriental Actividades 07/08

Sesión: 20 Fecha: 26-04-2008 Título: Programación Matemática. Aplicaciones _____________________________________________________________________________

potencia = obtenerPotencia(base, exponente)'escribimos la potencia en la etiqueta correspondienteMe.etiquetaPotencia.Text = Me.cajaTextoBase.Text + " ^ " +

Me.cajaTextoExponente.Text + " = " + potencia.ToString()

End Sub

Pero todavía nos falta lo más importante, nuestra aplicación aún no sabe cómo obtener la potencia de un número. Para ello deberemos crear una función (obtenerPotencia) a la que le pasaremos como parámetros la base y el exponente y nos devolverá como resultado la potencia.

Una función no es más que una secuencia de instrucciones que realizan una determinada tarea y que al terminar ésta devuelven un valor o resultado. Las funciones se pueden llamar desde otras partes de la aplicación. A las funciones se les pueden pasar parámetros que podrán ser utilizados dentro de la función para conseguir la tarea.

Hemos visto anteriormente que al pulsar sobre el botón botonCalcular se ejecuta el procedimiento botonCalcular_Click. La diferencia entre una función y un procedimiento es que los procedimientos no devuelven ningún valor. La forma de declarar una función es muy parecida a la de los procedimientos, basta con sustituir Sub por Function e indicarle el tipo del valor que va a devolver. De esta forma podríamos crear nuestra función obtenerPotencia:

Function obtenerPotencia(ByVal base As Integer, ByVal exponente As Integer) As Long

If exponente = 0 ThenReturn 1

ElseReturn base * obtenerPotencia(base, exponente - 1)

End If

End Function

A nuestra función le pasamos dos parámetros de tipo entero (Integer): la base y el exponente de la potencia, y le indicamos, al final de la definición, el tipo del resultado que devuelve (Long). Para devolver el resultado se utiliza la palabra reservada Return. Cuando se llega a alguna línea en la que se encuentra esta palabra la función finaliza, devolviendo el valor que aparece tras Return.

Ahora vamos a analizar el código encargado de calcular la potencia:

If exponente = 0 ThenReturn 1

ElseReturn base * obtenerPotencia(base, exponente - 1)

End If

Si lo observamos un poco veremos que es bastante similar al algoritmo que hemos visto anteriormente para el cálculo de potencias:

● Si el exponente es 0 la función devuelve como resultado 1.● Si el expontente es distinto de 0 devuelve:

Página 3 Luis Cabello y Paco Villegas

Page 23: ESTALMAT -Andalucía Oriental Actividades 07/08thales.cica.es/geogebra/sites/thales.cica.es.estalmat.oriental/files/s... · Actividad 1: Procedimientos. Proyecto “Visor de Imágenes”

ESTALMAT -Andalucía Oriental Actividades 07/08

Sesión: 20 Fecha: 26-04-2008 Título: Programación Matemática. Aplicaciones _____________________________________________________________________________

base * obtenerPotencia(base, exponente – 1 (base * (base ^ (exponente – 1)))

Veamos un ejemplo concreto analizando cómo actúa esta función. Si como base introducimos 2 y como exponente 3 (2 ^ 3) tendríamos:

potencia = obtenerPotencia(2, 3)

obtenerPotencia(2, 3) = 2 * obtenerPotencia (2, 2)

obtenerPotencia(2, 2) = 2 * obtenerPotencia (2, 1)

obtenerPotencia(2, 1) = 2 * obtenerPotencia (2, 0)

obtenerPotencia(2, 0) = 1

Al llegar a exponente 0 finaliza el proceso y se van sustituyendo las sucesivas funciones por su valor hasta obtener el resultado buscado:obtenerPotencia(2, 0) = 1

obtenerPotencia(2, 1) = 2 * 1 = 2

obtenerPotencia(2, 2) = 2 * 2 = 4

obtenerPotencia(2, 3) = 2 * 4 = 8

potencia = 8

2. FACTORIAL DE UN NÚMERO

Para crear la aplicación encargada de calcular el factorial de un número seguiremos los mismos pasos que en el ejemplo anterior:

● Crearemos un proyecto basado en una aplicación para Windows llamado CalculoFactorial● Guardaremos el proyecto con el mismo nombre● Añadiremos al formulario los siguientes controles:

○ Caja de texto■ Name: cajaTextoNumero

○ Etiqueta■ Name: etiquetaNumero■ Text: Introducir el número

○ Botón:■ Name: botonCalcular■ Text: Calcular

○ Etiqueta:■ Name: etiquetaFactorial■ Text: FACTORIAL

Página 4 Luis Cabello y Paco Villegas

Page 24: ESTALMAT -Andalucía Oriental Actividades 07/08thales.cica.es/geogebra/sites/thales.cica.es.estalmat.oriental/files/s... · Actividad 1: Procedimientos. Proyecto “Visor de Imágenes”

ESTALMAT -Andalucía Oriental Actividades 07/08

Sesión: 20 Fecha: 26-04-2008 Título: Programación Matemática. Aplicaciones _____________________________________________________________________________ Haremos doble click sobre el botón para que se cree el método que capturará el evento generado al hacer click sobre dicho botón, y escribiremos el siguiente código:

Private Sub botonCalcular_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles botonCalcular.Click

'definimos las variables que vamos a utilizarDim numero As Integer 'Enteros de 32 bits [-2^32, (2^32)-1]Dim factorial As Long 'Enteros de 64 bits [-2^64, (2^64)-1]

'obtenemos el número entero introducido en la caja de textonumero = CInt(Me.cajaTextoNumero.Text)

'calculamos el factorialfactorial = obtenerFactorial(numero)'escribimos el factorial en la etiqueta correspondienteMe.etiquetaFactorial.Text = "El factorial de " +

Me.cajaTextoNumero.Text + " es " + factorial.ToString()

End Sub

Si observáis el código es bastante similar al que habíamos escrito para calcular las potencias. En este caso utilizamos una nueva función (obtenerFactorial), a la que pasamos como parámetro el numero del que queremos obtener el factorial.

También podemos observar cómo el tipo de las variables que definimos son los mismos. El número lo definimos como un entero de 32 bits (Integer) y el factorial como un entero de 64 bits (Long).

La función sería la siguiente:

Function obtenerFactorial(ByVal numero As Integer) As Long

If numero = 0 ThenReturn 1 'El factorial de 0 es 1

ElseIf numero > 0 ThenReturn numero * obtenerFactorial(numero - 1)

End If

End Function

A pesar de que la función devuelve un entero de tipo Long, la aplicación no permite calcular el factorial de números mayores de 20. Esto es debido a que una variable de tipo Long permite valores comprendidos entre -9223372036854775808 y 9223372036854775807, y el factorial de 21 es mayor que esta cifra.

Si observamos el código de nuevo veremos que es similar al algoritmo matemático utilizado para el cálculo del factorial.

● Si el número vale 0 devuelve (Return) 1● Si el número es mayor de 0 la función devuelve (Return)

numero * obtenerFactorial(numero – 1)

Página 5 Luis Cabello y Paco Villegas

Page 25: ESTALMAT -Andalucía Oriental Actividades 07/08thales.cica.es/geogebra/sites/thales.cica.es.estalmat.oriental/files/s... · Actividad 1: Procedimientos. Proyecto “Visor de Imágenes”

ESTALMAT -Andalucía Oriental Actividades 07/08

Sesión: 20 Fecha: 26-04-2008 Título: Programación Matemática. Aplicaciones _____________________________________________________________________________

Veamos un ejemplo concreto sobre cómo actúa la función calculando el factorial de 4:

factorial = obtenerFactorial(4)

obtenerFactorial(4) = 4 * obtenerFactorial(3)

obtenerfactorial(3) = 3 * obtenerFactorial(2)

obtenerFactorial(2) = 2 * obtenerFactorial(1)

obtenerFactorial(1) = 1 * obtenerFactorial(0)

obtenerFactorial(0) = 1 Finaliza el proceso

Al llegar el número a 0 finaliza el proceso y se van sustituyendo las sucesivas funciones por su valor hasta obtener el resultado buscado:

obtenerFactorial(0) = 1

obtenerFactorial(1) = 1 * 1 = 1

obtenerFactorial(2) = 2 * 1 = 2

obtenerFactorial(3) = 3 * 2 = 6

obtenerFactorial(4) = 4 * 6 = 24

Estamos suponiendo que los número introducidos para calcular el factorial son siempre enteros positivos, ya que en caso contrario los resultados no serían correctos. Por ejemplo, si introducimos números negativos, la función da como resultado 0. Está claro que este resultado no es correcto. Para evitar este tipo de errores habría que comprobar antes de llamar a la función que el texto introducido es un entero positivo. Os dejamos este trabajo como mejora de la aplicación.

3. SUCESIÓN DE FIBONACCI

De forma similar a los ejemplos anteriores crearemos un nuevo proyecto llamado SucesionFibonacci, añadiendo al formulario los siguientes controles:

● Caja de textoName: cajaTextoElemento

● EtiquetaName: etiquetaElementoText: Elemento nº

● Botón:Name: botonCalcularText: Calcular

Página 6 Luis Cabello y Paco Villegas

Page 26: ESTALMAT -Andalucía Oriental Actividades 07/08thales.cica.es/geogebra/sites/thales.cica.es.estalmat.oriental/files/s... · Actividad 1: Procedimientos. Proyecto “Visor de Imágenes”

ESTALMAT -Andalucía Oriental Actividades 07/08

Sesión: 20 Fecha: 26-04-2008 Título: Programación Matemática. Aplicaciones _____________________________________________________________________________

● Etiqueta:Name: etiquetaFibonacciText: FIBONACCI

De forma similar a cómo hicimos en los ejemplos anteriores, en el método que se genera al hacer doble click en el botón Calcular escribiremos:

Private Sub botonCalcular_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles botonCalcular.Click

'definimos las variables que vamos a utilizarDim elemento As Integer 'Enteros de 32 bits [-2^32, (2^32)-1]Dim fibonacci As Long 'Enteros de 64 bits [-2^64, (2^64)-1]

'obtenemos el número entero introducido en la caja de textoelemento = CInt(Me.cajaTextoElemento.Text)

'calculamos el valor del elemento en la sucesión de Fibonaccifibonacci = obtenerFibonacci(elemento)'escribimos el valor en la etiqueta correspondienteMe.etiquetaFibonacci.Text = "El valor del elemento " +

Me.cajaTextoElemento.Text + " de la sucesión de Fibonacci es " + fibonacci.ToString()

End Sub

En este método para obtener el valor del elemento llamamos a la función obtenerFibonacci pasándole como argumento el elemento. El código de esta función podría ser el siguiente:

Function obtenerFibonacci(ByVal elemento As Integer) As LongIf elemento = 1 Then

Return 0 'El primer elemento de la sucesión vale 0ElseIf elemento = 2 Then

Return 1 'El segundo elemento de la sucesión vale 1ElseIf elemento > 2 Then'A partir del tercer elemento el valor es la suma de los dos anteriores

Return obtenerFibonacci(elemento - 1) + obtenerFibonacci(elemento - 2)

End If End Function

De nuevo partimos de la base de que el texto introducido en la caja de texto es un valor válido (entero positivo). Al igual que los otros ejemplos os dejamos como ejercicio mejorar la aplicación para que realice las comprobaciones necesarias, y prevenir de esta forma los posibles errores que se producirán si se introducen valores no válidos.

Veamos un ejemplo concreto sobre cómo actúa la función calculando el valor del elemento 5:

fibonacci = obtenerFibonacci(5)

Página 7 Luis Cabello y Paco Villegas

Page 27: ESTALMAT -Andalucía Oriental Actividades 07/08thales.cica.es/geogebra/sites/thales.cica.es.estalmat.oriental/files/s... · Actividad 1: Procedimientos. Proyecto “Visor de Imágenes”

ESTALMAT -Andalucía Oriental Actividades 07/08

Sesión: 20 Fecha: 26-04-2008 Título: Programación Matemática. Aplicaciones _____________________________________________________________________________

obtenerFibonacci(5) = obtenerFibonacci(4) + obtenerFibonacci(3)

obtenerFibonacci(4) = obtenerFibonacci(3) + obtenerFibonacci(2)obtenerFibonacci(3) = obtenerFibonacci(2) + obtenerFibonacci(1)

obtenerFibonacci(2) = 1obtenerFibonacci(1) = 0

obtenerFibonacci(2) = 1

obtenerFibonacci(3) = obtenerFibonacci(2) + obtenerFibonacci(1)obtenerFibonacci(2) = 1obtenerFibonacci(1) = 0

A pesar de que hemos seleccionado un elemento de los primeros, podéis observar como las funciones se repiten, esto hace que el número de sumas se vaya incrementando a medida que avanzamos en la sucesión.

Solución iterativa: para hacer después de la sesiónAl igual que ocurre con la mayoría de los problemas matemáticos, no existe una única forma de solucionarlos. En este caso vamos a mostrar como se podría hacer de forma iterativa.

Agregamos al formulario un nuevo botón con las propiedades:

● Botón:Name: botonCalcularIterativoText: Calcular iterativo

Como siempre hacemos doble clik en este nuevo botón y escribimos:

Private Sub botonCalcularIterativo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles botonCalcularIterativo.Click

'definimos las variables que vamos a utilizarDim elemento As Integer 'Enteros de 32 bits [-2^32, (2^32)-1]Dim fibonacci As Long 'Enteros de 64 bits [-2^64, (2^64)-1]

'obtenemos el número entero introducido en la caja de textoelemento = CInt(Me.cajaTextoElemento.Text)

'calculamos el valor del elemento en la sucesión de Fibonaccifibonacci = obtenerFibonacciIterativo(elemento)

Página 8 Luis Cabello y Paco Villegas

Page 28: ESTALMAT -Andalucía Oriental Actividades 07/08thales.cica.es/geogebra/sites/thales.cica.es.estalmat.oriental/files/s... · Actividad 1: Procedimientos. Proyecto “Visor de Imágenes”

ESTALMAT -Andalucía Oriental Actividades 07/08

Sesión: 20 Fecha: 26-04-2008 Título: Programación Matemática. Aplicaciones _____________________________________________________________________________

'escribimos el valor en la etiqueta correspondienteMe.etiquetaFibonacci.Text = "ITERATVO: El valor del elemento " +

Me.cajaTextoElemento.Text + " de la sucesión de Fibonacci es " + fibonacci.ToString()

End Sub

Y creamos una nueva función llamada obtenerFibonacciIterativo:

Function obtenerFibonacciIterativo(ByVal elemento As Integer) As Long 'definimos las variables que vamos a utilizar Dim penultimo, ultimo, actual As Long Dim i As Integer

'iniciamos los valores de las variables de los dos valores iniciales penultimo = 0 ultimo = 1

If elemento = 1 Then Return 0 'El primer elemento de la sucesión vale 0 ElseIf elemento = 2 Then Return 1 'El segundo elemento de la sucesión vale 1 ElseIf elemento > 2 Then 'A partir del tercer elemento el valor es la suma de los dos

anteriores 'Calculamos el valor de cada elemento de forma iterativa hasta

llegar al elemento buscado ' For i = 3 To elemento Step 1 actual = ultimo + penultimo penultimo = ultimo ultimo = actual Next

Return actual End If

End Function

Intentad obtener el valor del elemento 40 con cada una de las funciones y observad el tiempo que tarda cada una de ellas.

Veamos cómo actúa este método para calcular el valor del elmento 5 de la sucesión de Fibonacci:

fibonacci = obtenerFibonacciIterativo(5)

penultimo = 0ultimo = 1

Desde el elemento 3 hasta el 5

elemento 3:

Página 9 Luis Cabello y Paco Villegas

Page 29: ESTALMAT -Andalucía Oriental Actividades 07/08thales.cica.es/geogebra/sites/thales.cica.es.estalmat.oriental/files/s... · Actividad 1: Procedimientos. Proyecto “Visor de Imágenes”

ESTALMAT -Andalucía Oriental Actividades 07/08

Sesión: 20 Fecha: 26-04-2008 Título: Programación Matemática. Aplicaciones _____________________________________________________________________________

actual = ultimo (1) + penultimo (0) = 1penultimo = 1ultimo = 1

elemento 4: actual = ultimo (1) + penultimo (1) = 2penultimo = 2ultimo = 1

elemento 5: actual = ultimo (2) + penultimo (1) = 3penultimo = 3ultimo = 2

Termina el bucle y la función devuelve (Return) el valor actual (3)

4. TORRES DE HANOI

Para este ejemplo crearemos un proyecto llamado TorresHanoi.

Añadiremos los controles necesarios para que el formulario quede como el de la imagen:

Los controles que hemos añadido al formulario tienen las siguientes propiedades:

Etiquetas:● Name: etiquetaAnillos● Text: Nº de anillos

● Name: etiquetaOrigen● Text: A = Origen

● Name: etiquetaAuxiliar● Text: B = Auxiliar

● Name: etiquetaDestino● Text: C = Destino

● Name: etiquetaHanoi● Text: MOVIMIENTOS TORRES DE HANOI

● Name: etiquetaMovimientos● Text: Nº total de movimientos

Cajas de texto:

Página 10 Luis Cabello y Paco Villegas

Page 30: ESTALMAT -Andalucía Oriental Actividades 07/08thales.cica.es/geogebra/sites/thales.cica.es.estalmat.oriental/files/s... · Actividad 1: Procedimientos. Proyecto “Visor de Imágenes”

ESTALMAT -Andalucía Oriental Actividades 07/08

Sesión: 20 Fecha: 26-04-2008 Título: Programación Matemática. Aplicaciones _____________________________________________________________________________

● Name: cajaTextoAnillos

● Name: cajaTextoMovimientos● Multiline: true● ScrollBars: Vertical

Botón:● Name: botonVerMoimientos● Texto: Ver movimientos

En la caja de texto donde irán apareciendo los movimientos de los anillos (cajaTextoMovimientos) hemos modificado las propiedades Multiline a true para que admita varias líneas, y la propiedad ScrollBars a Vertical para que muestre una barra de desplazamiento vertical en caso de que el número de líneas a mostrar sea mayor que el número de líneas que caben en la caja de texto.

También necesitamos hacer algo que no habíamos hecho en los ejemplos anteriores, y es declarar variables a nivel de la clase Form1, ya que las vamos a necesitar en varios de los métodos utilizados.

Si observáis el código de los ejemplos anteriores podéis observar que hemos declarado variables (mediante la palabra reservada Dim) dentro de los métodos, ya que estas variables sólo iban a ser utilizadas dentro de dichos métodos (funciones o procedimientos). Las variables declaradas dentro de un método sólo son visibles dentro de ese método.

Declaramos las siguientes variables:

Public Class Form1

Dim movimientos As LongDim origen, destino, auxiliar As String

.................................

.................................

End Class

En el método que se genera al hacer doble click sobre el botón Ver movimientos escribimos el siguiente código:

Private Sub botonVerMovimientos_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles botonVerMovimientos.Click

'definimos las variables que vamos a utilizarDim anillos As Integer 'Enteros de 32 bits [-2^32, (2^32)-1]

'obtenemos el número entero introducido en la caja de textoanillos = CInt(Me.cajaTextoAnillos.Text)

'reiniciamos el número de movimientos a 0, así como la letra asignada a cada barra

Página 11 Luis Cabello y Paco Villegas

Page 31: ESTALMAT -Andalucía Oriental Actividades 07/08thales.cica.es/geogebra/sites/thales.cica.es.estalmat.oriental/files/s... · Actividad 1: Procedimientos. Proyecto “Visor de Imágenes”

ESTALMAT -Andalucía Oriental Actividades 07/08

Sesión: 20 Fecha: 26-04-2008 Título: Programación Matemática. Aplicaciones _____________________________________________________________________________

'y borramos el texto de cajaTextoMovimientosmovimientos = 0origen = "A"auxiliar = "B"destino = "C"Me.cajaTextoMovimientos.Text = ""

'realizamos los movimientos para pasar los anillos del origen al destinomoverAnillos(origen, destino, auxiliar, anillos)'escribimos el valor en la etiqueta correspondienteMe.etiquetaMovimientos.Text = "Nº total de movimientos = " +

movimientos.ToString()

End Sub

Cada vez que pulsamos sobre el botón le damos los valores iniciales a las variables movimientos, origen, destino y auxiliar. También llamamos al procedimiento moverAnillos que tiene el siguiente código:

Sub moverAnillos(ByVal origen As String, ByVal destino As String, ByVal auxiliar As String, ByVal anillos As Integer)

If anillos = 1 Then movimientos = movimientos + 1 Me.cajaTextoMovimientos.Text = Me.cajaTextoMovimientos.Text +

movimientos.ToString + ".- Mover anillo de " + origen + " a " + destino + vbCrLf

Else'movemos los n-1 anillos de arriba del origen al auxiliarmoverAnillos(origen, auxiliar, destino, anillos - 1)'movemos el que queda sólo, del origen al destinomoverAnillos(origen, destino, auxiliar, 1)'volvemos a mover los n-1 anillos del auxiliar al destinomoverAnillos(auxiliar, destino, origen, anillos - 1)

End IfEnd Sub

Ya que en este ejemplo no necesitamos que el método devuelva ningún valor, creamos un procedimiento en lugar de una función. Para ello cambiamos la palabra Function que utilizábamos para crear las funciones por la palabra Sub.

Veamos cómo funciona este procedimiento:

Si el número de anillos a mover es 1:● se realizará el movimiento,

contabilizándose éste● se escribirá en la caja de texto una

nueva línea con el número del

Página 12 Luis Cabello y Paco Villegas

Page 32: ESTALMAT -Andalucía Oriental Actividades 07/08thales.cica.es/geogebra/sites/thales.cica.es.estalmat.oriental/files/s... · Actividad 1: Procedimientos. Proyecto “Visor de Imágenes”

ESTALMAT -Andalucía Oriental Actividades 07/08

Sesión: 20 Fecha: 26-04-2008 Título: Programación Matemática. Aplicaciones _____________________________________________________________________________

movimiento y los datos del origen y el destino. Para que cada movimiento se escriba en una nueva línea añadimos al final del texto vbCrLf, que equivale a un salto de línea.

Si el número de anillos a mover es mayor de 1:● movemos los n-1 anillos de arriba del origen al auxiliar, convirtiéndose el auxiliar en el

destino y el destino en el auxiliar.● movemos el que queda sólo del origen al destino, quedándose ya correctamente colocado● volvemos a mover los n-1 anillos del auxiliar al destino, convirtiéndose el auxiliar en el

origen, y el origen en el auxiliar

Página 13 Luis Cabello y Paco Villegas