UNIVERSIDAD TECNICA FEDERICO SANTA MARIA DEPARTAMENTO DE ELECTRONICA Programación en Pascal Capítulo 5. Programas basados en relaciones de recurrencia. 5. PROGRAMAS BASADOS EN RELACIONES DE RECURRENCIA. Existen numerosas situaciones que pueden representarse mediante relaciones de recurrencia; entre ellas mencionamos las secuencias y las series. Ambas son casos particulares de procesos iterativos , que consisten en la repetición de una acción con pequeñas variaciones cada vez. Una secuencia corresponde a un conjunto ordenado de valores, tales que un valor puede obtenerse a partir de los valores anteriores. La relación que permite obtener el valor actual en términos de los anteriores se denomina relación de recurrencia. Una serie es una expresión cuyo valor puede calcularse sumando los términos que la componen. Los términos de una serie son una secuencia. En general puede expresarse como una sumatoria. Lo característico de una secuencia es su término general, que permite obtener cada uno de los elementos de la secuencia. La observación del término general permite obtener la relación de recurrencia que genera la secuencia. Empleando notación matemática, podemos visualizar una secuencia como sigue: V0, V1, V2, .... Vi, .... Vn Es decir una secuencia de valores, a los cuales puede asociárseles un subíndice, el que establece una relación de orden. Una serie puede representarse por: j=i Si = ∑V j j=0 Es decir, la suma indexada de los términos. Nos interesa desarrollar programas en que una variable tome los valores de una secuencia; y también poder almacenar la suma de los términos de una serie en el espacio asignado a una variable. Prof. Leopoldo Silva Bijit. 07-07-2003 40 UNIVERSIDAD TECNICA FEDERICO SANTA MARIA DEPARTAMENTO DE ELECTRONICA Programación en Pascal Capítulo 5. Programas basados en relaciones de recurrencia. 5.1 Secuencias. Antes de desarrollar un esquema general de algoritmos que traten esta situación, veremos un ejemplo. 5.1.1 Ejemplo. Factoriales a) Algoritmo. Sea Fn=n! el término general de la secuencia. Tenemos F0 = 1 { valor inicial } F1 = F0*1 F2 = F1*2 ....... ....... Fj = F(j-1)*j { relación de recurrencia para j>0 } Debe observarse que es necesario definir un valor inicial, ya que la relación de recurrencia debe, para poder ser evaluada, partir de un valor conocido. Si se observa que los valores: 1, 2, 3,....j también forman una secuencia ( sea Ji), puede escribirse: Ji = J(i-1) + 1 Fi = F(i-1)*Ji para i>0. Con valores iniciales: J0 = 0 F0 = 1 Es fundamental considerar que en el algoritmo se dispondrá de una variable para almacenar los valores de la secuencia. En el ejemplo necesitamos espacio para dos variables, una para el valor actual de F, y otro para el valor actual de J. En la relación de recurrencia el subíndice i refleja el tiempo del proceso. Si i indica el valor actual; ( i-1 ) está asociado al valor anterior. Prof. Leopoldo Silva Bijit. 07-07-2003 41 UNIVERSIDAD TECNICA FEDERICO SANTA MARIA DEPARTAMENTO DE ELECTRONICA Programación en Pascal Capítulo 5. Programas basados en relaciones de recurrencia. La notación empleada, hasta el momento, corresponde a la algebraica. No debe confundirse los signos igual con la asignación o el operador de relación. A continuación veremos un programa que calcula el valor de N!; donde N es un valor que deberá ser suministrado por el operador. Nótese que no interesa almacenar, para un uso futuro, los diferentes valores de la secuencia. Si este fuera el caso se necesitarían más variables, una por cada valor diferente a recordar. b) Programa. Program factorial; { calcula N! } Var j,f,n:integer; Begin Read(n); j:=0; f:=1; {inicialización de variables} while j<n do begin j:=j+1; f:=f*j end ; {relación de recurrencia} write(f) end. El programa puede escribirse fácilmente a partir de la relación de recurrencia desarrollada anteriormente. Nótese que el subíndice i, que da el orden en la relación, indica cómo deben concatenarse las acciones. Específicamente para calcular Fi es preciso conocer Ji; esto indica que debe calcularse primero el valor actual de j a partir de su valor anterior. Demás está destacar que el orden es importante, y que un cambio en la concatenación de asignaciones corresponde a la implementación de otra relación de recurrencia. 5.1.2. Esquema general de secuencias. A partir del ejemplo anterior puede abstraerse el siguiente esquema de algoritmo: --V := vo ; while p(V) do V := f(V); --- {iniciación de variables} {generación secuencia} V simboliza al conjunto de variables cuyos valores son generados por una relación de recurrencia; ésta es descrita por: V := f(V), que destaca que para calcular los valores actuales se recurre a los valores anteriores. Prof. Leopoldo Silva Bijit. 07-07-2003 42 UNIVERSIDAD TECNICA FEDERICO SANTA MARIA DEPARTAMENTO DE ELECTRONICA Programación en Pascal Capítulo 5. Programas basados en relaciones de recurrencia. p(V) es un predicado; es decir, una condición que depende de las variables en análisis. Establece la condición de término de la iteración. 5.1.3. Algunas situaciones representadas por secuencias. Todas las fórmulas del cálculo financiero son representables mediante relaciones de recurrencia. La derivada e integral de una función, pueden evaluarse numéricamente empleando relaciones de recurrencia. Debido a lo anterior, la descripción dinámica de sistemas, que suele modelarse mediante ecuaciones diferenciales, también puede tratarse con los métodos desarrollados antes. En este caso específico las relaciones de recurrencia se denominan ecuaciones de diferencias. Algunos métodos numéricos para el cálculo de raíces también se plantean mediante relaciones de recurrencia. Los algoritmos clásicos de multiplicación, división, raíz cuadrada, recíproco y otros suelen también plantearse como procesos iterativos, descritos por relaciones de recurrencia. 5.2. Series. La mayoría de las funciones pueden calcularse, para un valor de su argumento, mediante una serie que las aproxima. Este es el caso del seno, coseno, tangente y otras funciones trigonométricas; también se calculan mediante series finitas, las funciones hiperbólicas. Logaritmos y exponenciales también suelen estar implementados mediante series. En los lenguajes de alto nivel, las funciones anteriores están disponibles; es decir están incorporadas como instrucciones del procesador aritmético que implementa la máquina virtual del lenguaje. Debido a lo anterior, los algoritmos para estas series han recibido gran dedicación y suelen estar optimizados, tanto en espacio (número de variables empleadas ) como en tiempo (veces que se efectúan las acciones). Consideremos la siguiente secuencia: S0 = t0 = t0 S1 = t0 + t1 = S0 + t1 S2 = t0 + t1 + t2 = S1 + t2 ---------------------------------------------- Prof. Leopoldo Silva Bijit. 07-07-2003 43 UNIVERSIDAD TECNICA FEDERICO SANTA MARIA DEPARTAMENTO DE ELECTRONICA Programación en Pascal Capítulo 5. Programas basados en relaciones de recurrencia. Si = t0 + t1 + t2 + ... ti = S(i-1) + ti para i>0 Se denomina serie a la suma: j =i Si = ∑ t j j =0 El término general puede describirse por la relación: tj = f(tj - 1) que genera t1,t2,......ti a partir de t0. Entonces la serie puede representarse por la siguiente relación de recurrencia: S0 = t0 Si = Si-1 + ti para i > 0 5.2.1. Esquema general. El siguiente segmento describe el algoritmo general para la evaluación de una serie: ----t := t0; s := t; {inicialización} while p(s, t) do begin t := f(t) ; s := s + t end; {serie} ----5.2.2. Serie exponencial. Se tiene: x2 x3 + + .... para todo x. 2! 3! Puede comprobarse que el término general resulta: ex = 1 + x + ti = t(i-1)* x/i para i > 0; con t0 = 1 Se tiene que: Prof. Leopoldo Silva Bijit. 07-07-2003 44 UNIVERSIDAD TECNICA FEDERICO SANTA MARIA DEPARTAMENTO DE ELECTRONICA Programación en Pascal Capítulo 5. Programas basados en relaciones de recurrencia. lim Si = e x i →∞ con Si = j=i tj ∑ j=0 El siguiente programa calcula, en forma aproximada, el valor de exp(x): Program exponencial; var x,s,t,epsilon: real; i: integer; begin read(x); t := 1; s := t ; i := 0 ; epsilon :=1.0E-6; while t > epsilon do begin i := i + 1; t:= t*x/i ; s:= s + t end; write(s) end. La computación se efectúa empleando números reales; y la detención de la iteración se logra cuando el término general es menor o igual al valor de epsilon. El bloque de repetición se efectúa i veces; mayor será este número cuanto menor sea el valor de epsilon. Como se verá mas adelante existe un mínimo valor representable como número real, dentro del procesador; el valor de epsilon debe ser mayor que este valor. La asignación que calcula el término general efectúa una mezcla de tipos. Ya que t y x son reales, e i es de tipo entero. En Pascal se permite mezcla de tipos en expresiones (Report pag 146.). Si uno de los operadores es real; entonces, el resultado también es real. Un resultado real puede almacenarse en una variable real; pero no en una entera. En la mayoría de los lenguajes tradicionales, se acepta la mezcla de tipos en expresiones y además se contempla la conversión de tipos en asignaciones. Esta libertad suele ser fuente de innumerables errores en programación; por esta razón los lenguajes modernos imponen la compatibilidad de tipos. Suelen emplearse funciones especiales que permiten convertir un valor de un tipo en otro; a esta operación se la denomina conversión explícita. Prof. Leopoldo Silva Bijit. 07-07-2003 45