ADA Tema 4. Técnicas de Solución de Problemas 1. Introducción

Tamaño: px
Comenzar la demostración a partir de la página:

Download "ADA Tema 4. Técnicas de Solución de Problemas 1. Introducción"

Transcripción

1 ADA Tema 4. Técnicas de Solución de Problemas 1. Introducción 2. Divide y Vencerás 3. Complejidad de los algoritmos de Divide y Vencerás y tiempo de ejecución 4. Problemas que se resuelven con Divide y Vencerás 1. Introducción En este tema vamos a abordar la solución de problemas con diferentes técnicas que estudiaremos. Antes de ver la forma de resolver un problema debemos indicar las características del mismo y modelarlo como un tipo del que podemos crear objetos. Como todos los tipos un problema tendrá diferentes propiedades. Un problema en general lo modelaremos, como hemos visto en el capítulo anterior, mediante el interface genérico Problema<S> donde S es el tipo de la solución del problema. Al tipo que instancie a S le exigiremos en algunos contextos concretos propiedades específicas como que tenga un orden natural o que sea copiable, etc. El interface que representará a un problema en general será: public interface Problema<S> { public static enum TipoDeProblema { UNA_SOLUCION,TODAS_LAS_SOLUCIONES,MEJOR_SOLUCION; Problema.TipoDeProblema gettipodeproblema(); Un problema, con soluciones de tipo S, se resuelve mediante un algoritmo dado. Los tipos de algoritmos que estudiaremos están descritos por el tipo enumerado TipoDeAlgoritmo. Los algoritmos que estudiaremos serán implementaciones del tipo Algoritmo<S>. public interface Algoritmo<S>{ public enum TipoDeAlgoritmo { DIVIDE_Y_VENCERAS_CON_MEMORIA, DIVIDE_Y_VENCERAS_SIN_MEMORIA, PROGRAMACION_DINAMICA, ITERATIVO, VORAZ, RAMIFICA_Y_PODA; void ejecuta(); Problema<S> getproblema(); Metricas getmetricas(); TipoDeAlgoritmo gettipodealgoritmo();

2 Como vemos un algoritmo tiene las propiedades: Problema: Problema<S>, es el problema que estamos resolviendo. Metricas: Metricas, es un objeto que guarda información sobre diferentes propiedades del algoritmo. TipoDeAlgoritmo: TipoDeAlgoritmo, es el tipo concreto de algoritmo que estamos usando. El método ejecuta pone en funcionamiento el algoritmo. La clase Metricas mide propiedades de un algoritmo en las que podemos estar estamos interesados como por ejemplo TiempoDeEjecucion. Las propiedades que pueden medirse las iremos viendo a medida que sean necesarias. El tipo algoritmo lo especializamos en tres tipos: AlgoritmoConUnaSolucion, AlgoritmoConVariasSoluciones y AlgoritmoConVariosProblemas. Estas especializaciones están pensadas respectivamente, como indica su nombre, para algoritmos que devuelven una solución, varias soluciones o resuelven varios problemas cada uno con una solución. Los interfaces de cada uno de ellos son: public interface AlgoritmoConUnaSolucion<S> extends Algoritmo<S> { S getsolucion(); boolean issolucion(); public interface AlgoritmoConVariasSoluciones<S extends Copiable<S>> extends Algoritmo<S> { SortedSet<S> getsoluciones(); Integer getnumerodesoluciones(); boolean issolucion(); S getmejorsolucion(); Set<S> getmejoressoluciones(); Comparator<S> getordendesoluciones(); public interface AlgoritmoConVariosProblemas<S extends Copiable<S>> extends Algoritmo<S> { S getsolucion(problema<s> p); boolean issolucion(problema<s> p); boolean isproblema(problema<s> p); Integer getnumerodeproblemas(); Integer getnumerodeproblemasconsolucion(); En el algoritmo con varias soluciones asumimos que las soluciones están ordenadas con respecto a un orden y que podemos preguntar por la mejor solución, con respecto a ese orden por todas las soluciones o por las mejores soluciones. En el algoritmo con varios problemas asumimos que se resuelven un conjunto de problemas que comparten datos de algún tipo. En este tipo de algoritmo podemos preguntar si hay solución un problema dado, dentro del rango de problemas considerado, si tiene solución, cual es la solución, el número de problemas considerados o el número de ellos con solución.

3 2. Divide y Vencerás Para el uso adecuado de esta técnica es conveniente recordar los conceptos de generalización de parámetros y conjunto de problemas. Cuando al problema de partida se le añaden nuevas propiedades para obtener otro problema más general decimos que hemos hecho una generalización de parámetros. En muchos casos es necesario generalizar el problema para resolverlo con mayor facilidad. Como vimos en el capítulo anterior llamaremos conjunto de problemas al conjunto de problemas concretos que pueden obtenerse instanciando, de todas las formas posibles, algunas propiedades escogidas de un problema general dado. En algunas técnicas es muy importante especificar detalladamente el conjunto de problemas con el que estamos trabajando. Dentro de un conjunto de problemas dado podemos distinguir, como para cualquier tipo, dos clases de propiedades: propiedades compartidas por todos los problemas del conjunto y propiedades específicas de cada problema en particular. Como vimos en el capítulo anterior dado un conjunto de problemas podemos escoger dos formas para identificar a cada uno de los problemas concretos. Cada forma tiene sus ventajas e inconvenientes. Estas formas son: Asociar un objeto a cada problema. Es la técnica más general y sistemática. En el contexto de un conjunto de problemas es suficiente definir la igualdad (y los métodos asociados hashcode, tostring, compareto) en base a las propiedades específicas ignorando las propiedades compartidas. Las propiedades compartidas se pueden implementar de varias maneras: como variables de tipo static compartidas por todos los objetos (problemas) de la clase o como una propiedad más. Asociar a cada problema un conjunto de parámetros. El conjunto de parámetros representa las propiedades específicas de cada problema. Este modo de representar los problemas concretos es menos reutilizable, como veremos, pero más sencillo de usar en casos simples. La igualdad de dos problemas se implementa como igualdad del conjunto de parámetros que los representan. Las propiedades compartidas pueden implementarse como variables con un ámbito suficientemente amplio o como una propiedad más representada por un parámetro adicional. La primera técnica de solución de problemas que estudiaremos se denomina Divide y Vencerás. El término Divide y Vencerás (en inglés, Divide and Conquer) hace referencia a uno de los más importantes paradigmas de diseño de algoritmos para resolver problemas como los que hemos modelado en el capítulo anterior. El método está basado en la resolución recursiva de un problema dividiéndolo en dos o más sub-problemas de igual tipo o similar. El proceso continúa hasta que éstos llegan a ser lo suficientemente sencillos como para que se resuelvan directamente. Al final, las soluciones a cada uno de los sub-problemas se combinan para dar una solución al problema original.

4 En esta técnica, y en otras que veremos más adelante, es muy importante detallar el conjunto de problemas con el que estamos tratando. A cada problema del conjunto debemos asignarle un tamaño que medirá el grado de complejidad del problema. En el caso del problema de la Potencia Entera, visto en el capítulo anterior, el tamaño es la propiedad Exponente. Los problemas del conjunto de problemas tenemos que clasificarlos en dos clases: casos base que problemas sencillos que tienen un tamaño pequeño y cuya solución puede ser obtenida directamente y casos recursivos que los problemas que no son casos base. Tras modelar un problema tal como hemos explicado en el capítulo anterior y con las ideas anteriores en mente la resolución del mismo mediante esta técnica consta fundamentalmente de los siguientes pasos: En primer lugar considerar el conjunto de problemas con el que vamos a tratar. Este conjunto de problemas puede ser obtenido del problema original o de una generalización de parámetros del mismo. Decidir cuál es el tamaño de cada problema y cuáles son las propiedades compartidas y específicas. Clasificar el conjunto de problemas en casos base y casos recursivos. Decidir como representar cada problema del conjunto: mediante un conjunto de parámetros o mediante un objeto. En segundo lugar han de proporcionarse las soluciones para los problemas que son casos base (es decir los problemas sencillos de tamaño pequeño). En tercer lugar ha de plantearse la forma de descomponer cada problema del conjunto (que sea un caso recursivo) en varios problemas del mismo conjunto, pero de menor tamaño. A esta tarea se le conoce como división u obtención de los sub-problemas. Si el número de sub-problemas es uno entonces la técnica es conocida como Reducción en vez de Divide y Vencerás. Por último, combinar las soluciones obtenidas en el paso anterior para construir la solución del problema original. El algoritmo diseñado con la filosofía de Divide y Vencerás funciona de la siguiente manera: si el problema original es un caso base resolver el problema directamente, si es un caso recursivo dividirlo en sub-problemas, resolver recursivamente cada uno de ellos y combinar las soluciones obtenidas. Es muy importante que en el proceso de división el tamaño de cada subproblema sea menor que el tamaño del problema original. El hecho de que el tamaño de los sub-problemas sea estrictamente menor que el tamaño original del problema nos garantiza la convergencia hacia los casos base y por lo tanto nos garantiza que el proceso termina. Un problema, que se resuelve por la técnica de Divide Y Vencerás, adopta la forma:,,,,, Donde X representa el problema de tamaño n, los sub-problemas de tamaño con, c la función que combina las soluciones de los problemas (en el contexto del problema a resolver) y la solución del caso base de los que puede haber más de uno. Siempre asumiremos un valor de que indique que no hay solución. Representaremos este valor

5 por. En esta técnica si uno de los problemas no tiene solución entonces el problema completo tampoco la tiene. La técnica Divide y Vencerás, cuando el número de sub-problemas es uno, se llama reducción o simplificación de problemas. Veamos, en primer lugar, el software resultante si decidimos representar cada problema del conjunto mediante un objeto. Es la aproximación más sistemática y la que usaremos casi siempre aunque en el algunos casos sencillos puede ser preferible usar otro punto de vista (representar cada problema como un conjunto de parámetros) que veremos más adelante. Desde el punto de vista adoptado la técnica Divide y Vencerás, explicada arriba, consiste en implementar una nueva vista de cada problema que denominaremos ProblemaDyV. Esta vista es un nuevo tipo que extiende Problema tal como se ve a continuación. Cada problema del conjunto ofrece el tipo Problema (donde están los detalles del problema) y ProblemaDyV (donde están los detalles de la forma de resolverlo mediante la técnica de Divide y Vencerás). public interface ProblemaDyV<S> extends Problema<S> { boolean escasobase(); S getsolucioncasobase(); ProblemaDyV<S> getsubproblema(int i); S combinasoluciones(s... ls); int getnumerosubproblemas(); Los cuatro métodos que contiene son: escasobase(). Indica si el problema que se está resolviendo es tan simple que no necesita recursión para su resolución y por lo tanto puede obtenerse la solución directamente. getsolucioncasobase(). Devuelve la solución al problema, resuelto de forma directa, suponiendo que el método anterior ha devuelto true. getsubproblema( ). Devuelve el sub-problemas i-ésimo. combinasoluciones( ). Combina las soluciones de cada uno de los sub-problemas de manera que juntas resuelvan el problema completo. getnumerosubproblemas(). Número de sub-problemas. Una vez que disponemos de los tipos Problema<S> y ProblemaDyV<S> podemos diseñar una clase genérica (adecuada para todos los problemas que implementan los interfaces anteriores) que contiene el algoritmo para resolver el problema por la técnica de Divide y Vencerás. Hay otras técnicas para resolver problemas que veremos más adelante. Para cada técnica diseñaremos una clase con el algoritmo correspondiente. Todas esas clases son implementaciones de la idea general representada por el tipo Algoritmo<S> o alguna de sus especializaciones. La clase AlgoritmoDivideYVencerasSinMemoria<S> es la implementación del tipo Algoritmo<S> (en concreto de AlgoritmoConUnaSolucion<S> puesto que esta técnica está muy orientada a

6 resolver problemas con una solución) que contiene las técnicas de Divide y Vencerás. Más adelante las ampliaremos con otros detalles que nos permitirán obtener de forma automática diversas métricas en tiempo de ejecución. La clase es de la forma: public class AlgoritmoDivideYVencerasSinMemoria<S> implements AlgoritmoConUnaSolucion<S> { private ProblemaDyV<S> problema; private S solucion; private Class<S> tiposolucion; public AlgoritmoDivideYVencerasSinMemoria(ProblemaDyV<S> p){ problema = p; public public void ejecuta() { tiposolucion = (Class<S>) problema.getsolucioncasobase().getclass(); solucion = dyv(problema); private S dyv(problemadyv<s> p){ S s; if( p.escasobase()){ s = p.getsolucioncasobase(); else { int numerodesubproblemas = p.getnumerosubproblemas(); S[] soluciones = Utiles.creaArray(tipoSolucion,numeroDeSubProblemas); for(int i = 0; i < numerodesubproblemas; i++){ s = dyv(p.getsubproblema(i)); soluciones[i]=s; s = p.combinasoluciones(soluciones); return s; public void setproblema(problemadyv<s> problema) { this.problema = public ProblemaDyV<S> getproblema() { return public S getsolucion() { return public TipoDeAlgoritmo gettipodealgoritmo() { return public boolean issolucion() {

7 return solucion!=null; De forma equivalente podemos diseñar una plantilla que contenga el código de la clase anterior con una variable que sustituya al tipo S. A esa variable de la plantilla la llamaremos ${typesolucion. La plantilla la llamaremos dyvo. Esta plantilla incluye código en la clase diseñada por lo tanto no incluye los constructores ni la variable problema que pasa a ser el this de la correspondiente clase. Aplicaciones al Problema de Fibonacci Veamos con funciona todo junto en el caso concreto del problema de Fibonacci. Si tenemos especificado el problema de Fibonacci visto en el tema anterior como: public interface ProblemaFibonacci extends Problema<BigInteger> { Integer getn(); Para resolver el problema por la técnica de Divide y Vencerás diseñamos la clase ProblemaFibonacciDyVImplO que implementa los interfaces ProblemaFibonacci, ProblemaDyV<BigInteger> y Algoritmo<BigInteger>. Entonces podemos diseñar la clase de prueba para obtener la solución del problema con esta técnica: public class TestFibonacci1 extends Test { public static void main(string[] args) { Integer n = 40; AlgoritmoConUnaSolucion<BigInteger> p = new ProblemaFibonacciDyVImplO(n); a.ejecuta(); mostrar("el problema es "+p); BigInteger s = a.getsolucion(); mostrar("la solucion es "+s); En implementación de la clase ProblemaFibonacciDyVImplO hay que tener en cuenta: La implementación del problema: propiedades, métodos relacionados con la igualdad, etc. En definitiva implementación del interface ProblemaFibonacci. La implementación del interface del problema para poder ser resuelto por l técnica de Divide y Vencerás. Esto implica la implementación la implementación de la interfaz ProblemaDyV<BigInteger>. La implementación del interfaz Algoritmo<BigInteger> con la técnica escogida (en este caso Divide y Vencerás). Esto podemos hacerlo de varias maneras: reutilizando la clase AlgoritmoDivideYVencerasSinMemoria<BigInteger> (mediante herencia o composición) o usando la plantilla dyvo si queremos tener más control sobre el código. En el ejemplo siguiente hemos usado la plantilla citada.

8 public class ProblemaFibonacciDyVImplO implements ProblemaDyV<BigInteger>, ProblemaFibonacci, AlgoritmoConUnaSolucion<BigInteger> { private Integer n; public ProblemaFibonacciDyVImplO(Integer n) { this.n = n; public Integer getn() { return n;... public BigInteger combinasoluciones(biginteger... ls) { return ls[0].add(ls[1]); public boolean escasobase() { return getn() == 0 getn()==1; public BigInteger getsolucioncasobase() { BigInteger s; if(getn()==0) s = BigInteger.ZERO; else s = BigInteger.ONE; return s; public ProblemaDyV<BigInteger> getsubproblema(int i) { return new ProblemaFibonacciDyVImplO(getN()-i-1); public int getnumerosubproblemas() { return 2; private BigInteger solucion; public void ejecuta() { solucion = dyv(this); private BigInteger dyv(problemadyv<biginteger> p) { BigInteger s; if (p.escasobase()) { s = p.getsolucioncasobase(); else { ProblemaDyV<BigInteger> p0 = p.getsubproblema(0); BigInteger s0 = dyv(p0); ProblemaDyV<BigInteger> p1 = p.getsubproblema(1); BigInteger s1 = dyv(p1); s = p.combinasoluciones(s0, s1); return s;... Donde se ha tenido en cuenta:

9 La definición del problema de Fibonacci como calcular f(n) tal que: f(n) = f(n-1)+f(n-2) y f(0) =0, f(1) =1. De la primera parte de la definición podemos obtener el código de los métodos getsubproblema(i) y combinasoluciones y de la segunda los métodos escasobase y getsolucioncasobase. El conjunto de problemas con el que estamos tratando es el que se obtiene al variar la propiedad N desde 0 en adelante. Los problemas sólo tienen una propiedad individual que es la propiedad N. Toda la información sobre el problema podemos resumirla en la siguiente tabla: Ficha 1 Problema de Fibonacci Técnica: Divide y Vencerás sin Memoria Representación: Cada problema un objeto Tamaño: N Propiedades Individuales f(n) = { N, Integer no negativo 0 Si n ==0 1 Si n == 1 f(n-1)+f(n-2) Si n > 1 De ahora en adelante para cada problema a resolver con la técnica de Divide y Vencerás construiremos una tabla como la anterior. A partir de la tabla es metódico construir las clases implicadas porque en la tabla se definen las propiedades del problema y por lo tanto el conjunto de problemas con el que estamos tratando, los casos base, los sub-problemas en que dividimos cada problema, la forma de combinarlos y la forma de representarlos. Por defecto la forma de representar los problemas es mediante un objeto por problema que será, sobre todo en otras técnicas, la más habitual. Un enfoque alternativo (a representar cada problema por un objeto) es representar cada problema por unos parámetros que representan un conjunto de propiedades. Como conjunto de propiedades se eligen las propiedades individuales de los problemas. Ahora el mecanismo necesita más ajuste manual pero sigue siendo bastante sistemático. La diferencia es que ahora los métodos escasobase, getsolucioncasobase, etc. serán métodos privados que necesitan tomar, en cada problema particular, como parámetros las propiedades que definen al problema. Tampoco se puede diseñar de forma general una clase que contenga el algoritmo de Divide y Vencerás. Es decir cuando representamos un problema por un objeto las signaturas del los métodos son las que recogimos en el interface ProblemaDyV<S>: public interface ProblemaDyV<S> extends Problema<S> { boolean escasobase(); S getsolucioncasobase(); ProblemaDyV<S> getsubproblema(int i); S combinasoluciones(s... ls); int getnumerosubproblemas(); Y las llamadas a esos métodos para escribir el algoritmo de Divide y Vencerás:

10 private BigInteger dyv(problemadyv<biginteger> p) { BigInteger s; if (p.escasobase()) { s = p.getsolucioncasobase(); else { ProblemaDyV<BigInteger> p0 = p.getsubproblema(0); BigInteger s0 = dyv(p0); ProblemaDyV<BigInteger> p1 = p.getsubproblema(1); BigInteger s1 = dyv(p1); s = p.combinasoluciones(s0, s1); return s; Si representamos un problema por un conjunto de parámetros la signatura de los métodos es: boolean escasobase(t1 a1,...,tk ar); S getsolucioncasobase(t1 a1,...,tk ar); S combinasoluciones(s... ls); Donde un problema se representa por el producto cartesiano <T1,,Tk>. Siendo T1,,Tk los tipos de las propiedades P1,, Pk que hemos decidido que representen al problema. Las llamadas esos métodos para escribir el algoritmo de Divide y Vencerás con esta representación de los problemas es: private BigInteger dyv(integer n){ BigInteger s; if( escasobase(n)){ s = getsolucioncasobase(n); else { BigInteger s1 = dyv(n-1); BigInteger s2 = dyv(n-2); s = combinasoluciones(s1,s2); return s; Observamos que al ser el método más manual no es necesario disponer de un método que nos de los sub-problemas ni el número de ellos. Un sub-problema se identifica como una expresión que se calcula a partir de las propiedades del problema. En este caso los sub-problemas son: n-1, n-2. Es posible diseñar una plantilla que recoja esas ideas para el caso particular de que los problemas se identifiquen por una sola propiedad. La denominaremos dyvp1. Otra para cuando hay dos propiedades dyvp2, etc.

11 La ficha del problema, muy similar a la anterior, es ahora: Ficha 2 Problema de Fibonacci Técnica: Divide y Vencerás sin Memoria Representación: Cada problema un conjunto de parámetros Tamaño: N Propiedades Individuales f(n) = { N, Integer no negativo 0 Si n ==0 1 Si n == 1 f(n-1)+f(n-2) Si n > 1 El nuevo enfoque lo concretamos en la clase ProblemaFibonacciDyVImpP. Esta clase implementa el tipo ProblemaFibonacci y Algoritmo y tiene el código: public class ProblemaFibonacciDyVImplP implements ProblemaFibonacci, AlgoritmoConUnaSolucion<BigInteger> { private Integer n; public ProblemaFibonacciDyVImplP(Integer n) { this.n = n; public Integer getn() { return n;... private BigInteger solucion; public void ejecuta(){ solucion = dyv(n);... private BigInteger dyv(integer n){ BigInteger s; if( escasobase(n)){ s = getsolucioncasobase(n); else { BigInteger s1 = dyv(n-1); BigInteger s2 = dyv(n-2); s = combinasoluciones(s1,s2); return s;... Es conveniente comparar los dos enfoques para decidir en cada problema en particular cual es el más adecuado. En resumen a partir de la información contenida en la Ficha que describe un problema es bastante sistemático, en el enfoque un objeto por cada problema o representación de un

12 problema por un conjunto de propiedades, diseñar e implementar las clases correspondientes. Por lo tanto en el resto de los problemas nos concentraremos en indicar para cada problema los detalles de la tabla asociada. El test asociado a la Ficha 2 es: public class TestFibonacci2 extends Test { public static void main(string[] args) { Integer n = 6; AlgoritmoConUnaSolucion<BigInteger> a = new ProblemaFibonacciDyVImplP(n); a.ejecuta(); mostrar("el problema es "+n); BigInteger s = a.getsolucion(); mostrar("la solucion es "+s); Que es conveniente comparar con el correspondiente al de la Ficha 1. Veamos, representado cada problema por un conjunto de parámetros, la solución del problema de la Potencia Entera. La ficha correspondiente es: Ficha 3 Problema PotenciaEntera<B> Técnica: Reducción sin Memoria Representación: Cada problema un conjunto de parámetros Tamaño: E Propiedades Individuales E: Integer no negativo Propiedades Compartidas pot(a,e) = pt(e) { A: B que extiende BasePotenciaEntera<B> 1 Si e == 0 A Si e == 1 pt(e/2)^2*(espar(e)?1:a) Si e > 1 En la ficha anterior A representa la propiedad Base del problema (a es un valor de esa propiedad) y E la propiedad Exponente (e es un valor de esa propiedad). En la ficha 3 vemos como cada problema, del conjunto de problemas considerado, puede ser representado por pt(e) (donde e es una valor de la única propiedad individual). El tipo BasePotenciaEntera<B> es una generalización de los tipos que disponen de operaciones de multiplicar por la base, elevar al cuadrado y elemento unidad de la multiplicación (las operaciones que el algoritmo hace sobre valores de la solución). Casos particulares, con la conveniente adaptación, son: enteros (con distintas precisiones), reales (con distintas precisiones), matrices, matrices de Fibonacci, etc. El problema que resolvemos es el problema general donde B puede ser instanciado a cualquiera de los tipos anteriores.

13 public interface BasePotenciaEntera<T> { T getone(); T getsquare(); T getbase(); T getmultiplybase(); void setbase(t base); T getbase(); Veamos, en primer lugar, la razón de la expresión que aparece en el caso recursivo es debido a las siguientes igualdades: / / / / = /? : 1 Donde hemos usado el operador ternario de java _?_:_. Escogemos representar cada problema por un parámetro que es el exponente. Por ilustración incluimos el código de los métodos más relevantes de la clase PotenciaEnteraDyVImpl: public class PotenciaEnteraDyVImpl<B extends BasePotenciaEntera<B>> implements PotenciaEntera<B>, AlgoritmoConUnaSolucion<B> { private B base; private Integer exponente; public PotenciaEnteraDyVImpl(B b, Integer exponente) { super(); this.base = b; base.setbase(base); this.exponente = exponente; public B getbase() { return base; public Integer getexponente() { return exponente; private B solucion; public void ejecuta(){ solucion = dyv(exponente); private boolean escasobase(integer n) { return n == 0 n == 1; private B getsolucioncasobase(integer n) { B r = null; if(n == 0) r = base.getone(); else if(n==1)

14 r = base; return r; private B dyv(integer n){ B s; if( escasobase(n)){ s = getsolucioncasobase(n); else { s = dyv(n/2); s = s.getsquare(); if(utiles.esimpar(n)) s = s.getmultiplybase(); return s;... Como vimos en el capítulo anterior las matrices de Fibonacci son de la forma. Es decir dependen de dos parámetros. Para implementar el tipo MatrizFibonacci, cuyos valores son las matrices de Fibonacci, y que extiende BasePotenciaEntera<MatrizFibonacci> hay que tener en cuenta que: , , ,. 0,0 Para implementar el tipo MatrizFibonacci (que debe extender el tipo BasePotenciaEntera<MatrizFibonacci>) hay que tener en cuenta las igualdades: ; La primera nos permite implementar el método getsquare, la segunda getmultiplybase. Con estas ideas podemos resolver, de nuevo, el problema de Fibonacci con otra técnica: instanciando el Problema Potencia Entera con el tipo MatrizFibonacci implementado. La ficha del problema es ahora: Ficha 4 Problema de Fibonacci Técnica: Instanciación ProblemaPotenciaEntera<MatrizFibonacci> Tamaño: N Propiedades Individuales N, Integer no negativo ,0

15 El test para este problema es: public class TestFibonacci4 extends Test { public static void main(string[] args) { MatrizFibonacci base = new MatrizFibonacci(BigInteger.ONE,BigInteger.ZERO); Integer n = 1000; AlgoritmoConUnaSolucion<MatrizFibonacci> a = new PotenciaEnteraDyVImpl<MatrizFibonacci>(base,n); a.ejecuta(); mostrar("el problema es "+n+" la solucion "+a.getsolucion().get(0,0)); El problema de la potencia entera puede ser instanciado para resolver otros problemas. Algunos de ellos son: con a de tipo entero o real. con A una matriz rectangular Una recurrencia del tipo. Con unas condiciones iniciales dadas. La idea se la misma que en el caso de Fibonacci: transformar la recurrencia en la ecuación matricial y posteriormente calcular la potencia n-ésima de la matriz. %. Es decir el resto con respecto a r de sin tener que hacer la operación de potencia y usando resultados intermedios razonablemente pequeños. Esto es debido a las propiedades % % % y % % %% que nos permite implementar el tipo BasePotenciaEntera con esas operaciones. Divide y Vencerás con Memoria La técnica de divide y vencerás tiene una variante muy importante. Es la técnica de Divide y Vencerás con Memoria. El problema de Fibonacci nos puede servir de nuevo de motivación. Hemos resuelto el problema de Fibonacci de dos maneras: mediante un enfoque directo usando Divide y Vencerás sin Memoria (la técnica de Divide y Vencerás que hemos usado hasta ahora Fichas 1, 2) e instanciando el problema de la Potencia Entera (Ficha 4). En la versión de las Ficha 1 (también de la 2) podemos comprobar que la complejidad es exponencial. Eso es debido a que al resolver el problema de f(n) se resuelven primero los f(n-1) y f(n-2). Estos a su vez resuelven primero f(n-2), f(n-3) y f(n-3), f(n-4) respectivamente y así sucesivamente. Vemos que para resolver f(n) se resuelven muchas veces muchos de los subproblemas. En particular el f(n-3) anterior. Una forma de evitar resolver el mismo problema varias veces es recordar que ya se resolvió y cuál fue la solución. El esquema general de esta técnica es:

16 ,,,,,,,,, Como vemos siempre aparece un nuevo caso base que ocurre si el problema considerado pertenece al dominio de la memoria. El nuevo operadores ca tiene que, además de calcular la solución a partir de las soluciones de los sub-problemas, añadir a la memoria la solución encontrada del problema. Donde la memoria m puede concretarse mediante una variable de tipo Esto puede hacerse con un Map<Problema,Solucion>. La forma de implementarlo es distinta según que representemos los problemas como objetos o como conjunto de parámetros. Veamos la primera alternativa en primer lugar. La ficha correspondiente sería: Ficha 5 Problema de Fibonacci Técnica: Divide y Vencerás con Memoria Representación: Cada problema un objeto Tamaño: N Propiedades Individuales f(n) = { N, Integer no negativo 0 Si n ==0 1 Si n == 1 f(n-1)+f(n-2) Si n > 1 Para implementar la información de la Ficha 5 podemos reutilizar la clase ProblemaFibonacciDyVImpl2 que usamos en la Ficha 1. Pero ahora necesitamos una clase que implemente el tipo Algoritmo con las ideas del método Divide y Vencerás con Memoria. Esta es la clase AlgoritmoDivideYVencerasConMemoria. Los detalles más relevantes de la misma son: public class AlgoritmoDivideYVencerasConMemoria<S> implements AlgoritmoConUnaSolucion<S> { private Map<ProblemaDyV<S>, S> map; private ProblemaDyV<S> problema; private S solucion; public AlgoritmoDivideYVencerasConMemoria(ProblemaDyV<S> p) { problema = p; map = MapsFactory.creaMap(); tipodealgoritmo = Algoritmo.TipoDeAlgoritmo.DIVIDE_Y_VENCERAS_CON_MEMORIA; public void ejecuta() { solucion = dyv(problema);

17 private S dyv(problemadyv<s> p) { S s; if (map.containskey(p)) { s = map.get(p); else if (p.escasobase()) { s = p.getsolucioncasobase(); map.put(p, s); else { int numerodesubproblemas = p.getnumerosubproblemas(); S[] soluciones = Utiles.creaArray(numeroDeSubProblemas); for(int i = 0; i < numerodesubproblemas; i++){ ProblemaDyV<S> pr = p.getsubproblema(i); s = dyv(pr); soluciones[i]=s; map.put(pr, s); s = p.combinasoluciones(soluciones); map.put(p, s); return s;... De forma similar al caso sin memoria a partir del código de la clase anterior podemos escribir una plantilla, que denominaremos dyvmo, que puede ayudarnos a generar un código equivalente. Ahora el test asociado a la Ficha 5 es el siguiente y podemos compararlo, pos su similitud, con el test asociado a la Ficha 1. public class TestFibonacci5 extends Test { public static void main(string[] args) { Integer n = 40; AlgoritmoConUnaSolucion<BigInteger> p = new ProblemaFibonacciDyVImplMO(n); a.ejecuta(); mostrar("el problema es "+p); BigInteger s = a.getsolucion(); mostrar("la solucion es "+s); AlgoritmoDivideYVencerasSinMemoria y AlgoritmoDivideYVencerasConMemoria son dos clases reutilizables que implementan, respectivamente las técnicas Divide y Vencerás sin y con Memoria. La clase ProblemaFibonacciDyVImplMO, que implementa los interfaces ProblemaFibonacci (que extiende a Problema<BigInteger>), ProblemaDyV<BigInteger> y AlgoritmoConUnaSolucion<BigInteger> pero ahora usaremos la plantilla dyvmo (o reutilizamos la clase que implementa el algoritmo con memoria). Elegir entre una técnica u otra sólo implica elegir una de las dos clases reutilizables AlgoritmoDivideYVenceras o una de las dos plantillas: dyvo, dyvmo.

18 Como vemos (clase AlgoritmoDivideYVencerasConMemoria) el algoritmo que implementa la técnica usa un atributo de tipo Map<ProblemaDyV<S>, S>. Este atributo sirve para recordar los problemas resueltos (que pertenecen a su dominio) y la solución (imagen del problema). Como sabemos para que esto funcione adecuadamente es crítico que el problema tenga bien implementada la igualdad y los métodos relacionados (equals, hashcode). La igualdad la definimos basada en las propiedades individuales del problema tal como aparecen descritas en la ficha correspondiente. Todavía tenemos otra posibilidad: resolver el problema de Fibonacci por la técnica de Divide y Vencerás con Memoria pero representando cada problema por un conjunto de parámetros. Esta forma la recogemos en la Ficha 6: Ficha 6 Problema de Fibonacci Técnica: Divide y Vencerás con Memoria Representación: Cada problema un conjunto de parámetros Tamaño: N Propiedades Individuales f(n) = { N, Integer no negativo 0 Si n ==0 1 Si n == 1 f(n-1)+f(n-2) Si n > 1 El test correspondiente a la Ficha 6 es el que aparece abajo. public class TestFibonacci6 extends Test { public static void main(string[] args) { Integer n = 1000; AlgoritmoConUnaSolucion<BigInteger> a = new ProblemaFibonacciDyVImplMP(n); a.ejecuta(); mostrar("el problema es "+n); BigInteger s = a.getsolucion(); mostrar("la solucion es "+s); La clase ProblemaFibonacciDyVImplMP implementa ProblemaFibonacci, AlgoritmoConUnaSolucion<BigInteger> y su código, que incluimos abajo en sus detalles que cambian, puede ser comparado con el de la clase ProblemaFibonacciDyVImplP que implementaba las mismas ideas pero sin memoria. public class ProblemaFibonacciDyVImpl3 implements ProblemaFibonacci, AlgoritmoConUnaSolucion<BigInteger> { private Integer n; private BigInteger solucion; private Map<Integer,BigInteger> map = MapsFactory.creaMap();

19 public void ejecuta(){ solucion = dyv(n);... private BigInteger dyv(integer n){ BigInteger s; if(map.containskey(n)) { s = map.get(n); else if(escasobase(n)){ s = getsolucioncasobase(n); map.put(n, s); else { BigInteger s1 = dyv(n-1); map.put(n-1, s1); BigInteger s2 = dyv(n-2); map.put(n-2, s2); s = combinasoluciones(s1,s2); map.put(n, s); return s;... La otra cuestión importante son los detalles de la variable Map. En este problema en particular la variable es del tipo Map<Integer,BigInteger>: el tipo de la única propiedad que identifica a un problema y el tipo de la solución. Cuando representamos los problemas por objetos (Ficha 5) la variable es del tipo genérico Map<ProblemaDyV<S>, S>. En el caso de un problema similar al resuelto en la Ficha 6 pero con varias variables individuales el tipo de la variable será Map<T, S> donde S se instanciará al tipo de la solución y T a un producto cartesiano de los tipos de las propiedades individuales. Por las mismas razones que antes este producto cartesiano debe tener bien implementados los métodos relacionados con la igualdad. Como sabemos el producto cartesiano de varios tipos 1 2 es un tipo cuyos valores son los pares ordenados,, donde el primer valor es tipo T1 y el segundo del tipo T2, etc. Para dos tipos se le suele llamar Par. Solución de Conjuntos de Problemas Los problemas que se resuelven con la técnica de Divide y Vencerás con Memoria usan una variable denominada map de tipo Map<ProblemaDyV<S>, S>. Esto nos permite usar esta variable para implementar el tipo AlgoritmoConVariosProblemas<S> sin necesidad de cálculos adicionales. Esto nos permitirá preguntar por el número de problemas resueltos, la solución de cada uno, etc. Las ideas pueden resumirse en: La solución de un problema es su imagen en la variable map El número de problemas es el cardinal del dominio de map. El número de problemas con solución es el cardinal del subconjunto de problemas cuya solución es válida

20 Un problema es del conjunto considerado (todos los sub-problemas resueltos usando la técnica de Divide y Vencerás con Memoria) si es del tipo considerado y pertenece al dominio de map. Divide y Vencerás Probabilista La técnica de Divide Y Vencerás puede ser combinada en algunos casos con técnicas aleatorias. El algoritmo adopta, como hemos visto, la forma:,,, En algunos casos es interesante obtener a partir del problema de tamaño n dos subproblemas, de tamaños i, en el rango [1,n-1], y n-i respectivamente. Una posibilidad es escoger i aleatoriamente en el rango [1,n-1]. Si la complejidad de c( ) es entonces el tiempo de ejecución medio de este tipo de problemas cumple la recurrencia: Donde es la probabilidad del caso i en un problema de tamaño n. En definitiva es usar una variable aleatoria para decidir el tamaño de los sub-problemas. Como veremos la solución de esta recurrencia es log. Este tipo de técnica es útil cuando el problema a resolver tiene una propiedad que es un agregado de datos (conjunto, lista, array, etc.). Corrección de los algoritmos de Divide y Vencerás La corrección de un algoritmo de Divide y Vencerás se puede probar por inducción matemática, y su coste computacional se determina resolviendo relaciones de recurrencia. Para demostrar la corrección hacemos dos cosas: Demostrar que las soluciones de los casos base son correctas Suponiendo que son correctas las soluciones de los sub-problemas demostrar que la combinación de sus soluciones produce la solución correcta para el problema completo. Demostrar que el tamaño va decreciendo estrictamente cuando pasamos de un problema a sus sub-problemas y esa secuencia decrece hasta el tamaño de los casos base y alcanza alguno de ellos. Veamos esto en el problema de la Potencia Entera: Casos base: 1, Casos recursivos o, si n es par o, si n es impar y / representa división entera

21 3. Complejidad de los algoritmos de Divide y Vencerás y Tiempo de Ejecución Órdenes de Complejidad y recurrencias Como vimos en capítulos anteriores una vez diseñado un algoritmo, demostrado que acaba y que cumple con la especificación (en el sentido de que hace el trabajo para el que fue pensado) tenemos que estudiar su comportamiento en cuanto al tiempo de ejecución. En general estamos interesados en el tiempo de ejecución como una función del tamaño n del problema cuando el tamaño es grande. Sea T(n) la función que nos da el tiempo de ejecución en función del tamaño. Sólo estamos interesados en los aspectos cualitativos de T(n). Es decir en su comportamiento para valores grandes de n. Según su comportamiento para grandes valores de n las funciones T(n) las clasificamos en órdenes de complejidad. Cada orden de complejidad es un conjunto de funciones con comportamiento equivalente para grandes valores de n. Los órdenes de complejidad los definimos con las notaciones: O(g(n)) (cota superior), Θ (g(n)) (orden exacto), Ω (g(n)) (cota inferior). Una función f(n) es de complejidad O(g(n)), Θ (g(n)), Ω (g(n)), respectivamente si: lim Θ lim, 0 Ω lim 0 La notación O(g(n)) define un conjunto de funciones similares a g(n) en su comportamiento para grandes valores de n. En concreto son las funciones menores o iguales a g(n). En el sentido de que el lim es finito pudiendo ser cero. Por eso se le llama cota superior en el sentido de que g(n) es mayor o igual que todas las funciones O(g(n)). La notación Θ(g(n)) define un conjunto de funciones similares a g(n) en su comportamiento para grandes valores de n. En concreto son las funciones iguales a g(n). En el sentido de que el lim es finito y mayor que cero. Se le llama orden exacto en el sentido de que g(n) es igual a todas las funciones Θ(g(n)). La notación Ω(g(n)) define un conjunto de funciones similares a g(n) en su comportamiento para grandes valores de n. En concreto son las funciones mayores o iguales a g(n). En el sentido de que el lim es infinito o finito mayor que cero. Por eso se le llama cota inferior en el sentido de que g(n) es menor o igual que todas las funciones Ω(g(n)). Para indicar que una función es de un orden de complejidad dado se indica indistintamente como. Igualmente con las otras notaciones Θ, Ω. Para calcular la complejidad de algoritmos recursivos es necesario plantear ecuaciones de recurrencia que relacionan la complejidad del problema con la de los subproblemas y la de la

22 obtención de los subproblemas y la combinación de las soluciones. Usualmente aparecen recurrencias lineales de la forma: 1 Donde los, son números reales, con los todos distintos, y polinomios de orden en. La ecuación se denomina homogénea si los, son todos iguales a cero. La solución de la ecuación es: Donde son las raíces distintas, cada una de multiplicidad, de la denominada ecuación característica: Ejemplo: Sea recurrencia: Tenemos 1, 1, 1, 2, 0 por lo que la ecuación característica es: Y por lo tanto la solución es Θ2 ya que: Θ2 Ejemplo: El problema de Fibonacci es, como hemos visto, 1 2. El tiempo de ejecución,, verifica la ecuación de recurrencia 1 2 cuya ecuación característica es Sus raíces son 1,618, 0,618, 1. Luego c φ c φ c Θφ. Puesto que 1, 1. Un caso particular de este tipo de ecuaciones que tiene mucha utilidad es: Con Θn, cuya solución es: Θn, si a 1 Θn, si a 1 Θa /, si a 1

23 Complejidad de los problemas de Divide y Vencerás sin Memoria Los problemas que se resuelven con la técnica de Divide y Vencerás dan lugar a un tipo particular de recurrencias cuya solución es conveniente conocer. Como vimos anteriormente un problema, que se resuelve por la técnica de Divide Y Vencerás, adopta la forma:,,,,, Donde X representa el problema de tamaño n, los subproblemas de tamaño con, c la función que combina las soluciones de los problemas y la solución del caso base de los que puede haber más de uno. El tiempo de ejecución,, para este tipo de problemas verifica la recurrencia: Donde, son, respectivamente, los tiempos para calcular los sub-problemas y para combinar las soluciones. Suponiendo que un problema de tamaño n se divide en a subproblemas, todos del mismo tamaño n/b, y que el coste de dividir el problema en subproblemas más el coste de combinar las soluciones es g(n) entonces la ecuación de recurrencia será para los casos recursivos ( :,, 1, 1 La solución de esa recurrencia viene dada por el denominado Teorema Maestro (Master Theorem) cuya demostración puede verse en la literatura: Θ,, Θ Θ,, O Θ,, Ω, lim 1 Veamos algunos ejemplos: Tenemos: a = 2, b = 2, k = 1, r = 0, Θ entonces Θ log Tenemos: a = 8, b = 2, k = 2, O entonces Θ 2. Tenemos: a = 2, b = 2, k = 2, Ω entonces Ejemplo Θ. Porque vemos que se cumple lim 1.

24 El problema de la Potencia Entera, según la Ficha 3, puede expresarse como pt(n)=pt(n/2)^2*(espar(n)? 1: a). El tiempo obedece a la recurrencia. Aquí 1, 2, 0, 0,. Es el caso uno anterior luego log. Una recurrencia algo más general, que parece en los problemas de Divide y Vencerás con subproblemas no iguales en tamaño, es: Con las condiciones adicionales: 0, 1, La solución es: Θ 1 donde p es la solución de 1 Como vemos las funciones h i no aparecen en la solución. Su aparición en la recurrencia son requisitos técnicos que permiten ignorar detalles en las operaciones enteras que puedan aparecer. Así por ejemplo la solución de 2 tiene la misma complejidad que /2 donde representa la división entera y / la división real. Esto es debido a que n b = n/b+(n b-n/b) y donde n b-n/b, que es un factor pequeño, hace el papel de h. Veamos un ejemplo. Sea la recurrencia. La solución es Θ log puesto que p = 2 es la solución de 1, ln, 1 ln n log. Complejidad de los problemas de Divide y Vencerás con Memoria Como vimos arriba un problema, que se resuelve por la técnica de Divide Y Vencerás, adopta la forma:,,,, Si se usa memoria la recurrencia asociada es diferente al caso de no usar memoria. Sea, como antes, n el tamaño de X y sea g(n) el tiempo necesario para calcular los sub-problemas más el tiempo de para combinar las soluciones. Por comodidad asociemos un índice a cada uno de los problemas del conjunto de problemas considerado. El índice está compuesto con por conjunto de parámetros que identifican el problema de manera única: las que denominados propiedades individuales del problema. Así a los problemas,,,, les asociamos los índices,,,,. Sea el tamaño del problema de índice i. Para resolver un problema de índice i debemos resolver un subconjunto de problemas. Sea el conjunto formado por los

25 índices del subconjunto de problemas que hay que resolver para calcular la solución de. Entonces tiempo de ejecución verifica: Esto es debido a que, supuesto calculados los sub-problemas, el tiempo para calcular un problema de índice i es. Luego el tiempo necesario para calcular un problema es la suma de lo que se requiere para cada uno de los sub-problemas que es necesario resolver (aquellos cuyos índices forman el conjunto ). Un caso particular, muy usado, se presenta cuando. Entonces la fórmula anterior queda: 1 Θ Es decir, en este caso muy general, el tiempo de ejecución es proporcional al número de problemas que es necesario resolver. Ejemplos En el problema de Fibonacci el índice de cada problema puede ser su propiedad N y g(n) = k. Podemos comprobar que en este caso 0,1,2,,. Luego la complejidad del problema de Fibonacci resuelto con memoria es. En el problema de la Potencia Entera el índice de cada problema puede ser su propiedad Exponente y, de nuevo, g(n) = k. Cuando resolvemos un problema, de tamaño n, por Reducción sin Memoria, según se indica en la Ficha 3, se verifica log 1. Puesto que la secuencia,,,,1 tiene de longitud log 1. Por lo tanto la complejidad del Potencia Entera con Memoria es log. El hecho de que la secuencia,,,,1 tenga longitud log 1 puede verse fácilmente si asumimos que n es una potencia de 2 de la forma 2, log. En este caso la secuencia puede ser escrita 2, 2, 2,, 2 que tiene evidentemente la longitud indicada. El razonamiento se puede extender, pero no lo haremos aquí, para valores de n que no son potencias de 2. Estas ideas nos permiten decidir cuándo usar Divide y Vencerás con y sin Memoria. Sólo usaremos la Memoria cuando la complejidad del problema se reduzca (caso del problema de Fibonacci). Si la complejidad es la misma (caso del problema de la Potencia Entera) nos usaremos Memoria. Las razones para que la complejidad sea distinta (usando memoria y sin usarla) es la aparición de subproblemas repetidos al resolver un problema. Esto ocurre en el problema de Fibonacci y no ocurre en el Problema de la Potencia Entera. Por lo tanto un criterio directo para decidir si usar memoria o no es verificar si aparecen subproblemas repetidos o no. Cálculo numérico de recurrencias

26 En algunos casos nos podemos encontrar con recurrencias que no se pueden encajar en los patrones anteriores. Es necesario, en este caso, una solución numérica de la misma. Es el caso de la recurrencia que aparece si queremos calcular la complejidad del caso medio cuando escogemos aleatoriamente el tamaño de los sub-problemas de un problema de tamaño n. Si los sub-problemas pueden tomar los tamaños i y n-i-1, para los posibles valores i, y consideramos igualmente probables entonces la recurrencia es: 1 1 Con 1 1, 0 0 y la probabilidad del caso i en un problema de tamaño n. Usualmente asumiremos la distribución uniforme de los casos y por lo tanto, para valores grandes de n, 1. La recurrencia puede resolverse con las técnicas de Divide y Vencerás con memoria vistas anteriormente tal como se describe en la Ficha 7. La complejidad de T(n) la encontraremos mediante un ajuste. Ficha 7 Problema de Recurrencia del Caso Medio Técnica: Divide y Vencerás si Memoria Representación: Cada problema un conjunto de parámetros Tamaño: N Propiedades Individuales N, Integer no negativo , 0 0 Incluimos un detalle de la clase que implementa las ideas de la Ficha anterior:... private Double dyv(integer n){ Double s; if(map.containskey(n)) { s = map.get(n); else if(escasobase(n)){ s = getsolucioncasobase(n); map.put(n, s); else { s = 0.; for(int i =0; i<n;i++){ Double s1 = dyv(i); map.put(i, s1); Double s2 = dyv(n-i-1); map.put(n-i-1, s2);

27 ... s = s+s1+s2; s = n-1+s/n; map.put(n, s); return s; Tras resolver numéricamente la recurrencia representamos los valores obtenidos para T(n). En el gráfico vemos que es casi una recta pero al intentar ajustarla obtenemos un T(n) frente a n y = 16,383x -7446,5 R² = 0,9987 T(n) frente a n Lineal (T(n) frente a n) Tal como vemos en la figura anterior el ajuste de T(n), aunque cercano, no es exactamente una recta. Representamos ahora T(n) frente a n*ln(n). Vemos que el ajuste es perfecto con 1.

28 T(n) frente a n*ln(n) y = 1,7344x -987,83 R² = 1 T(n) frente a n*ln(n) Lineal (T(n) frente a n*ln(n)) Concluimos que la solución de la recurrencia anterior es pueden usarse para otras recurrencias complejas.. Estas ideas Cálculo del umbral Una cuestión importante en la técnica de Divide y Vencerás es la definiciónn del tamaño que separa los casos base de los casos recursivos. Llamaremos umbral a ese tamaño. Un problema se considera simple (caso base) cuando su tamaño es menor o igual que el umbral elegido. Veamos como calcularlo. El tiempo de ejecución del algoritmo dependerá del umbral seleccionado. Sea un algoritmo del tipo Divide y Vencerás donde el coste de la solución directa (caso base) sea h(n) entonces el tiempo de ejecución verifica: El umbral óptimo se encontrará en la intersección entre el tiempo de ejecución del caso base (línea roja) y el del caso recursivo (línea azul): Sustituyendo es: en e igualando a la ecuación para el umbral

29 Ejemplo. Sea el algoritmo con la ecuación de recurrencia dada por: El umbral verifica 3 16, tamaño del umbral. 16, 16, 8 que es el Medición del tiempo de ejecución y otros parámetros de un algoritmo Junto al cálculo teórico de la complejidad es conveniente medir para implementación concreta el tiempo de ejecución y otros parámetros relevantes. Para ello diseñamos una clase denominada Metricas con ese objetivo. El tipo Algoritmo, que hemos visto arriba, dispone de una propiedad Metricas que nos permite medir sus parámetros particulares. public class Metricas { int getnumerodellamadasrecursivas() { int getnumerodeusosdelamemoria(){ long gettiempodeejecucion(){ int getnumerodecasosbase(){ long getnumerodeproblemas(){... La clase Metricas está diseñada para medir, de un algoritmo dado, las siguientes propiedades, a las que añadiéremos otras más adelante. NumeroDeLLamadasRecursivas: Número de llamadas recursivas. NumeroDeUsosDeLaMemoria: Número de veces que se accede a TiempoDeEjecucion: Tiempo de ejecución en nanosegundos. NumeroDeCasosBase: Número de casos base resueltos. NumeroDeProblemas: Número de problemas distintos resueltos. En el caso del problema de Fibonacci, resuelto por la técnica de Divide y Vencerás con Memoria y N = 1000, obtenemos los siguientes parámetros: Número de Llamadas Recursivas = 1999 Numero de Usos de la Memoria = 998 Tiempo de Ejecucion en nanoseg= 15 Número de Casos Base = 2 Número de Problemas = 1001

Diseño y Análisis de Algoritmos

Diseño y Análisis de Algoritmos 1. Recursividad 2. "Dividir para Reinar" 3. Recursividad y Tabulación (Programación Dinámica) 4. Métodos Matemáticos Funciones discretas Notación O Ecuaciones de recurrencia 5. Casos de Estudio Breve descripción

Más detalles

Unidad Didáctica 3. Tipos genéricos. Fundamentos de Programación Departamento de Lenguajes y Sistemas Informáticos

Unidad Didáctica 3. Tipos genéricos. Fundamentos de Programación Departamento de Lenguajes y Sistemas Informáticos Unidad Didáctica 3 Tipos genéricos Fundamentos de Programación Departamento de Lenguajes y Sistemas Informáticos Definición de tipo genérico Hablamos de un tipo genérico cuando el tipo en cuestión depende

Más detalles

Multiplicación de matrices simétricas

Multiplicación de matrices simétricas Multiplicación de matrices simétricas La traspuesta de una matriz A n n es definida como una matriz A T n n tal que A T [i, j] =A[j, i] paracadai, j 2{1,...,n} Además, una matriz A es simétrica si A =

Más detalles

Análisis de Algoritmos

Análisis de Algoritmos Análisis de Algoritmos Amalia Duch Barcelona, marzo de 2007 Índice 1. Costes en tiempo y en espacio 1 2. Coste en los casos mejor, promedio y peor 3 3. Notación asintótica 4 4. Coste de los algoritmos

Más detalles

Para las ecuaciones diferenciales ordinarias no lineales no existen métodos generales.

Para las ecuaciones diferenciales ordinarias no lineales no existen métodos generales. Unidad IV: Sistemas continuos (continuación) Objetivo específico: Entender ampliamente el fenómeno del comportamiento de los modelos matemáticos para la resolución de problemas enfocados a las ecuaciones

Más detalles

Análisis y Diseño de Algoritmos

Análisis y Diseño de Algoritmos Análisis y Diseño de Algoritmos Notación Asintótica DR. JESÚS A. GONZÁLEZ BERNAL CIENCIAS COMPUTACIONALES INAOE Introducción Por qué el análisis de algoritmos? Determinar tiempos de respuesta (runtime)

Más detalles

Estructuras de Datos y de la Información Ingeniería Técnica en Informática de Gestión. Curso 2007/2008 Ejercicios del Tema 2

Estructuras de Datos y de la Información Ingeniería Técnica en Informática de Gestión. Curso 2007/2008 Ejercicios del Tema 2 Estructuras de Datos y de la Información Ingeniería Técnica en Informática de Gestión. Curso 2007/2008 Ejercicios del Tema 2 Diseño de algoritmos recursivos 1. Dado un vector de enteros de longitud N,

Más detalles

Análisis y Diseño de Algoritmos

Análisis y Diseño de Algoritmos Análisis y Diseño de Algoritmos Recurrencias DR. JESÚS A. GONZÁLEZ BERNAL CIENCIAS COMPUTACIONALES INAOE Introducción 2 Cuando un algoritmo se llama a sí mismo Su tiempo de ejecución se puede describir

Más detalles

Tema: Programación Dinámica.

Tema: Programación Dinámica. Programación IV. Guía 11 1 Facultad: Ingeniería Escuela: Computación Asignatura: Programación IV Tema: Programación Dinámica. Objetivos Específicos Definir el concepto de programación dinámica. Interpretar

Más detalles

Estructuras de control selectivas

Estructuras de control selectivas Práctica 3 Estructuras de control selectivas Fundamentos de Programación Departamento de Lenguajes y Sistemas Informáticos Versión 2.0.2 Concepto de sentencia y estructura de control El cuerpo de los métodos

Más detalles

Programación orientada a objetos

Programación orientada a objetos Repaso Programación orientada a objetos Curso INEM. Programación en Java Santiago Muelas Pascual smuelas@fi.upm.es! Herencia! Superclase/subclase! super! Modificador protected! Redefinicion de métodos!

Más detalles

Tema: Programación Dinámica.

Tema: Programación Dinámica. Programación IV. Guía No. 12 1 Facultad: Ingeniería Escuela: Computación Asignatura: Programación IV Tema: Programación Dinámica. Objetivos Específicos Definir el concepto de programación dinámica. Interpretar

Más detalles

un conjunto cuyos elementos denominaremos vectores y denotaremos por es un espacio vectorial si verifica las siguientes propiedades:

un conjunto cuyos elementos denominaremos vectores y denotaremos por es un espacio vectorial si verifica las siguientes propiedades: CAPÍTULO 2: ESPACIOS VECTORIALES 2.1- Definición y propiedades. 2.1.1-Definición: espacio vectorial. Sea un cuerpo conmutativo a cuyos elementos denominaremos escalares o números. No es necesario preocuparse

Más detalles

Unidad 2: Ecuaciones, inecuaciones y sistemas.

Unidad 2: Ecuaciones, inecuaciones y sistemas. Unidad 2: Ecuaciones, inecuaciones y sistemas 1 Unidad 2: Ecuaciones, inecuaciones y sistemas. 1.- Factorización de polinomios. M. C. D y m.c.m de polinomios. Un número a es raíz de un polinomio es 0.

Más detalles

Análisis de algoritmos

Análisis de algoritmos Tema 08: Divide y vencerás (DyV) M. en C. Edgardo Adrián Franco Martínez http://www.eafranco.com edfrancom@ipn.mx @edfrancom edgardoadrianfrancom 1 Contenido Introducción Divide y vencerás Observaciones

Más detalles

La eficiencia de los programas

La eficiencia de los programas La eficiencia de los programas Jordi Linares Pellicer EPSA-DSIC Índice General 1 Introducción... 2 2 El coste temporal y espacial de los programas... 2 2.1 El coste temporal medido en función de tiempos

Más detalles

259. El número de combinaciones de m objetos entre un conjunto de n, denotado por n, para n 1 y 0 m n, se puede definir recursivamente por: m

259. El número de combinaciones de m objetos entre un conjunto de n, denotado por n, para n 1 y 0 m n, se puede definir recursivamente por: m 258. Aplicar el algoritmo de programación dinámica para el problema del cambio de monedas sobre el siguiente ejemplo: n = 3, P = 9, c = (1, 3, 4). Qué ocurre si multiplicamos P y c por un valor constante,

Más detalles

FUNCIONES REALES DE UNA VARIABLE CONCEPTOS FUNDAMENTALES

FUNCIONES REALES DE UNA VARIABLE CONCEPTOS FUNDAMENTALES FUNCIONES REALES DE UNA VARIABLE Índice Presentación... 3 Conjunto de los números reales... 4 Los intervalos... 6 Las potencias... 7 Los polinomios... 8 La factorización de polinomios (I)... 9 La factorización

Más detalles

UNIDAD 1 NUMEROS COMPLEJOS

UNIDAD 1 NUMEROS COMPLEJOS UNIDAD 1 NUMEROS COMPLEJOS El conjunto de los números complejos fue creado para poder resolver algunos problemas matemáticos que no tienen solución dentro del conjunto de los números reales. Por ejemplo

Más detalles

Fundamentos matemáticos. Tema 1 Números reales. Polinomios

Fundamentos matemáticos. Tema 1 Números reales. Polinomios Grado en Ingeniería agrícola y del medio rural Tema 1 Números reales. Polinomios José Barrios García Departamento de Análisis Matemático Universidad de La Laguna jbarrios@ull.es 2017 Licencia Creative

Más detalles

Esquema de Dividir y Vencer

Esquema de Dividir y Vencer Esquema de Dividir y Vencer Amalia Duch Barcelona, marzo de 2006 Índice 1. Esquema general 1 2. Búsqueda binaria (binary search) 2 3. Ordenación por fusión (merge sort) 2 4. Ordenación rápida (quick sort)

Más detalles

Complejidad computacional. Algoritmos y Estructuras de Datos I. Complejidad computacional. Notación O grande

Complejidad computacional. Algoritmos y Estructuras de Datos I. Complejidad computacional. Notación O grande Complejidad computacional Algoritmos y Estructuras de Datos I Segundo cuatrimestre de 2014 Departamento de Computación - FCEyN - UBA Algoritmos - clase 10 Introducción a la complejidad computacional y

Más detalles

Tema 2. Divide y vencerás.

Tema 2. Divide y vencerás. Programa de teoría Parte I. Estructuras de Datos. 1. Abstracciones especificaciones. 2. Conjuntos diccionarios. 3. Representación de conjuntos mediante árboles. 4. Grafos. Parte II. Algorítmica. 1. Análisis

Más detalles

TEMA 3. Algebra. Teoría. Matemáticas

TEMA 3. Algebra. Teoría. Matemáticas 1 1 Las expresiones algebraicas Las expresiones algebraicas son operaciones aritméticas, de suma, resta, multiplicación y división, en las que se combinan letras y números. Para entenderlo mejor, vamos

Más detalles

Programación II Recursividad Dr. Mario Rossainz López

Programación II Recursividad Dr. Mario Rossainz López 5. RECURSIVIDAD 5.1. Introducción La recursividad es una técnica en la que una función o método se hace llamadas a sí misma en el proceso de la realización de sus tareas. La recursividad da al programador

Más detalles

DESIGUALDADES. AXIOMA 1.- Tricotomía de los números reales. Si a y b son números reales entonces se cumple una y solo una de las relaciones

DESIGUALDADES. AXIOMA 1.- Tricotomía de los números reales. Si a y b son números reales entonces se cumple una y solo una de las relaciones DESIGUALDADES 4.1.- AXIOMAS DE ORDEN. Cualquier conjunto o Campo de números que satisface los siguientes 4 Axiomas se dice que es un conjunto de números ORDENADO. El conjunto o Campo de los números reales

Más detalles

Examen Teórico Convocatoria de Junio de 2012

Examen Teórico Convocatoria de Junio de 2012 Examen Teórico Convocatoria de Junio de 2012 Nombre: DNI: Titulación: 1. Sobre el control de errores en Java: a) El siguiente método contiene un error de compilación debido al uso de excepciones. Explica

Más detalles

SESIÓN N 07 III UNIDAD RELACIONES Y FUNCIONES

SESIÓN N 07 III UNIDAD RELACIONES Y FUNCIONES SESIÓN N 07 III UNIDAD RELACIONES Y FUNCIONES RELACIONES BINARIAS PAR ORDENADO Es un arreglo de dos elementos que tienen un orden determinado donde a es llamada al primera componente y b es llamada la

Más detalles

NOTACIÓN O GRANDE. El análisis de algoritmos estima el consumo de recursos de un algoritmo.

NOTACIÓN O GRANDE. El análisis de algoritmos estima el consumo de recursos de un algoritmo. NOTACIÓN O GRANDE El análisis de algoritmos estima el consumo de recursos de un algoritmo. Esto nos permite comparar los costos relativos de dos o más algoritmos para resolver el mismo problema. El análisis

Más detalles

RESUMEN DE FUNCIONES. MATEMÁTICAS APLICADAS A LAS CIENCIAS SOCIALES I

RESUMEN DE FUNCIONES. MATEMÁTICAS APLICADAS A LAS CIENCIAS SOCIALES I RESUMEN DE FUNCIONES. MATEMÁTICAS APLICADAS A LAS CIENCIAS SOCIALES I 1.- INTRODUCCIÓN Definición: Una función real de variable real es una aplicación entre dos subconjuntos de los números reales, de modo

Más detalles

Introducción al análisis de algoritmos

Introducción al análisis de algoritmos Estructura de Datos y Algoritmos Introducción al análisis de algoritmos 1. Eficiencia en tiempo de Ejecución Cuando resolvemos un problema nos vemos frecuentemente enfrentando una elección de programas,

Más detalles

Complejidad de algoritmos recursivos

Complejidad de algoritmos recursivos Tema 3. Complejidad de algoritmos recursivos 1. INTRODUCCIÓN... 1 CLASIFICACIÓN DE FUNCIONES RECURSIVAS... 1 DISEÑO DE FUNCIONES RECURSIVAS... 2 2. VENTAJAS E INCONVENIENTES DE LA RECURSIVIDAD... 4 3.

Más detalles

Ejercicio 1 (proyecto prlistas, paquete listas)

Ejercicio 1 (proyecto prlistas, paquete listas) PRÁCTICA 3 Curso 2004-05 En esta práctica construiremos y usaremos dos paquetes: el primero, listas, que implementa listas genéricas y el segundo, colas, que implementa colas y colas de prioridades genéricas.

Más detalles

Tema 6 Patrones de Diseño. Programación Orientada a Objetos Curso 2010/2011

Tema 6 Patrones de Diseño. Programación Orientada a Objetos Curso 2010/2011 Tema 6 Patrones de Diseño Programación Orientada a Objetos Curso 2010/2011 Contenido Introducción a los patrones de diseño. Patrón del Método plantilla. Patrón Composición. Patrón Estrategia. Clases anónimas

Más detalles

Algoritmos y Estructuras de Datos Iteradores. Guillermo Román Díez

Algoritmos y Estructuras de Datos Iteradores. Guillermo Román Díez Algoritmos y Estructuras de Datos Iteradores Guillermo Román Díez groman@fi.upm.es Universidad Politécnica de Madrid Curso 2015-2016 Guillermo Román, UPM AED: Introducción 1/26 Iteradores Es muy común

Más detalles

Lección 3: Orden e intervalos

Lección 3: Orden e intervalos GUÍA DE MATEMÁTICAS III Lección 3: Orden e intervalos La recta real En la lección anterior presentamos los números reales y vimos que éstos están constituidos por los números racionales y los irracionales.

Más detalles

Algoritmos de Búsqueda

Algoritmos de Búsqueda Introducción a la Computación Algoritmos de Búsqueda Esteban E. Mocskos (emocskos@dc.uba.ar) Facultad de Ciencias Exactas y Naturales, UBA CONICET 11/10/2017 E. Mocskos (UBA CONICET) Algoritmos de Búsqueda

Más detalles

6 Vectores. Dependencia e independencia lineal.

6 Vectores. Dependencia e independencia lineal. 6 Vectores. Dependencia e independencia lineal. Introducción Hay fenómenos reales que se pueden representar adecuadamente mediante un número con su adecuada unidad de medida. Sin embargo para representar

Más detalles

Tema 5- Diseño Recursivo y. Objetivos Principales. Bibliografía Básica

Tema 5- Diseño Recursivo y. Objetivos Principales. Bibliografía Básica Tema 5- Diseño Recursivo y Eficiente Tema 5- Diseño Recursivo y Eficiente Germán Moltó Escuela Técnica Superior de Ingeniería Informática Universidad Politécnica de Valencia Índice general: 1. Introducción

Más detalles

Análisis y Diseño de Algoritmos

Análisis y Diseño de Algoritmos Análisis y Diseño de Algoritmos Introducción: El Rol de los Algoritmos en Computación DR. JESÚS A. GONZÁLEZ BERNAL CIENCIAS COMPUTACIONALES INAOE Temario 2 1. Introducción 2. Notación Asintótica 3. Recurrencias

Más detalles

Apuntes de Teórico PROGRAMACIÓN 3

Apuntes de Teórico PROGRAMACIÓN 3 Apuntes de Teórico PROGRAACIÓN Programación Dinámica Versión. Índice Índice... Introducción... Principio de optimalidad...5 Ejemplo: Camino de menor costo...6 Ejemplo: problema de la mochila...6 Aplicación

Más detalles

Tema 7: Geometría Analítica. Rectas.

Tema 7: Geometría Analítica. Rectas. Tema 7: Geometría Analítica. Rectas. En este tema nos centraremos en estudiar la geometría en el plano, así como los elementos que en este aparecen como son los puntos, segmentos, vectores y rectas. Estudiaremos

Más detalles

Concurso: Cuánto sabes de JAVA?

Concurso: Cuánto sabes de JAVA? Concurso: Cuánto sabes de JAVA? Motivación: o Para cambiar el ritmo de las jornadas y que no todas las actividades sean charlas o Recordar conocimientos y aprender algo nuevo. o Las preguntas pueden ayudarnos

Más detalles

Examen escrito de Programación 1

Examen escrito de Programación 1 Examen escrito de Programación 1 Escuela de Ingeniería y Arquitectura Departamento de Informática e Ingeniería de Sistemas 31 de agosto de 2012 Disponer sobre la mesa en lugar visible un documento de identificación

Más detalles

Tema 3 Algebra. Ecuaciones. Sistemas de ecuaciones: Inecuaciones Índice

Tema 3 Algebra. Ecuaciones. Sistemas de ecuaciones: Inecuaciones Índice Tema 3 Algebra. Ecuaciones. Sistemas de ecuaciones: Inecuaciones Índice 1. ECUACIONES... 2 1.1. Ecuaciones de primer grado... 2 1.2. Ecuaciones de segundo grado... 3 1.2.1. Ecuación de segundo grado completa...

Más detalles

Manos a la obra: Recursión, división y listas

Manos a la obra: Recursión, división y listas Manos a la obra: Recursión, división y listas Taller de Álgebra I Cuatrimestre de verano de 2015 Calentando motores La clase pasada vimos ejemplos de definiciones recursivas. Hoy vamos a continuar con

Más detalles

1.- DOMINIO DE LA FUNCIÓN

1.- DOMINIO DE LA FUNCIÓN En este resumen vamos a tratar los puntos que necesitamos para poder representar gráficamente una función. Empezamos viendo la información que podemos obtener de la expresión matemática de la función.

Más detalles

Introducción al Análisis del Coste de Algoritmos

Introducción al Análisis del Coste de Algoritmos 1/11 Introducción al Análisis del Coste de Algoritmos Josefina Sierra Santibáñez 7 de noviembre de 2017 2/11 Eficiencia de un Algoritmo Analizar un algoritmo significa, en el contexto de este curso, predecir

Más detalles

Ejemplo: El problema de la mochila. Algoritmos golosos. Algoritmos y Estructuras de Datos III. Segundo cuatrimestre 2013

Ejemplo: El problema de la mochila. Algoritmos golosos. Algoritmos y Estructuras de Datos III. Segundo cuatrimestre 2013 Técnicas de diseño de algoritmos Algoritmos y Estructuras de Datos III Segundo cuatrimestre 2013 Técnicas de diseño de algoritmos Algoritmos golosos Backtracking (búsqueda con retroceso) Divide and conquer

Más detalles

Ecuaciones e inecuaciones. Sistemas de ecuaciones e inecuaciones

Ecuaciones e inecuaciones. Sistemas de ecuaciones e inecuaciones de ecuaciones e inecuaciones Álvarez S., Caballero M.V. y Sánchez M. a M. salvarez@um.es, m.victori@um.es, marvega@um.es 1 Índice 1. Definiciones 3 2. Herramientas 5 2.1. Factorización de polinomios: Regla

Más detalles

Universidad de Valladolid. Departamento de informática. Campus de Segovia. Estructura de datos Tema 1: Recursividad. Prof. Montserrat Serrano Montero

Universidad de Valladolid. Departamento de informática. Campus de Segovia. Estructura de datos Tema 1: Recursividad. Prof. Montserrat Serrano Montero Universidad de Valladolid Departamento de informática Campus de Segovia Estructura de datos Tema 1: Recursividad Prof. Montserrat Serrano Montero ÍNDICE Conceptos básicos Ejemplos recursivos Recursividad

Más detalles

CURSO CERO DE MATEMATICAS. Apuntes elaborados por Domingo Pestana Galván. y José Manuel Rodríguez García

CURSO CERO DE MATEMATICAS. Apuntes elaborados por Domingo Pestana Galván. y José Manuel Rodríguez García INGENIEROS INDUSTRIALES Y DE TELECOMUNICACIONES CURSO CERO DE MATEMATICAS Apuntes elaborados por Domingo Pestana Galván y José Manuel Rodríguez García UNIVERSIDAD CARLOS III DE MADRID Escuela Politécnica

Más detalles

Sea A el conjunto de alumnos de una clase.

Sea A el conjunto de alumnos de una clase. ANÁLISIS MATEMÁTICO BÁSICO. FUNCIONES DE VARIABLE REAL. Dados dos conjuntos A y B, podemos emparejar los elementos de A con los del conjunto B. Si lo hacemos de modo que para todo elemento a A le asociamos,

Más detalles

4.2. El número de combinaciones de m objetos entre un conjunto de n, denotado por n, para n 1 y 0 m n, se puede definir recursivamente por: m

4.2. El número de combinaciones de m objetos entre un conjunto de n, denotado por n, para n 1 y 0 m n, se puede definir recursivamente por: m 4.1. Aplicar el algoritmo de programación dinámica para el problema del cambio de monedas sobre el siguiente ejemplo: n = 3, P = 9, c = (1, 3, 4). Qué ocurre si multiplicamos P y c por un valor constante,

Más detalles

1. dejar a una lado de la igualdad la expresión que contenga una raíz.

1. dejar a una lado de la igualdad la expresión que contenga una raíz. 1. Resuelve las siguientes ecuaciones reales: Solución x 1 + x = 0 ; 3 x = 3 ; ln(x 1) + 4 = ln 3 Ecuaciones con raíces: No todas las ecuaciones de este tipo son sencillas de resolver, pero podemos intentar

Más detalles

Estructuras Discretas. Conjuntos. Conjuntos & Funciones. Especificación de Conjuntos.

Estructuras Discretas. Conjuntos. Conjuntos & Funciones. Especificación de Conjuntos. Estructuras Discretas Conjuntos Conjuntos & Funciones Claudio Lobos clobos@inf.utfsm.cl niversidad Técnica Federico Santa María Estructuras Discretas INF 152 Definición: conjunto n conjunto es una colección

Más detalles

TEMA 6: GEOMETRÍA ANALÍTICA EN EL PLANO

TEMA 6: GEOMETRÍA ANALÍTICA EN EL PLANO Alonso Fernández Galián Tema 6: Geometría analítica en el plano TEMA 6: GEOMETRÍA ANALÍTICA EN EL PLANO La geometría analítica es el estudio de objetos geométricos (rectas, circunferencias, ) por medio

Más detalles

Diagonalización de matrices

Diagonalización de matrices 7 Diagonalización de matrices 7.1. Matrices diagonalizables Existen diversos procesos en los que el estado en cada uno de sus pasos se puede representar por un determinado vector y en los que, además,

Más detalles

Tema 1. Espacios Vectoriales Definición de Espacio Vectorial

Tema 1. Espacios Vectoriales Definición de Espacio Vectorial Tema 1 Espacios Vectoriales. 1.1. Definición de Espacio Vectorial Notas 1.1.1. Denotaremos por N, Z, Q, R, C, a los conjuntos de los números Naturales, Enteros, Racionales, Reales y Complejos, respectivamente.

Más detalles

REESCRIBIR ECUACIONES CON MÚLTIPLES VARIABLES Ejemplo 2. Ejemplo 4

REESCRIBIR ECUACIONES CON MÚLTIPLES VARIABLES Ejemplo 2. Ejemplo 4 REESCRIBIR ECUACIONES CON MÚLTIPLES VARIABLES 6.1.1 Para reescribir una ecuación con más de una variable debes usar el mismo proceso que para resolver una ecuación de una variable. El resultado final suele

Más detalles

Bloque 1. Conceptos y técnicas básicas en programación

Bloque 1. Conceptos y técnicas básicas en programación Bloque 1. Conceptos y técnicas básicas en programación 1. Introducción 2. Datos y expresiones. Especificación de algoritmos 3. Estructuras algorítmicas básicas 4. Iteración y recursión 5. Iteración y recursión

Más detalles

Ecuaciones e inecuaciones. Sistemas de ecuaciones e inecuaciones

Ecuaciones e inecuaciones. Sistemas de ecuaciones e inecuaciones Ecuaciones e inecuaciones. Sistemas de ecuaciones e inecuaciones Álvarez S., Caballero M.V. y Sánchez M. a M. salvarez@um.es, m.victori@um.es, marvega@um.es Índice 1. Herramientas 6 1.1. Factorización

Más detalles

Estructura de datos y de la información Boletín de problemas - Tema 9

Estructura de datos y de la información Boletín de problemas - Tema 9 Estructura de datos y de la información Boletín de problemas - Tema 9 1. Dada la siguiente función recursiva: void F(char c) { if (( A

Más detalles

Tema 5: Funciones. Límites de funciones

Tema 5: Funciones. Límites de funciones Tema 5: Funciones. Límites de funciones 1. Concepto de función Una aplicación entre dos conjuntos y es una transformación que asocia a cada elemento del conjunto un único elemento del conjunto. Una función

Más detalles

Un tercer ejemplo: verificación de primalidad

Un tercer ejemplo: verificación de primalidad Un tercer ejemplo: verificación de primalidad Vamos a ver un algoritmo aleatorizado para verificar si un número es primo. I Este algoritmo es más eficiente que los algoritmos sin componentes aleatorias

Más detalles

Tema 9. Recursividad

Tema 9. Recursividad Tema 9. Recursividad http://aulavirtual.uji.es José M. Badía, Begoña Martínez, Antonio Morales y José M. Sanchiz {badia, bmartine, morales, sanchiz@icc.uji.es Estructuras de datos y de la información Universitat

Más detalles

PENDIENTES DE MATEMÁTICAS DE 3º ESO (CURSO )

PENDIENTES DE MATEMÁTICAS DE 3º ESO (CURSO ) PENDIENTES DE MATEMÁTICAS DE 3º ESO (CURSO 2015-2016) CRITERIOS E INDICADORES Se detallan a continuación los criterios de evaluación junto con sus indicadores de contenidos asociados. Criterio 1: Identificar

Más detalles

σ * (.a 1 a 2... a t ) β * β e

σ * (.a 1 a 2... a t ) β * β e . ERRORES DE REDONDEO Y ESTABILIDAD Qué es un método numérico? Un método numérico es un procedimiento mediante el cual se obtiene, casi siempre de manera aproximada, la solución de ciertos problemas realizando

Más detalles

Algoritmos Iterativos de Búsqueda y Ordenación y sus tiempos

Algoritmos Iterativos de Búsqueda y Ordenación y sus tiempos Estructura de Datos y Algoritmos Algoritmos Iterativos de Búsqueda y Ordenación y sus tiempos 1. Algorimos de ordenación Discutiremos el problema de ordenar un array de elementos. A los efectos de simplificar

Más detalles

lasmatemáticas.eu Pedro Castro Ortega materiales de matemáticas Expresiones algebraicas. Ecuaciones de primer grado

lasmatemáticas.eu Pedro Castro Ortega materiales de matemáticas Expresiones algebraicas. Ecuaciones de primer grado lasmatemáticaseu Pedro Castro Ortega Epresiones algebraicas Ecuaciones de primer grado 1 Epresiones algebraicas 11 Definición de epresión algebraica Una epresión algebraica es un conjunto de números letras

Más detalles

Álgebra Lineal. Tema 6. Transformaciones lineales y matrices

Álgebra Lineal. Tema 6. Transformaciones lineales y matrices Álgebra Lineal Tema 6. Transformaciones lineales y matrices Grado en Ingeniería Informática Doble Grado en Ingeniería Informática y Administración de Empresas AUTORES: J. S ALAS, A. T ORRENTE Y E.J.S.

Más detalles

1. Números naturales y sistema de numeración decimal

1. Números naturales y sistema de numeración decimal 1. Números naturales y sistema de numeración decimal Conocer el sistema de numeración decimal y relacionarlo con los números naturales. Representación en la recta real de los mismos. Realizar operaciones

Más detalles

CURSO CERO DE MATEMATICAS. Apuntes elaborados por Domingo Pestana Galván. y José Manuel Rodríguez García

CURSO CERO DE MATEMATICAS. Apuntes elaborados por Domingo Pestana Galván. y José Manuel Rodríguez García INGENIEROS INDUSTRIALES Y DE TELECOMUNICACIONES CURSO CERO DE MATEMATICAS Apuntes elaborados por Domingo Pestana Galván y José Manuel Rodríguez García UNIVERSIDAD CARLOS III DE MADRID Escuela Politécnica

Más detalles

Unidad 1: SISTEMAS DE ECUACIONES. MÉTODO DE GAUSS

Unidad 1: SISTEMAS DE ECUACIONES. MÉTODO DE GAUSS Unidad 1: SISTEMAS DE ECUACIONES. MÉTODO DE GAUSS 1.1.- SISTEMAS DE ECUACIONES LINEALES Ecuación lineal Las ecuaciones siguientes son lineales: 2x 3 = 0; 5x + 4y = 20; 3x + 2y + 6z = 6; 5x 3y + z 5t =

Más detalles

Los errores asociados a todo cálculo numérico tienen su origen en dos grandes factores:

Los errores asociados a todo cálculo numérico tienen su origen en dos grandes factores: Errores El concepto de error es consustancial con el cálculo numérico. En todos los problemas es fundamental hacer un seguimiento de los errores cometidos a fin de poder estimar el grado de aproximación

Más detalles

Notación Asintótica. Programación Avanzada

Notación Asintótica. Programación Avanzada Notación Asintótica Programación Avanzada Orden de crecimiento asintótico Ayuda a: Identificar el comportamiento de un algoritmo en el peor, el mejor o el caso promedio. Tener una idea del comportamiento

Más detalles

Capítulo 4. Inecuaciones. M.Sc. Alcides Astorga M., Lic. Julio Rodríguez S. Instituto Tecnológico de Costa Rica Escuela de Matemática

Capítulo 4. Inecuaciones. M.Sc. Alcides Astorga M., Lic. Julio Rodríguez S. Instituto Tecnológico de Costa Rica Escuela de Matemática 1 Capítulo 4 Inecuaciones M.Sc. Alcides Astorga M., Lic. Julio Rodríguez S. Instituto Tecnológico de Costa Rica Escuela de Matemática Revista digital Matemática, educación e internet (www.cidse.itcr.ac.cr)

Más detalles

IN34A - Optimización

IN34A - Optimización IN34A - Optimización Complejidad Leonardo López H. lelopez@ing.uchile.cl Primavera 2008 1 / 33 Contenidos Problemas y Procedimientos de solución Problemas de optimización v/s problemas de decisión Métodos,

Más detalles

matemáticos, como por ejemplo las cinco operaciones básicas, factorial de un número.

matemáticos, como por ejemplo las cinco operaciones básicas, factorial de un número. Sesión 4: Programar en Scratch soluciones a problemas simples matemáticos, como por ejemplo las cinco operaciones básicas, factorial de un número. Objetivo: Aprender a realizar algoritmos y procedimientos

Más detalles

TEMA 2: ÁLGEBRA 1. TEOREMA DEL RESTO Y APLICACIONES

TEMA 2: ÁLGEBRA 1. TEOREMA DEL RESTO Y APLICACIONES TEMA 2: ÁLGEBRA 1. TEOREMA DEL RESTO Y APLICACIONES Dado un polinomio P(x) y un número real a, el resto de la división de P(x) entre (x a) es P(a) (es decir, el resultado de sustituir el valor de x por

Más detalles

EJERCICIO Y EJEMPLO RESUELTO: USO DE LA INTERFAZ CLONEABLE DE JAVA. MÉTODO CLONE() PARA CLONAR OBJETOS. (CU00912C)

EJERCICIO Y EJEMPLO RESUELTO: USO DE LA INTERFAZ CLONEABLE DE JAVA. MÉTODO CLONE() PARA CLONAR OBJETOS. (CU00912C) APRENDERAPROGRAMAR.COM EJERCICIO Y EJEMPLO RESUELTO: USO DE LA INTERFAZ CLONEABLE DE JAVA. MÉTODO CLONE() PARA CLONAR OBJETOS. (CU00912C) Sección: Cursos Categoría: Lenguaje de programación Java nivel

Más detalles

Entiendo los métodos de Java equals y hashcode

Entiendo los métodos de Java equals y hashcode Todos los días cuando programamos usamos objetos y en muchas ocasiones necesitamos comparar unos con otros. Para ello en muchas ocasiones usamos los métodos de de Java equals y hashcode. Estos métodos

Más detalles

Unidad Didáctica 2. Elementos básicos del lenguaje Java Tipos, declaraciones, expresiones y asignaciones

Unidad Didáctica 2. Elementos básicos del lenguaje Java Tipos, declaraciones, expresiones y asignaciones Unidad Didáctica 2 Elementos básicos del lenguaje Java Tipos, declaraciones, expresiones y asignaciones Fundamentos de Programación Departamento de Lenguajes y Sistemas Informáticos Versión 1.0.3 Índice

Más detalles

Geometría. Facultad de Ciencias Exactas y Naturales Universidad de Buenos Aires. Training Camp 2012

Geometría. Facultad de Ciencias Exactas y Naturales Universidad de Buenos Aires. Training Camp 2012 Geometría Leopoldo Taravilse Francisco Roslán Facultad de Ciencias Exactas y Naturales Universidad de Buenos Aires Training Camp 2012 Leopoldo Taravilse, Francisco Roslán (UBA) Geometría TC 2012 1 / 30

Más detalles

Univ. Nacional de Colombia, Medellín Escuela de Matemáticas Matemáticas Discretas Marzo 8, Soluciones Taller 5

Univ. Nacional de Colombia, Medellín Escuela de Matemáticas Matemáticas Discretas Marzo 8, Soluciones Taller 5 Univ. Nacional de Colombia, Medellín Escuela de Matemáticas Matemáticas Discretas Marzo 8, 00 Soluciones Taller 5. Pruebe por inducción que n 3 = 3 + 3 + 3 3 + + (n ) 3 + n 3 = = ( ) n(n + ) Caso base:

Más detalles

Análisis de algoritmos. Recursividad

Análisis de algoritmos. Recursividad Análisis de algoritmos Recursividad 1 Matrushka La Matrushka es una artesanía tradicional rusa. Es una muñeca de madera que contiene otra muñeca más pequeña dentro de sí. Ésta muñeca, también contiene

Más detalles

2.1 Descripción en espacio de estado de sistemas dinámicos

2.1 Descripción en espacio de estado de sistemas dinámicos 2 Análisis de sistemas lineales 2.1 Descripción en espacio de estado de sistemas dinámicos El objetivo de este capítulo es formular una teoría general de describir los sistemas dinámicos en funcion de

Más detalles

MATEMÁTICAS Versión impresa INECUACIONES

MATEMÁTICAS Versión impresa INECUACIONES MATEMÁTICAS Versión impresa INECUACIONES 1. INTRODUCCIÓN Imaginen que queremos abrir una nueva librería en el centro de la ciudad. Y que tenemos un presupuesto de 800 $ como máximo para comprar los libros.

Más detalles

UNIDAD 1: NÚMEROS RACIONALES OBJETIVOS

UNIDAD 1: NÚMEROS RACIONALES OBJETIVOS UNIDAD 1: NÚMEROS RACIONALES Distinguir las distintas interpretaciones de una fracción. Reconocer fracciones equivalentes. Amplificar fracciones. Simplificar fracciones hasta obtener la fracción irreducible.

Más detalles

Algebra lineal y conjuntos convexos

Algebra lineal y conjuntos convexos Apéndice A Algebra lineal y conjuntos convexos El método simplex que se describirá en el Tema 2 es de naturaleza algebraica y consiste en calcular soluciones de sistemas de ecuaciones lineales y determinar

Más detalles

Construcciones del Lenguaje Java

Construcciones del Lenguaje Java Construcciones del Lenguaje Java Autor: Juan Alberto López Cavallotti Versión de Java: 5 / 6 Comentarios Comentario de Línea Comentario Multilínea //Esto es un comentario. /* Esto comenta varias lineas.

Más detalles

Conjuntos Los conjuntos se emplean en muchas áreas de las matemáticas, de modo que es importante una comprensión de los conjuntos y de su notación.

Conjuntos Los conjuntos se emplean en muchas áreas de las matemáticas, de modo que es importante una comprensión de los conjuntos y de su notación. NÚMEROS REALES Conjuntos Los conjuntos se emplean en muchas áreas de las matemáticas, de modo que es importante una comprensión de los conjuntos y de su notación. Un conjunto es una colección bien definida

Más detalles

13. Utilizar la fórmula del término general y de la suma de n términos consecutivos

13. Utilizar la fórmula del término general y de la suma de n términos consecutivos Contenidos mínimos 3º ESO. 1. Contenidos. Bloque I: Aritmética y álgebra. 1. Utilizar las reglas de jerarquía de paréntesis y operaciones, para efectuar cálculos con números racionales, expresados en forma

Más detalles

Fundamentos matemáticos. Tema 2 Matrices y ecuaciones lineales

Fundamentos matemáticos. Tema 2 Matrices y ecuaciones lineales Grado en Ingeniería agrícola y del medio rural Tema 2 José Barrios García Departamento de Análisis Matemático Universidad de La Laguna jbarrios@ull.es 2017 Licencia Creative Commons 4.0 Internacional J.

Más detalles

UNIDAD 1. NÚMEROS. (Página 223 del libro) Nivel II. Distancia. Ámbito Científico Tecnológico.

UNIDAD 1. NÚMEROS. (Página 223 del libro) Nivel II. Distancia. Ámbito Científico Tecnológico. UNIDAD 1. NÚMEROS. (Página 22 del libro) Nivel II. Distancia. Ámbito Científico Tecnológico. Clasificación de los números Números naturales son aquellos que utilizamos para contar. N = 0,1,2,,,5,6, Números

Más detalles

Tema 7.- Fundamentos de la Programación Orientada a Objetos

Tema 7.- Fundamentos de la Programación Orientada a Objetos Tema 7.- Fundamentos de la Programación Orientada a Objetos 7 de enero de 2014 Objetivos Saber definir clases propias. Saber crear objetos de una clase determinada e interactuar con ellos (Problema 1).

Más detalles

Una ecuación puede tener ninguna, una o varias soluciones. Por ejemplo: 5x 9 = 1 es una ecuación con una incógnita con una solución, x = 2

Una ecuación puede tener ninguna, una o varias soluciones. Por ejemplo: 5x 9 = 1 es una ecuación con una incógnita con una solución, x = 2 Podemos definir a las ecuaciones como una igualdad entre expresiones algebraicas (encadenamiento de números y letras ligados por operaciones matemáticas diversas),en la que intervienen una o más letras,

Más detalles

Carlos Montenegro. Programación Orientada a Objetos Proyecto Curricular de Ingeniería de Sistemas

Carlos Montenegro. Programación Orientada a Objetos Proyecto Curricular de Ingeniería de Sistemas 2 - Introducción al lenguaje Java, identificadores y comentarios. Carlos Montenegro Programación Orientada a Objetos Proyecto Curricular de Ingeniería de Sistemas 1. Introducción: Java tiene como todos

Más detalles

Tema 2: EL TIPO DE DATOS ENTERO. INSTRUCCIÓN DE ASIGNACIÓN Y DE COMPOSICIÓN SECUENCIAL

Tema 2: EL TIPO DE DATOS ENTERO. INSTRUCCIÓN DE ASIGNACIÓN Y DE COMPOSICIÓN SECUENCIAL Tema 2: EL TIPO DE DATOS ENTERO. INSTRUCCIÓN DE ASIGNACIÓN Y DE COMPOSICIÓN SECUENCIAL Cualquier duda sobre el contenido de este tema se puede enviar al foro TEORIA2. 2.1.- El tipo de datos entero (byte,

Más detalles

Tema 7: Recursividad

Tema 7: Recursividad Tema 7: Recursividad Objetivos: en este tema estudiaremos funciones recursivas; esto es, funciones que se invocan a sí mismas. Estas funciones son equivalentes a estructuras tipo bucle pero permiten especificar

Más detalles