Conceptos básicos: Algoritmos y aproximaciones

En el siguiente trabajo pretendemos presentar una serie de concepto y definiciones propios del estudio de los Algoritmos, su análisis y diseño. En el mismo podremos encontrar los conceptos de algoritmo y algunos de sus componentes, análisis y diseño. También veremos los diferentes tipos de formas y tamaños o medidas en que se pueden almacenar y representar los datos y estructuras en un algoritmo o programa. En ese mismo orden encontraremos las diferentes técnicas para diseñarlos como son el método de la fuerza bruta, el voraz, divide y vencerás, programación dinámica, de vuelta atrás, entre otros. De igual forma podremos ver las definiciones y algunas características, reglas, normas, tipos de algoritmos de búsqueda y ordenación así como sus aplicaciones. Finalmente veremos los que es la verificación y derivación de programas, donde daremos los conceptos básicos de semántica y sus tipos haciendo mayor énfasis en la semántica axiomática, la recursividad e iteración, los diseños de estos últimos, así como los típicos ciclos utilizados en algoritmos y programas y los paso a tener en cuenta al momento de desarrollar un algoritmo iterativo o recursivo. Es importante el estudio y conocimiento de lo que hoy conocemos como Algoritmos Computacionales, que desde su aparición hasta nuestros días es, y seguirá siendo; vital para el desarrollo de aplicaciones para computadoras y el manejo y dominio de la lógica de programación para resolver problemas. Como estudiantes de la Facultad de Ciencias y Tecnología " Escuela de Informática y Computación " de la Universidad Dominicana Organización y Métodos O&M con aspiraciones de iniciarnos como Ingeniero en Sistemas y Computación. Con el objetivo inmediato de aprobar con los mejores meritos la asignatura de Algoritmos Computacionales. General: Posibilitar la estudiante alcanzar una visión sistemática de lo que conocemos sobre Los Algoritmos Computacionales. Específicos : Introducir los conceptos propios sobre Algoritmo, su importancia en el mundo de las aplicaciones para computadoras y el manejo de lógica de programación.
y y y y y y

Proporcionar una idea de su uso. Visualizar sus ventajas e importancia. Definir sus tipos y variantes. Proporcionar conceptos sobre su análisis y diseño. Proporcionar concepto sobre las técnicas de diseño. Desglosar sus variantes (ordenación, búsqueda, etc. ).

Marco Historico. Un algoritmo es un conjunto de operaciones y procedimientos que deben seguirse para resolver un problema. La palabra algoritmo se deriva del nombre latinizado del gran Matemático Árabe Mohamed Ibn Al Kow Rizmi, el cual escribió sobre los años 800 y 825 su obra Quitad Al Mugabala, donde se recogía el sistema de numeración hindú y el concepto del cero. Fue Fibinacci, el que tradujo la obra al latín y el inicio con la palabra: Algoritmi Dicit. El lenguaje algorítmico es aquel por medio al cual se realiza un análisis previo del problema a resolver y encontrar un método que permita resolverlo. El conjunto de todas las operaciones a realizar y e orden en que se deben efectuarse, se le denomina algoritmo.

Es un método para resolver un problema mediante una serie de datos precisos, definidos y finitos. Generalidades El programador de computadoras es ante que nada una personaque resuelve problemas, por lo que para llegar a ser un programador eficaz se necesita aprender a resolver problemas de un modo riguroso y sistemático. A la metodología necesaria para resolver problemas mediante programas se denomina Metodología de la Programación. El eje central de esta metodología es el concepto, ya tratado, de algoritmo. Un algoritmo es un método para resolver un problema. Aunque la popularización del término ha llegado con el advenimiento de la era informática, algoritmo proviene de Mohammed alKhowarizmi, matemático persa que vivió durante el siglo IX y alcanzo gran reputación por el enunciado de las reglas para sumar, restar, multiplicar y dividir números decimales; la traducciónal latín del apellido de la palabra algorismus derivo posteriormente en algoritmo. Euclides, el gran matemático griego (del siglo IV antes de Cristo) que invento un método para encontrar el máximo común divisor de dos números, se considera con Al-Khowarizmi el otro gran padre de la algoritmia ( ciencia que trata de los algoritmos). El profesor Niklaus Wirth, inventor de Pascal, Modula-2 y Oberon, titulo uno de sus mas famosos libros, Algoritmos + Estructuras de Datos = Programas, significándonos que solo se puede llegar a realizar un buen programa con el diseño de un algoritmo y una correcta estructura de datos. Esta ecuación será de una de las hipótesis fundamentales consideradas en esta obra. La resolución de un problema exige el diseño de un algoritmo que resuelva el problema propuesto. Los pasos para la resolución de un problema son: 1. Diseño de algoritmo, que describe la secuencia ordenada de pasos que conducen a la solución de un problema dado. (Análisis del problema y desarrollo del algoritmo). 2. Expresar el algoritmo como un programa de lenguaje de programación adecuado. (Fase de codificación.) 3. Ejecución y validación del programa por la computadora. Para llegar a la realización de un programa es necesario el diseño previo de algoritmo, de modo que sin algoritmo no puede existir un programa. Los algoritmos son independientes tanto del lenguaje de programación en que se expresan como de la computadoraque lo ejecuta. En cada problema el algoritmo se puede expresar en un lenguaje diferente de programación y ejecutarse en una computadora distinta; sin embargo, el algoritmo será siempre el mismo. Así, por ejemplo, en una analogía con la vida diaria, una receta de un plato de cocina se puede expresar en español, ingles o francés, pero cualquiera que sea el lenguaje, los pasos para la elaboración del plato se realizaran sin importar el idioma del cocinero. En la cienciade la computación y en la programación, los algoritmos son más importantes que los lenguajes de programación o las computadoras. Un lenguaje de programación es tan solo un medio para expresar un algoritmo y una computadora es solo un procesador para ejecutarlo. Tanto el lenguaje de programación como la computadora son los mediospara obtener un fin: conseguir que el algoritmo se ejecute y se efectúe el proceso correspondiente. Dada la importancia del algoritmo en la ciencia de la computación, un aspecto muy importante será el diseño de algoritmos. El diseño de la mayoría de los algoritmos requiere creatividady

conocimientos profundos de la técnica de la programación. En esencia, la solución de un problema se puede expresar mediante un algoritmo. Características de los Algoritmos: Las características fundamentales que debe cumplir todo algoritmo son:
y y y

Un algoritmo debe ser preciso e indicar el orden de realización de cada paso. Un algoritmo debe estar definido. Si se sigue un algoritmo dos veces, se debe obtener el mismo resultado cada vez. Un algoritmo debe ser finito. Si se sigue un algoritmo se debe terminar en algún momento; o sea, debe tener un numero finito de pasos.

La definición de un algoritmo debe definir tres partes: Entrada, Proceso y Salida. En el algoritmo de receta de cocina citado anteriormente se tendrá: Entrada: ingrediente y utensilios empleados. Proceso: elaboración de la receta en la cocina. Salida: terminación del plato (por ejemplo, cordero). Ejemplo de Algoritmo: Un cliente ejecuta un pedido a una fábrica. Esta examina en su banco de datos la ficha del cliente; si el cliente es solvente entonces la empresa acepta el pedido; en caso contrario rechazara el pedido. Redactar el algoritmo correspondiente. Los pasos del algoritmo son: 1. 2. 3. 4. 5. inicio leer el pedido examinar la ficha del cliente si el cliente es solvente aceptar pedido; en caso contrario, rechazar pedido fin

Diseño del Algoritmo: En la etapa de análisis del proceso de programación se determina que hace el programa. En la etapa de diseño se determina como hace el programa la tarea solicitada. Los métodos mas eficaces para el proceso de diseño se basan en el conocido por Divide y Vencerás, es decir, la resolución de un problema complejo se realiza dividiendo el problema en sub problemas y a continuación dividir estos sub problemas en otros de nivel mas bajo, hasta que pueda ser implementada una solución en la computadora. Este método se conoce técnicamente como diseño descendente (Top Down) o modular. El proceso de romper el problema en cada etapa y expresar cada paso en forma más detallada se denomina refinamiento sucesivo. Cada sub programa es resuelto mediante un modulo (sub programa) que tiene un solo punto de entrada y un solo punto de salida. Cualquier programa bien diseñado consta de un programa principal (el modulo de nivel mas alto) que llama a sub programas (módulos de nivel mas bajo) que a su vez pueden llamar a otros sub programas. Los programas estructurados de esta forma se dice que tienen un diseño modular y el método de romper el programa en módulos más pequeño se llama Programación Modular. Los módulos pueden ser planeados, codificados, comprobados y depurados independientemente (incluso por diferentes programadores) y a continuación combinarlos entre si. El proceso implica la ejecución de los siguientes pasos hasta que el programa se termina:

y y y y

programar modulo. Comprobar el modulo. Si es necesario, depurar el modulo. Combinar el modulo con los módulos anteriores.

El proceso que convierte los resultados del análisis del problema en un diseño modular con refinamiento sucesivo que permitan una posterior traducción al lenguaje se denomina diseño de algoritmo. El diseño del algoritmo es independiente del lenguaje de programación en el que se vaya a codificar posteriormente. 4. Análisis De Algoritmos Recursos De Computadores Y Complejidad Algoritmo: Conjunto de reglas para resolver un problema. Su ejecución requiere unos recursos. Un algoritmo es mejor cuantos menos recursos consuma, su facilidad de programarlo, corto, fácil de entender, robusto, etc. Criterio empresarial: Maximizar la eficiencia. Eficiencia: Relación entre los recursos consumidos y los productos conseguidos. Recursos consumidos: Tiempo de ejecución. Memoria principal: Entradas/salidas a disco. Comunicaciones, procesadores, etc. Lo que se consigue: Resolver un problema de forma exacta, forma aproximada o algunos casos. Recursos consumidos: Ejemplo. ¿Cuántos recursos de tiempo y memoria consume el siguiente algoritmo sencillo? i:= 0 a[n+1]:= x repetir i:= i + 1 hasta a[i] = x Respuesta: Depende. ¿De qué depende? De lo que valga n y x, de lo que haya en a, de los tipos de datos, de la máquina... En general los recursos dependen de: Factores externos. El ordenador donde lo ejecutemos: 286, Pentium III, Cray,... El lenguaje de programación y el compilador usado. La implementación que haga el programador del algoritmo. En particular, de las estructuras de datos utilizadas. Tamaño de los datos de entrada. Ejemplo. Calcular la media de una matriz de NxM. Contenido de los datos de entrada. Mejor caso. El contenido favorece una rápida ejecución. Peor caso. La ejecución más lenta posible. Caso promedio. Media de todos los posibles contenidos.

IF y CASE: Estudiar lo que puede ocurrir.. luego se diferencia en una constante con los anteriores. Programa "cifras. T(4)= 0. ¿Existe una cota inferior y superior del número de ejecuciones? ¿Se puede convertir en un FOR? El análisis de algoritmos también puede ser a posteriori: implementar el algoritmo y contar lo que tarda para distintas entradas. Bucles FOR: Se pueden expresar como una sumatoria.. Mejor caso y peor caso según la condición.... Ejemplo. pero ¿qué significa T(N)? Tiempo de ejecución en segundos. W (T): Orden inferior de T. T(N) = bN + c. T(7)= 10 s N= 8. Medidas Asintoticas Notación asintótica: El tiempo de ejecución T(n) está dado en base a unas constantes que dependen de factores externos. con los límites del FOR. si el algoritmo es poco eficiente.2 s N= 7. Asignación de tiempos. -.? Sabemos que cada ejecución lleva un tiempo constante. Bucles WHILE y REPEAT: Estudiar lo que puede ocurrir.1 ms N= 5. Suponiendo que b y c son constantes. cuántas instrucciones.5 min ¿Qué conclusiones podemos extraer? Análisis a priori: Evitamos la implementación. o alguna constante. o una constante diferente. Podemos comparar con otros algoritmos. para el conteo de instrucciones. ¿Cuánto tiempo. Operaciones básicas (+. u omega de T.Los factores externos no aportan información sobre el algoritmo.. Instrucciones ejecutadas por el algoritmo. Operaciones de entrada salida: Otra unidad de tiempo.. O(T): Orden de complejidad de T. T(N) = 2N + 4. :=. ¿Tardarán todas lo mismo? Ejecuciones del bucle principal. para valores suficientemente grandes (asintóticamente) sin considerar constantes..exe": N= 4. T(5)= 5 ms N= 6. *. con los segundos que tardan las operaciones básicas correspondientes. T(6)= 0. Nos interesa un análisis que sea independiente de esos factores. Podemos hacer previsiones. Conclusión: Estudiar la variación del tiempo y la memoria necesitada por un algoritmo respecto al tamaño de la entrada y a los posibles casos.): Una unidad de tiempo. de forma aproximada (y parametrizada). ¿Se puede predecir cuándo se cumplirán las condiciones? Llamadas a procedimientos: Calcular primero los procedimientos que no llaman a otros. Q (T): Orden exacto de T. Algunas reglas básicas. Notaciones asintóticas: Indican como crece T. Orden de complejidad de f(n): O(f) . externos no aportan información sobre el algoritmo. Normalmente usaremos la notación T(N)=. T(8)= 3. T(N) = N+1..

Dadas f y g. ..": no nos importa lo que pase para valores pequeños. " n ³ n0: t(n) £ c·f(n) } Nota: O(f) es un conjunto de funciones. g)).) es completa? Dadas f y g.g) = O(max(f. ¿se cumple O(f)Í O(g) ó O(g)Í O(f)? P4. de N en R+. ... Dadas f y g de N en R+. llamamos orden de f al conjunto de todas las funciones de Nm en R+ acotadas superiormente por un múltiplo real positivo de f. el tiempo y la memoria consumidos pueden depender de muchos parámetros. W (g) Í W (f) g(n) P5. -g))? P5.. La definición es aplicable a cualquier función de N en R. Ej.. para valores de n suficientemente grandes.n..m. Si f Î O(g) y g Î O(h) entonces f Î O(h). Grandes. Q (f)=Q (g) g(n) ii) limn¥ ® f(n) = 0 Þ O(f) Í O(g)... W (f)=W (g).xN ® R+) Ej.. . 2n+1 Î O(n). Dadas f y g de N en R+. Si f Î W (g) y g Î W (h) entonces f Î W (h) Ej. llamamos orden de f al conjunto de todas las funciones de N en R+ acotadas superiormente por un múltiplo real positivo de f. ¿Qué relación hay entre O(log2 n) y O(log10 n)? P6. O(f+g) = O(max(f.. O(f)=O(g) Û Q (f)=Q (g) Û f Î Q (g) Û W (f)=W (g) P7. O(f)= { t: N ® R+ / $ c Î R+... Memoria en una tabla hash. k) = kB+l+n+2kn Orden de complejidad de f(n1. nm): O(f) Dada una función f: Nm ® R+. para valores de (n1..": nos quitamos las constantes. ¿Cómo es la relación para los W ? P3. l. se cumple: i) limn¥ ® f(n) Î R+ Þ O(f)=O(g). n2. "Valores de n sufic. Dadas f y g de N en R+. no sólo tiempos de ejec. Dadas f y g de N en R+. M(B. $ n0 Î N. no una función. se cumple: i) O(f) = O(g) Û f Î O(g) y g Î O(f) ii) O(f) Í O(g) Û f Î O(g) ¿La relación de orden entre O(. "Funciones acotadas superiormente por un múltiplo de f. se cumple: i) limn¥ ® f(n) Î R+ Þ O(f) = O(g) g(n) ii) limn¥ ® f(n) = 0 Þ O(f) Ì O(g) g(n) iii) limn¥ ® f(n) = +¥ Þ O(f) É O(g) g(n) Notación con varios parámetros: En general. f: Nm ® R+ (f: Nx. nm) suficientemente grandes. W (f+g) = W (max(f+g)) ¿Y para los Q (f+g)? ¿Es cierto que O(f .Dada una función f: N ® R+. Si f Î O(g) entonces O(f) Í O(g). Propiedades P1. n Î O(n2) Þ 2n+1 Î O(n2) P2..

. Orden inferior u omega de f(n): W (f): Dada una función f: N ® R+. ¿Qué relación hay entre los siguientes órdenes? O(n+m).. ±O(f) £ O(g) Û O(f) Í O(g) Û Para toda t Î O(f). O(c) Ì O(n) O(cn + b) = O(dn + e) O(p) = O(q). Para cualquier f y g. $ n1. . para funciones con varios parámetros. tenemos W (f | P) y Q (f | P).. Relación de orden: igual que antes.. llamamos orden exacto de f al conjunto de todas las funciones de N en R+ que crecen igual que f. k2 ³ n2 . Orden exacto de f(n): Q (f): Dada una función f: N ® R+. n2.. f Î O(g | false). siendo c y d constantes positivas. Orden condicionado de f(n): O(f | P) Dada una función f: N ® R+. . " k1 ³ n1 . ‡Relación de orden entre O(... k2. t Î O(g) ‡Se cumple que: O(c) = O(d). " n ³ n0: t(n) ³ c·f(n) } La notación omega se usa para establecer cotas inferiores del tiempo de ejecución. y que más se aproxime asintóticamente. o variables T(N..a. $ n0 Î N.b). ¿O(f) « O(f | P)? Ordenes De Complejidad Uso de los órdenes de complejidad: Dado un tiempo t(n). si p es un polinomio de menor grado que q. t(n) = 2n2/5 + 3p /2. y del tiempo de inicialización b y de ejecución de un paso a. km) } De la misma forma. Podemos suponerlos constantes T(N). llamamos orden de f según P (o condicionado a P) al conjunto: O(f | P)= { t: N ® R+ / $ c Î R+. Las propiedades se siguen cumpliendo ® Demostrarlo. para valores de n suficientemente grandes.. O(n+2m) Notaciones condicionales: En algunos casos interesa estudiar el tiempo sólo para ciertos tamaños de entrada. O(nm) O(n2).. Ejemplo." km ³ nm : t(k1. llamamos omega de f al conjunto de todas las funciones de N en R+ acotadas inferiormente por un múltiplo real positivo de f. O(p) Ì O(q). km) £ c·f(k1.. asintóticamente y salvo constantes. podemos extender los conceptos de W (f) y Q (f). $ n0 Î N. Ejemplo.) = Relación de inclusión entre conjuntos. W (f)= { t: N ® R+ / $ c Î R+. Algoritmo de búsqueda binaria: Si N es potencia de 2 el estudio se simplifica.. Ejemplo. nm Î N. y P: N ® B. T(N) = T(N. a. " n ³ n0: P(n) Þ t(n) £ c·f(n) } De igual forma. b) = a·N + b El tiempo depende del tamaño del problema N. encontrar la función f más simple tal que t Î O(f). t(n) Î O(n2).O(f)= { t: Nm ® R+ / $ c Î R+.. si p y q son polinomios del mismo grado. . O(f) = O(f | true). k2.

) Ì O(n2) Ì O(n3) Ì .. Los logaritmos son del mismo orden. Todo problema algorítmico es un reto para su diseñador. ... una tarea difícil. aparecerá un orden logarítmico O(log2 n). " n ³ n0: c·f(n) ³ t(n) ³ d·f(n) } Notación o pequeña de f(n): o(f): Dada una función f: N ® R+.. n/4. Una forma de facilitar esta labor consiste en recurrir a técnicas conocidas de diseño de algoritmos. llamamos o pequeña de f al conjunto de todas las funciones de N en R+ que crecen igual que f asintóticamente: o(f)= { t: N ® R+ / lim t(n)/f(n) = 1}n¥ ® Esta notación conserva las constantes multiplicativas para el término de mayor orden. en general. La investigaciónen esta área ha permitido descubrir un conjunto de métodos o esquemas de diseño hacia los cuales puede orientarse la realización de muchos algoritmos. independientemente de la base. y a pesar de que resulta mas adecuado en bastantes casos utilizar alguno de estos esquemas que realizar un diseño desde cero. nnn å 1 = n Î O(n).. Técnica de diseño de algoritmos Diseño de Algoritmos: Hasta ahora se han realizado algunos comentarios respecto a la necesidad de diseñar algoritmos correctos y eficientes utilizando los elementos de un lenguaje de programación . El diseño de un algoritmo que resuelva un problema es.. a la vez bastante ineficiente. El acto de diseñar un algoritmo puede considerarse como una tarea que difícilmente podrá ser del todo automatizada. d Î R+.. t(n) = amnm + am-1nm-1 + . Ejemplo. El esquema mas sencillo quizás sea el llamado divide y vencerás. se decir.+a1x+a0 es O(xn).. otra para n/2.Q (f) = O(f) Ç W (f) = { t: N ® R+ / $ c. $ n0 Î N. Este método. basado en la descomposición de un problema en . llamado de fuerza bruta.. å i = n(n+1)/2 Î O(n2). å im Î O(nm+1) i=1 i=1 i=1 Si hacemos una operación para n. puede ser muy directo.. a esquemas muy generales que pueden adaptarse a un problema particular al detallar las partes generales del esquema. pero con un poco de análisis puede encontrarse algoritmos más eficientes.001. Muchos problemas pueden resolverse buscando una solución fácil y directa pero. Ì O(2n) Ì O(n!) Ì O(nn) ¿Qué pasa con las omegas? ¿Y con los órdenes exactos? El orden de un polinomio anxn+. otros son bastante complejos.. +a1n + a0 t(n) Î o(amnm) ¹ o(nm) ¿o(amnm) Í O(amnm)? ¿o(t) Í O(t)? Costa de complejidad con frecuencia Algunas relaciones entre órdenes frecuentes: O(1) Ì O(log n) Ì O(n) Ì O(n·log n) Ì O(n·(log n)2) Ì O(n1.Es necesario en este momento mencionar algo sobre como hacerlo. algunos resultan inmediatos de resolver. No obstante. 5. idear un algoritmo continua siendo una labor bastante creativa donde los conocimientos y la experiencia del propio diseñador tiene un papel fundamental.

Se programa un computador de manera que parta de un conjunto de axioma matemáticos y los que use para reducir aleatoriamente teoremas validos. pero que debe evitarse siempre que se pueda. hay problemas cuya solución no puede hallarse sino mediante un proceso de búsqueda. Si no nos importa la eficiencia del algoritmo. solo puede tomarse tras considerar varias solucionesde otras etapas mas simples. si la decisión en una etapa. con la experiencia. que debe completarse con otros conocimientos y. Supongamos que disponemos de una especificación precisa. la solución es dinámica. se produzca cierto resultado. Otro algoritmo realizaba un búsqueda dicotomica o binaria. En realidad. y el empleode tablas como estructura auxiliar para la resolución eficiente de problemas donde se aplica programación dinámica). dad su ineficacia. porque su desarrollo puede permitir profundizar más sobre el problema y conocer propiedades que sean utilizadas para obtener otra versión más eficiente. y quizás el mejor. tenemos una solución voraz. no es un esquema algorítmico. el uso de parámetros de acumulación al resolver problemas utilizando divide y vencerás. la fuerza bruta. puesto que existe un número reducido de esquema y técnicas de diseño. Otros esquemas requieren un análisis minucioso del problema de forma que la solución se vaya construyendo en etapas. Aprender los principiosbásicos del diseño de algoritmos podemos preguntarnos por un método aceptable. Por ejemplos: Algunos algoritmos de búsqueda de un elemento en un vector. Consideraciones generales Si el hábil programador dispone de un recetario de algoritmos de donde poder seleccionar el más adecuado para cada problema. dados uno datos de entrada valido. es organizar el diseño sobre un esquema de algoritmo o una técnica de diseño que haya demostrado su utilidad para otros problemas. su uso adecuado mediante el esquema de búsqueda con retroceso (o backtracking) permite ganar gran eficiencia respecto a soluciones de fuerza bruta. Aun así. sobre todo. Este método de trabajo es practicable. Nos estamos refiriendo a métodos basados en la mejora de la eficiencia (por ejemplo. Si puede preverse que decisión conviene en cada etapa para producir cierto tipo de mejor resultado. conviene conocer otros métodos de diseño de algoritmos que también resultan de utilidad práctica. a pesar de lo complejas que son las operaciones de búsqueda. pero dado que no se ha analizado apenas el problema. completa y consistente del problema a resolver y queremos obtener un algoritmo en el que. y a métodos basados en transformaciones del dominio para encontrar una solución mas fácilmente a un problema en un dominio transformado. podríamos utilizar un algoritmo general llamado algoritmo del museo británico. En principio. con complejidad . Uno de ellos realizaba una búsqueda secuencial con complejidad lineal sobre el tamaño del vector y podía usarse con cualquier vector. Por ultimo. su tarea se simplifica. poco reflexionada. El conocimiento de técnicas de diseño es solo un primer paso para el diseñador. es muy probable que no se hayan aprovechado propiedades deducibles del problema y que la solución sea terriblemente ineficiente. Método de fuerza bruta Comenzamos el estudio de esquemas algorítmicos con un método sencillo. siendo dicha solución finalmente adaptada al dominio original. Una solución por fuerza bruta también puede resultar adecuada como primera aproximación a la solución final. esto no es malo. si no mas bien calificativo Para una forma de diseñar algoritmos: tomar una solución directa. El mas entendido.subproblemas.

que juegan una competición que es ganada por el primero que venza en n partidos. Por sencillez . Lo más razonable es comprobar si el vector esta ordenado y. en combinación con otras contrucciones. se almacena en una tabla. Técnicas de los Parámetros Acumuladores y de Tabulacion La recurcion es un mecanismo que permite obtener. pero no todos: hay algunos fácilmente formulables. dichos algoritmos pueden servir como una primera aproximación al algoritmo definitivo. siendo ( n ) mayor que( 0 ). donde puede consultarse otras veces que se necesite. y solo se podía usar cuando el vector estuviese ordenado. Parámetros Acumuladores Veamos primero una solución ineficiente que intentaremos mejorar. A. se supone que ambos participantes tienen cualidades y preparación similar . por lo que uno puede sentirse tentado a usar siempre. Ejemplo: Números de Fibonacci Los números de fibonacci suele especificarse como: Fib(0)=1 Fib(1)1 Fib(n+2)=fib(n)+fib(n+1) Esta especificación de los números de fibonacci tienen una formulación recursiva inmediata en estilo funcional. Divide y vencerás: Consiste en descomponer un problema en un subproblema. pero debe mejorar su rendimiento para que sea práctico. aprovechar esta circunstancia para usar el algoritmo más eficiente: el de búsqueda binaria. una solución funcional a muchos problemas.B. Un modo de evitar problema lo proporciona la técnica de los parámetros acumuladores. Tabulacion No todos los algoritmos recursivos ineficientes pueden optimizarse con la técnica de los parámetros acumuladores. Cada una se ilustra con un ejemplo distinto. De forma que cada uno tiene un 50% de posibilidades de ganar cada partido. La intención es que la primera vez que se realiza un cálculo. no importa que). la modificación para incorporar probabilidades diferentes es evidente y no complica el problema. Otra técnica útil es el uso de tablas. pero muy ineficientes. La función principal simplemente realiza una llamada a esta función auxiliar en los que los parámetros de aquellas se modifican y los parámetros nuevos toman un valor inicial adecuado . Veremos dos parámetros para la mejora de eficiencia de algoritmos recursivos: el uso de parámetros acumuladores y el uso de tablas.logarítmica. Ejemplo: Sea el problema de la competición. La función principal usa una función auxiliar que tiene los parámetros de aquellas más algunos adicionales. El algoritmo primero responde a un razonamiento más sencillo. pero poco reflexionada. resolver independientemente los . Esta técnica también se suele emplear con la programación dinámica. De todas formas. cuya idea básica se expone a continuación. Los parámetros adicionales tienen como misión ir acumulando resultados principales durante el proceso recursivo. Hay dos participantes (deportistas o equipos. en caso positivo. En estos casos. Esta es la solución de fuerza bruta: una solución directa. Muchos algoritmos recursivos resultan eficientes.

. Pude aparecer obvio. Suponiendo que se disponga de cantidad suficiente de ciertos tipos diferentes de monedas de curso legal. la moneda de mayor valor ( es decir. El proceso finaliza cuando se ha devuelto todo el cambio. Ejemplo. se buscara en la segunda mitad.. se va procedimiento paso a paso realizándose la mejor elección (usando una función objetivo que respeta un conjunto de restricciones ) de entre las posibles. pero resulta difícil de asegurar en algoritmos complejos. en la búsqueda de caminos mínimos sobre grafos. Nunca se debe olvidar que la característica más simple e importante de un algoritmo es que funcione. Esta técnica se puede aplicar con éxito a problemas como la multiplicación de matrices. Se abre el diccionario por la pagina centrar(quedando dividido en dos mitades) y se comprueba si la palabra aparece allí o si es léxico gráficamente anterior o posterior. cierta medida. También influyen haciendo que nuestro algoritmo resulten más fáciles de leer y entender para otras personas. cuando se pueda. se trata de dar como cambio la menor cantidad posible usando estos tipos de monedas. Estilo y calidad de los programas van fuertemente unidos. La estrategia voraz aplicada comienza devolviendo. estas normas de estilo se dirigen hacia aspectos como la forma de construir los nombres de variables o tipo de datos que aparezcan.etc. la tipografía seguida ala hora de escribir nombres de variables. la búsqueda en estructuras ordenadas. palabras claves.etc. Los criterios de estilo pueden reflejarse en un conjunto de normas de estilo de codificación. Generalmente. El modo de encolumnar las distintas partes de un algoritmo para facilitar su lectura y comprensión. las siguientes respuestas reflejan. continua aplicándose el mismo criterio para la segunda moneda mas valiosa. Búsqueda de una palabra en un diccionario Como ejemplo sencillo de aplicación de esta estrategia puede considerarse la búsqueda de una palabra en un diccionariode acuerdo con el siguiente criterio. Ante la pregunta ¿Cuáles son las característica de un buen algoritmo?. Si no ha encontrado y es anterior se procede a buscarla en la primera mitad. Ello asegura que tanto algoritmos como programa resulten legibles y puedan modificarse fácilmente en caso de necesidad. Puede emplearse en problemas de optimización. Consideraciones y Criterios para Diseñar Algoritmos Algunas consideraciones estilísticas pueden contribuir a mejor la calidadde los algoritmos (y programas ) mediante la reducción del numero de errores que aparecen al desarrollar los. la ordenación de vectores. . y así sucesivamente. si es posterior. 2. el algoritmo debe funcionar. Dar un cambioutilizando el menor número de monedas Considérese ahora el problema de la devolución del cambio al realizar una compra (por ejemplo. Método voraz: Este método trata de producir tipo de mejor resultado a partir de conjunto de opciones candidatas . Ejemplo. 1. subprogramas. etc.subproblemas para luego combinar sus soluciones y obtener la solución del problema original.Para ello. y la normas sobre como y donde deben de introducirse los comentarios. como el conocido de la mochila. la planificación en el orden de la ejecución de unos programas en un computador. los factores que identifican la calidad en ellos . mientras el valor de dicha moneda sea mayor o igual al cambio que resta por dar). Corrección. en una maquina expendedora de tabaco). El procedimiento se repite sucesivamente hasta encontrar la palabra o decidir que no aparece.

dados unos ficheros almacenados en una cinta de que el tiempo de recuperación de un fichero cualquiera sea el mínimo en promedio. sea el problema de encontrar un subconjunto de los arcos de un grafo. en cuyo caso no importa cual se elija. Puede haber varias soluciones optimas. Para facilitar la descripción de este proceso. 4. no hay que desperdiciar estos recursos y tratar de desarrollar algoritmos más eficientes. pero con la fortuna de que cada vez que añade un elemento a la solución se tiene la certeza de haber realizado la mejor elección posible. Eficiencia. . el problema parte de: y Una función objetivo que da el valor de una solución. ésta es la función por optimizar. Otro ejemplo se da cuando. Por ejemplo. analizando durante cada etapa que elemento conviene añadir a la solución parcial ya existente. encontrando de una sola vez la solución completa y óptima. el problema incluye restricciones adicionales que limitan el número posible de soluciones. Se supone que un problema de esta clasetiene al menos una solución. es decir. el conjunto de candidatos que forman la solución está vacío. el candidato se incorpora definitivamente. Algoritmos voraces Esquema voraz Hay muchos problemas en los que se pretende obtener un subconjunto de n elementos que satisfaga ciertas restricciones y que optimice alguna medida. Normalmente. el algoritmo debe estar bien documentación. Esta característica hace que aunque el análisis del problema sea arduo. permite formar una solución del problema. Por lo que se ha descrito del esquema voraz. estos problemas no se intentan resolver "de golpe ". La eficiencia de un algoritmo se mide por los recursos que este consume. Obviamente. La única complicación es comprobar que se siguen satisfaciendo las restricciones del problema. claro. por tanto. lo ideal es que nuestro algoritmo resulte correcto. se desecha el candidato. En cada paso se intenta añadir el mejor de los candidatos restantes a dicha solución parcial. Ciertos detalles o algunas partes especiales de los mismos pueden olvidarse fácilmente o quedar oscura si no están adecuadamente comentadas. se habla de la memoria y del tiempo de ejecución .3. la solución voraz siempre resulte sencilla. Claridad. Un algoritmo voraz sigue el esquema anterior. Es más frecuente que el subconjunto de la solución se vaya formando paso a paso. En particular. el algoritmo no debe desaprovechar recursos. fiable y fácil de mantener. Según esta descripción. Por tanto. la calidad de un algoritmo tiene muchas facetas y todas ellas importantes. En realidad. eficiente. si satisface las restricciones del problema y. A menudo. la dificultad principal al diseñar un algoritmo voraz reside en encontrar un criterio en encontrar un criterio de selección que garantice la optimalidad de la solución. Si el algoritmo voraz se ha diseñado correctamente. Inicialmente. la primera solución encontrada es óptima. puede llamarse candidato al elemento tratado en cada paso. si dicho conjunto no es válido. Resumiendo. A pesar de que con la reducción de los costes del hardware es posible diseñar computadores más rápidos y con más memoria. La documentación ayuda a comprender el funcionamiento de los algoritmos. y de acuerdo con los puntos de vista anteriores. éste es un proceso repetitivo sencillo que trata sucesivamente los diferentes elementos del problema. Si este conjunto ampliado sigue siendo válido. Al contrario. La dificultad principal para resolver esta clase de problemas estriba en el análisis necesario para poder formular un algoritmo que halle la solución en varios pasos.

se considera el problema de un cambio o desglose en monedas. Obsérvese que las funciones de validez y completitud no se preocupan de la optimalidad del la solución. ( ) ) Puede verse por qué estos algoritmos se llaman " voraces " : en cada paso toman el mejor trozo de la solución. cada solución válida y completa es optima. solución) VorazAcumulador (candidatos. A su vez.. Hay que desglosar una cantidad en un conjunto de monedas tratando de cumplir alguna condición. Además. y de un importe. solución v (siguiente)) VorazAcumulador (candidatos ± (siguiente). Además.n) -> Cadidatos = ( ) v EsSolución ( solución)-> Value siguiente -> seleccionar ( candidatos ) IN EsVálida (solución v ( siguiente)) => VorazAcumulador (candidatos ± (solución). la decisión.n) : (1. es decir.. utilizar el menor número de monedas. Desglose en monedas Como primer ejemplo introductorio sencillo al que puede aplicarse la técnica voraz. Solución : (1. pero si la función de selección es la adecuada. Para ello. . Podemos representar el esquema voraz de la siguiente forma funcional: FUNCTION Voraz ( candidatos: ( 1. el lector puede intentar encontrar una solución voraz del problema del calendario. de las que se supone que hay cantidad suficiente para realizar el desglose.n ) : ( 1. es decir. la tabla de competición se va completando por filas. tales que sumados sus valores equivalgan al importe. sino que se utiliza durante el análisis del problema y es determinante en la elección de la función de selección. es definitiva. si permite formar alguna solución del problema. Se trata de indicar la cantidad (menor) de monedas de los tipos considerados. La función objetivo no suele aparecer en el algoritmo final. Como ejercicio. la solución consta de: y y y Un conjunto de candidatos Una función de selección que en cada momento determine que candidato de los aún no usados parece ser el mejor. este algoritmo tiene la ventaja de valer para las situaciones en que el número de participantes no es una potencia de dos. Como fila primera se toma la secuencia de los índices de los participantes en cualquier orden. Es fácil encontrar una solución si en cada etapa se genera el subcalendario correspondiente a un equipo. De todas formas..y Un conjunto de restricciones sobre el valor de los datos de entrada y sobre la solución final del problema.n) -> FUNCTION VorazAcumulador ( candidatos : (1.n). en este caso.. es decir. Una función que determine si cierto conjunto de candidatos es válido. se parte de un conjunto de tipos de monedas válidas. el mejor candidato. debe recordarse que puede haber varios criterios alternativos de selección y que de su correcta elección depende que la solución calculada por el algoritmo sea optima.. nunca cambian de opinión: una vez que un candidato es aceptado o rechazado en la solución. Cada fila resultante puede tener una complejidad de o (n2).

50. la técnica de divide y vencerás parte la entrada en k subproblemas. La condición de factibilidad de la solución siendo construida establece en el desglose debe ser menor o igual que el importe a desglosar. Después se resuelven estos subproblemas y se combinan las soluciones para obtener la solución para el problema original. suponemos que manejamos dineroespañol y. éste no será nunca excluido de él. Esta restricción permite una formulación y resolución recursiva de los subproblemas. considerado el problema como de tipo dato y la solución. 25. de tipo resultado: TYPEVAR     . 100. Por supuesto. Mas formalmente. Asimismo.M1 Se supone inicialmente asignados los valores a cada uno de los tipos de monedas. Con esta información se puede comprobar que en este problema están presentes los distintos elementos de la técnica voraz. La técnica de divide y vencerás es quizás una de las utilizadas debido a su sencillez: si un problema es demasiado grande para resolverlo de una vez. Su formación funcional es como sigue. se declaran los tipos VALORES y CANTIDADES para representar el valor asignado a cada unidad monetaria y la cantidad de cada tipo de moneda que se devolverá en el desglose. Los elementos de la técnica voraz están presentes en este problema de la siguiente forma: y y y y y El conjunto de candidatos está constituido por cada una de las monedas de los diferentes tipos que se pueden usar para realizar el desglose del importe dado. es fácil su generalización a k subproblemas 2<k<=n. dado un problema al resolver planteando en términos de una entrada de tamaño n. en caso contrario. 5 y 1 pesetas para el desglose. Una solución viene dad por un conjunto de monedas devuelto tras el desglose. en particular. Este esquema de partición de problemas se denomina esquema de divide y vencerás solo en el caso en que los problemas sean de la misma clase del problema original. cuando un candidato (moneda) se incorpora al conjunto solución. el proceso recursivo nunca terminaría. Estos valores se definen por medio de un tipo enumerado MONEDAS. Su declaración es la siguiente: TYPE Monedas -> M500 I M100 I M50 I M25 I M5 I M1. 1<k<=n. se descompone en varias partes más fáciles de resolver. Estos subproblemas se resuelven independientemente y después se combinan sus soluciones parciales para obtener la solución del problema original. deben existir algunos pasos sencillos cuya solución pueda calcularse fácil y directamente.Para simplificar. Valores -> Integer M500 M1 Cantidades -> Integer M500 . Además. podemos utilizar sólo monedas de 500. El caso más frecuente es cuando el número de subproblemas es dos. mientras sea posible. La función objetivo cosiste en minimizar la cantidad total de monedas utilizadas en el desglose. la moneda de mayor valor de entre las candidatas. Veamos el esquema de divide y vencerás para dos subproblemas. La función de selección establece que hay que elegir. Esquema de Divide y vencerás. Divide Y Vencerás La técnica divide y vencerás consiste en descomponer el problema en un conjunto de subproblemas más pequeños. y cuyo valor total es igual al importe a desglosar.

TYPEVAR dato. N. superior. para que esta técnica resulte eficiente todos los subproblemas deben ser de tamaño parecido.. 1. y sin perdida de generalidad. Partir y Combinar por funciones o procedimientos concretos. La eficiencia final del algoritmo depende de la función f(n) concreta que aparezca durante el análisis. en la que se utiliza un vector de tamaño N. DyVAux (problema. superior). solución) DyVAux (problema. DyVAux (problema. subsolucion2. Elaboración de un Calendario Deportivo: Sea un campeonato deportivo. Combinar (subsolucion1. IN inferior. OUT solución : resultado) -> PROCEDURE DyVAux (IN problema : dato1. subsolucion2). DivideYVenceras (subproblema2)) Se puede hacer una formulación imperativa similar. puede suponerse que las competiciones se celebran en días sucesivos y ..n. superior. El problema consiste en elaborar un calendario de competición de forma que cada participante compita exactamente una vez con cada uno de los demás participantes. inferior. olución) ELSE Medio := Partir (inferior. medio+1. inferior. medio. subsolucion2 : resultado IF EsPequeño (inferior.. así que hablaremos de participantes en vez de deportistas o equipos. escribiremos una formulación más restrictiva pero bastante usual. ResolverDirectamente. superior : 1. Por concreción.N subsolucion1.N. Sin embargo. en caso contrario donde T(n) es la función de tiempo de DivideYVenceras para entradas de tamaño n.si n es pequeño T(n) = 2 T(n/2) + f(n). g(n) es el tiempo que tarda la función ResolverDirectamente en resolver problemas de pequeño tamaño (normalmente una constante) y f(n) es el tiempo necesario para partir el problema y combinar las subsoluciones. subsolucion1). es general.. solución) El esquema general se adapta a un problema concreto al sustituir los metasimbolos EsPequeño. para nuestros propósitos resulta indiferente el deporteobjeto de la competición. superior) THEN ResolverDirectamente (problema.n. subproblema2) => Combinar (DivideYVenceras (subproblema1) . resultado FUNCTION DivideYVenceras (problema : dato) : resultado -> EsPequeño (problema) }=> ResolverDirectamente (problema) | VALUE subproblemas -> Partir (problema) IN subproblemas == (subproblema1.Dato. Nótese que. OUT solución : resultado) -> VAR medio: 1. resultado PROCEDURE DivideYVenceras (IN problema : dato1. Si el tamaño de los dos subproblemas es el mismo (o casi). el tiempo de cómputo de la función DivideYVecneras se describe con la siguiente relación de recurrencia: g(n).

El método de fuerza bruta resulta sencillo. porque el día j-esimo cada participante solo puede competir con otro participante. Solo sirve como solución aquellas combinaciones de fila que cumplan las restricciones enunciadas en el párrafoanterior sobre las columnas de la tabla (las restricciones sobre las filas están garantizadas por el modo de generar los conjuntos P(i)). Dado que el numero de participantes de n. Primero se obtiene para cada participante i. Si hay varios calendarios validos. la solución del problema puede representarse en una tabla de dimensión nx(n-1). el conjunto P(i) de todas las permutaciones posibles del resto de los participantes con los que debe competir. 1<=i<=n.. Se supone también que cada participante tiene asignado un número comprendido entre 1 y N. se elige uno cualquiera. 1<= i<=n. es decir. es decir. Por tanto. la columna j también contiene números distintos.n}-{i} ahora se completan las filas de la tabla de todas las formas posibles. incluyendo en cada fila i algún ejemplo de P(i). Para simplificar el problema. 1<=j<n. Se necesitan elaborar n-1 competiciones por participantes. resultan nx(n-1)!=n! formas de rellenar la tabla. Se dispone de una solución inmediata aplicando fuerza bruta. se supone que el numero de participantes es una potencia de dos. La siguiente figura describe visualmente parte de la elaboración de la tabla.que cada participante compite una vez por día. A su vez. contiene el numero del participante contra el que el participante i-esimo compite el día j-esimo. Cada conjunto P(i) consta de (n-1)! Elementos. hay n = 2k participantes para algún entero positivo k. Obsérvese que los números de participantes incluidos en la fila i de la tabla son distintos porque el participante i-esimo solo debe competir una vez con cada participante restante. pero es terriblemente ineficiente. El elemento (i. Sin embargo la aplicación de la técnica de divide y vencerás produce una solución mas sencillas aun pero muy eficientes. el conjunto de permutaciones de los números {1. días 1 participantes 1 2 2 1 1 2 3 1 2 3 4 2 1 4 3 3 4 1 2 4 3 2 1 1 2 3 4 5 6 7 1 2 3 4 5 6 7 8 2 1 4 3 8 5 6 7 3 4 1 2 7 8 5 6 4 3 2 1 6 7 8 5 5 6 7 8 1 2 3 4 6 5 8 7 4 1 2 3 7 8 5 6 3 4 1 2 .j)±esimo de la tabla.

es decir. es más complejo.N... por ejemplo. la unión de estos subcalendarios no forma un calendario completo para el campeonato de 2k participantes. de numeración comprendida entre 1 y 2k-1 y otro para los participantes comprendidos entre 2k-1 +1 y 2k . CompletarTabla (inf. PROCEDURE Calendario ( INOUT tabla : (1.8 7 6 5 2 3 4 1 Se distinguen dos casos.1 : = sup. donde se aplica divide y vencerás para resolver el problema y que se aprovecha de la simetría de la solución. En efecto. Completemos primero la parte de los participantes de numeración inferior. Veamos otra estrategia. El problema puede reducirse a dos sub problemas de tamaño 2k-1 si se elaboran independientemente dos subcalendarios de tamaño 2k x(2k-1 -1): uno para los participantes.1. medio+1. IN sup :1. sup.. inf. ya que a unión de los dos calendarios tiene un tamaño 2k x(2k-1 -1). la mitad izquierda de la tabla. El calendario de los participantes de numeración superior se completa de forma similar con los números de los participantes de numeración inferior. que es mucho mas eficiente que la solución de fuerza bruta. tabla).N. CompletarTabla (medio+1. para k>1.N-1) -> PROCEDURE FormaTabla (IN inf : 1.N-1) -> VAR medio : 1..1 := inf ELSE medio := (inf + sup) Div 2. el resto del calendario se puede construir fácilmente. El subcalendario del primer participante es sencillo porque basta con que compita en días sucesivos con los participantes de numeración. puede decirse que el "tamaño" del problema es 2k (sabemos que el calendario tendrá un tamaño de 2k x(2k-1 -1) posiciones). medio. Sin embargo. también de orden de complejidad cuadrática. tabla) Este sistema de ecuacionesdefina una función de tiempo del orden de O(n2).. mediante divide y vencerás. FormarTabla (medio+1. superior en orden creciente de numeración. tabla).2n .N) 1. OUT tabla : (1. El caso recursivo. .N.N)1. faltando 2k x2k-1 celdas para completar el calendario total. medio. rotando dicha secuencia a la derecha.N IF inf = sup-1 THEN tablainf. El caso básico se da cuando solo hay dos participantes. Por fortuna. sup. La idea consiste en añadir inicialmente a la tabla una columna "ficticia" de índice j=0.sup-1.. sucesivamente con los participantes 2k-1 +1. que almacena los índices de las filas. medio.. medio. tablasup. tabla). La solución es directa porque se celebra una sola competición entre ambos. El siguiente participante toma esta secuencia y realiza una fácil permutación de la misma que le garantiza el respeto de las restricciones de la solución.. Después se genera.N. FormarTabla (inf. faltan por elaborar las competiciones cruzadas entre los participantes de numeración inferior y los de numeración superior.1.. Si el numero de participantes es 2k . El algoritmo descrito se expresa a continuación.. Este proceso se repite para el resto de los participantes de numeración inferior. cuando hay más de dos participantes. sup-1. Finalmente se completa la mitad derecha de la tabla (correspondiente al cruce de los dos ¡ .

WHILE (i1<=medio) ^ (i2<=sup) DO IF vectori1 << vectori2 THEN vectorAuxj :=vectori1. j := inf.= vectori2. INOUT vector : INTEGER1.N IF inf < sup THEN medio := (inf+sup) Div 2. inf. para obtener un único vector ordenado. El algoritmo resultante es: PROCEDURE Ordenar (INOUT v : INTEGER1. los valores de las casillas (k. Este proceso de mezcla es realizado por un procedimiento auxiliar.grupos de equipos cuyos subcalendarios se han generado por divide y vencerás).. 1. que obviamente ya esta ordenado. Para el caso general. i1.. la combinación de los dos subvectores ya ordenados es fácil. índice : INTEGER i1 := inf.m y vm+1.s un vector de índice inferior i e índice superior s. OrdenarAux (vector. OrdenarAux (vector.. basta con mezclar los dos subvectores.j a partir de las casillas tablak... En esta última etapa. medio). es decir. sup). Mezclar (vector. i2 := i2 + 1 . i2 := medio + 1. medio+1. los componentes tablai..s . j : INTEGER. sup : 1.N. La partición puede hacerse por la mitad si se toma un índice m=[(i+s)/2] y dos subvectores vi.N) -> (* ordenación por mezcla *) PROCEDURE OrdenarAux (INOUT Vector : INTEGER1.N) -> VAR Medio : 1.l ya completadas. IN inf.1.. de acuerdo con las siguientes expresiones de los índices: i = (k + n/2) Mod (n+1) j = (1 + n/2) Mod n De esta forma se rellenan las casillas aun vacías.. IN medio: INTEGER. Ordenación de un Vector por Mezcla: La ordenación de un vector es un problema que se presta fácilmente a la aplicación de la técnica de divide y vencerás.. IN sup : INTEGER. mediante comparaciones de sus elementos sucesivos. medio.. i2.N.N. inf.l). sea vi. N) El procedimiento para realizar la mezcla de los subvectores ordenados es: PROCEDURE Mezclar ( IN inf : INTEGER. El caso básico corresponde a un subvector de un solo elemento. siendo 1<=k<=n y 0<=l<=(n/2)-1. sup) OrdenarAux (v.N) -> VAR vectorAux : INTEGER1. i1 :=i1 + 1 ELSE vectorAuxj .

sup DO vectorindice := vectorAuxindice El algoritmo resultante es sencillo conceptualmente. las ecuaciones anteriores se resuelven por sustituciones sucesivas. La matriz C tiene n2 elementos. es decir. de forma que las ecuaciones de recurrencia de la función de tiempo son: T(n) = a. de dimensión nxn.) las submatrices A y B pueden partirse en cuatro submatrices de dimensión (n/2)x(n/2).. El algoritmo anterior. Multiplicación de Matrices: Sean dos matrices. Es fácil analizar la complejidad del algoritmo para un vector de longitud n. es decir. pero mantenga la complejidad asintótica calculada. necesita copiar el vector auxiliar completo en el principal. resultando: T(n) = 2T(n/2) + bn= =2K T(n/2K) + kbn = an + bn log2 n El algoritmo de ordenación por mezcla es óptimo en tiempo de ejecución. El cálculo de cada elemento Cij requiere n multiplicaciones. por sencillez. que n es una potencia de dos.. la técnica de divide y vencerás sugiere un algoritmo distinto. A y B. Los únicos inconvenientes que presenta es que el procedimiento de mezcla necesita gran capacidad de almacenamiento (para dos copias del vector) y que. b=cte Si n es una potencia de 2. La operación de mezcla es proporcional a n.j := j + FOR índice IN i1. (Si n no es un potencia de dos. n>1. que existe un entero no negativo k tal que n=2k. J := j + 1 FOR índice In inf. además de mezclar. Si el producto AxB tiene la forma: A11 A12 B11 B12 C11 C12 A21 A22 B21 B22 C21 C22 Entonces: C11 = A11*B11 + A12*B21 C12 = A11*B12 + A12*B22 C21 = A21*B11 + A22*B21 C22 = A21*B12 + A22*B22 ¢ . J := j + 1 FOR índice IN i2. Supongamos. proviene directamente de la definición matemática del producto de matrices. n=1. pueden añadirse las filas y columnas de ceros necesarias para formar una dimensión que sea potencia de dos.j)-esimo se forma multiplicando cada elemento de la final i-esima de A por el elemento correspondiente de la columna j-esima de B y sumando los productos parciales.. n =2k para algún k. así que el tiempo total del algoritmo de multiplicación es de orden O(n3). Puede diseñarse un algoritmo de mezcla más complejo que mejore ambos aspectos.sup DO vectorAuxj := vectorindice . que podemos llamar algoritmo convencional de multiplicación de matrices. Sin embargo. a=cte 2T(n/2) + bn. La matriz productoC=AxB también es una matriz de nxn cuyo elemento (i.medio DO vectorAuxj := vectorindice.

dado que la complejidad respectiva de estas operaciones es O(n3)n y o(n2). aunque fuera a costa de un mayor numero de sumas de matrices. tal que Eo es el estado inicial del problema y deben tomarse n decisiones d.Para n=2. asimismo. Solamente al final se sabe cuál es la mejor de todas. Dos submatrices de (n/2)x(n/2) pueden sumarse en un tiempo bn2. evitándose una explosión combinatoria en la producción de las secuencias y consiguiéndose soluciones más eficientes en cuanto a tiempo de ejecución. Supongamos que tenemos un problema que satisface el principio de optimalidad. La existencia de un algoritmo eficiente para la multiplicación (en realidad. pero para n>2 las submatrices Cij se calculan mediante multiplicaciones (recursivas) y sumas de submatrices de dimensión (n/2)x(n/2).vn} el conjunto de valores de decisión posibles para la decisión d1. 1<i<N1. Sea D = { v1 .. una secuencia óptima de decisiones respecto a E0 es la mejor secuencias de decisión { Vli Sli }. una característica es que el programa "aprende "dinámicamente de las decisiones que toma. de forma que no se ha conseguido ningún ahorro sustancial de tiempo. los elementos Cij se calculan mediante algunas multiplicaciones y sumas de números. Eli el estado del problema tras la elección del valor vli 1<i<n1 y Sli una secuencia óptima de decisiones respecto al estao Eli. Además. todo problema resoluble con esta técnica debe de satisfacer el principio de optimalidad. sea. En la programación dinámica todos los subproblemas se resuelven de acuerdo con criterio de tamaño creciente y los resultados de subproblemas más pequeños se almacenan en algún tipo de estructura de datos (normalmente tablas) para facilitar la solución de los problemas más grandes. El método es eficiente porque una vez que se toma una decisión en un paso. porque si hay d opciones para cada una de las n decisiones. Entonces. La resolución de este sistema de ecuaciones nos dice que O(T(n))=OT(n3). conduciendo de forma directa a la solución. Esta vez se necesita producir varias secuencias de decisiones. pero de una manera menos directa que en el caso voraz. El algoritmo de Strassen calcula las cuatro submatrices Cij empleando 7 multiplicaciones y 18 sumas o restas de matrices. Este principio establece que "una secuencia óptima de decisiones que resuelve un problema debe cumplir la propiedad de que cualquier subsecuencia de decisiones también debe ser óptima respecto al subproblema que resuelva ". no todos los problemas pueden resolverse de esta manera. Programación Dinámica Principios de programación dinámica Se ha visto que la técnica voraz se aplica a problemas cuya solución puede formularse como el resultado de una secuencia de decisiones. Podemos formalizar algo más la idea básica. para cualquier operación de las anteriores) significaría la existencia de un algoritmo similar para las demás. £ . La programación dinámica (también llamada planificación dinámica) es una técnica de programación que también permite resolver problemas mediante una secuencia de decisiones. Sin embargo. como inversión de una matriz o hallar su determinante. asegurando que la secuencia de decisiones es la mejor de las posibles. no se reconsidera en el futuro. porque la multiplicación esta relacionada con otras operaciones sobre matrices mas usuales. Sin embargo. 1<i<n. No es fácil establecer una definición de la programación dinámica. el número de secuencias de decisión es exponencial sobre el número de decisiones. Podría conseguirse mas eficiencia si lográramos realizar menos multiplicaciones de matrices. Usando una técnica de fuerza bruta. interesa encontrar algoritmos mas eficientes. resultará un total de d secuencias posibles de decisión. siendo b alguna constante. De esta forma se reduce al número total de subsecuencias generadas.

1<i<n .) Una solución dinámica para problema ( k. Sea G(x1. Esquema de Algoritmos de Vuelta Atrás: Sea (x1..n ). a tomar... La formulación delantera expresa la decisión de Xl . La ecuación general relaciona la secuencia óptima en una etapa i con la decisión tomada en la etapa i y la subsecuencia óptima en la etapa posterior i+1.. INOUT solucion : elemento1. Supongamos que también existe algún predicado R que determina si un camino (x1.dl. si este subproblema de simboliza como problema (k.. Algoritmos De Vuelta Atrás Existen un alto número de problemas que pueden formularse como la búsqueda de la mejor solución o del conjunto de todas las soluciones que satisfacen ciertas condiciones.. sólo que en orden contrario.. Por supuesto.. a partir de la secuencia de decisiones Xi+1 Xn ( es la clase de formulación adoptada hasta ahora ).1 ) debe expresarse en términos de los valores de decisión existente para decisiones d1 y el subproblema problema ( k+1...xi) el conjunto de todos los valores posibles de xi+1 tales que (x1. La expresión inicial de la ecuación de recurrencia.xi+1) es un camino hasta el estado del problema.n son aquellos valores generados por G que satisfacen A.n) -> ¤ ¤¤ ¤ .Xn la secuencia de decisiones necesaria para resolver el problema.. 1<k<n. La formulación trasera expresa la decisión de Xi. del gusto del programador.xi+1) es falso si el camino (xi. Otros problemas satisfacen el principio de optimalidad.l). En algunos problemas de optimización se conoce un criterio óptimo de selección que puede usarse de forma voraz. ( Obsérvese que vamos a usar la técnica de resolución de problemas por generalización para después poder realizar una particularización de la solución obtenida. que es problema ( n.xi+1) no puede extenderse para alcanzar un nodo de respuesta.xi+1) termina en un nodo de respuesta. El Algoritmo de Vuelta Atrás se especifica de la forma siguiente: PROCEDURE Retroceso (IN k : INTEGER. debe existir una función de criterios que debe ser satisfecha por cada secuencia solución u optimizada por dichas secuencias solución si solo queremos la mejor. 1<i<n.1 ) resultante de aplicar cada valor de decisión. pudiéndose aplicar la técnica de programación dinámica.. la aplicación de la técnica de programación dinámica a un problema significa comprobar primero el principio de optimalidad y desarrollar después unas ecuaciones recurrentes del estilo de (1) y (2).....n ).. En resumen... partiendo como estado inicial de Ek-1. hay un caso en que la decisión d1 no va seguida por ninguna secuencia de decisiones....xi) el camino desde la raíz hasta un nodo de un árbol del espacio de estado. Sea X1 . tiene la ventaja ( quizás paradójica al tratar de un problema más pequeño ) de que proporciona una visión más general del problema en cuestión... además. La ecuación de recurrencia puede formularse de dos formas: delantera o trasera. todavía hay otros problemas peores que no queda mas remedio que realizar una búsqueda de la solución.. cada solución es el resultado de una secuencia de decisiones. entonces el problema completo es problema ( l. la ecuación de base establece el valor para la etapa n+1 en que no queda ninguna decisión Xi. 1<i<n.. Además. puede generalizarse la formulación del problema a cualquier subsecuencia de decisiones dk .. Sin embargo. sencillamente. La elección de una formulación delantera o trasera depende del problema considerado o. Por lo tanto. los candidatos para la posición i+1 del vector desolucion x1. a partir de la recurrentes con formulación trasera es igual que e la formulación delantera. Tiene sentido centrarse en un subproblema del problema inicial porque éste satisface el principio de optimalidad pero.El razonamiento anterior se refiere a la primera decisión d1 tomada desde el estado inicial E0 sin embargo.. Supongamos que existe algún predicado acotador A tal que A(x1.

pues tenemos ya una solucion mayor. A). Retroceso (k+1. pero necesitamos una solución eficiente. El problema del viajante Problema: Dado un grafo no dirigido. evitando así la exploración de gran parte de al estructura.k) THEN << guardar µsolucion¶ >>. Este mismo proceso se repite en el resto de nodos del árbol. El procedimiento no hace ninguna llamada recursiva cuando k = N+1 o cuando ningún nodo generado por G satisface el elemento posible que satisfacen A se añade una solución particular. k-1) DO Solucion k := nodo. solucion). se comprueba si se ha encontrado una solucion. Se sale del bucle FOR cuando no quedan mas valores para solución terminando la llamada actual al algoritmo. encontrar un ciclo simple de costo mínimo que pase por todos los nodos. Posibilidades: . Problema de optimización. 1. La solución exacta puede requerir un orden factorial o exponencial: el problema de la explosión combinatoria. donde la solución está formada por un grupo de elementos en cierto orden: podemos aplicar el esquema voraz. Normalmente.VAR nodo : elemento FOR noso IN G(solucion. y que al seguir avanzando en el árbol (mediante la aplicación de varios pasos de retrocesos) se alcanza un nodo que requiere k+1 colores. La técnica de ramificación y acotacotacion aplica de la siguiente manera: Supóngase que al recorrer un árbol y alcanza una hoja se tiene una solucion con k colores. Así. solucion) La llamada inicial del algoritmo es Retroceso(1. Ramificación (Bifurcacion) Y Acotación Los métodos de Ramificación y Acotación constituyen un a variante de las técnicas de retroceso para problemas donde se trata de encontrar el valor máximo o mínimo de cierta función objeto (esto suele suceder en los problemas de programación lineal entera). Se hace necesario utilizar algoritmos heurísticos: Un algoritmo heurístico (o simplemente heurística) puede producir una buena solución (puede que la óptima) pero también puede que no produzca ninguna solución o dar una solución no muy buena. La estructura de algoritmo voraz se puede utilizar para construir procedimientos heurísticos: hablamos de heurísticas voraces. se basa en un conocimiento intuitivo del programador sobre un determinado problema. En este punto podemos retroceder (y no seguir avanzando por mas ramas). k) THEN IF R(solucion. Es un problema NP. 1. 1. Después simplemente se llama recursivamente al algoritmo para generar los estados descendientes. Algoritmos Heuristicos Existen muchos problemas para los cuales no se conocen algoritmos que puedan encontrar la solución de forma eficiente: problemas NP-completos. Objetivo: obtener buenas soluciones en un tiempo de ejecución corto. IF R(solucion. k sirve de cota inferior al retroceso. completo y ponderado G = (V.

c2.. es probable que no sepamos resolverlo de manera precisa y completa utilizando un algoritmo polimico en tiempo.. pero garantizando que se forme un ciclo.. Empezar con un grafo sin aristas. ó bien. 2. Las aristas son los candidatos. próximas a la óptima.1. 1) Coste: 15+20+10+45+50=140 Heurística voraz 2 ± Una solución será un conjunto de aristas (a1. Sin embargo. 5)) Coste = 10+15+20+45+50 = 140 Conclusiones: Ninguno de los dos algoritmos garantiza una solución óptima. Para este tipo de problemas. Empezar en un nodo cualquiera. Este problema se puede resolver a través de otro aproximado. el orden de visita de los nodos. 2. . A continuación se ilustra este tipo de tratamiento de problemas al problema de recubrimiento de un grafico: Dado un grafo G=(V. Factible: una arista se puede añadir a la solución actual si no se forma un ciclo (excepto para la última arista añadida) y si los nodos unidos no tienen grado mayor que 2. a2. como es calcular el ajuste maximizal del grafo G.. 4). 2) Coste: 30+15+25+10+45=125 Empezando en el nodo 3. Algoritmos De Aproximación Dado un problema NP completo. normalmente ambos dan soluciones buenas. 3). se trata de encontrar un conjunto con el menor numero de vértices tal que toda arista sea incidente por lo menos de un vértice de V. Posibles mejoras: buscar heurísticas mejores.. 4. 5. sin importar el orden. Heurística voraz 1 ± Una solución será un cierto orden en el conjunto de nodos (c1.. 3. resulta parcialmente interesante que estos garanticen una cota en el margen de imprecisión. 3. . Función de selección: de los nodos candidatos seleccionar el más próximo al último (o al primero) de la secuencia actual (c1. Solución: (5. Hacer igual que en el algoritmo de Kruskal. Se trata de calcular un subconjunto A¶ de aristas tal que dos aristas .. (1. Solución: ((2. c2.A). ‡Ejemplo. Inicialización: seleccionar un nodo cualquiera. Selección: seleccionar la arista candidata de menor coste. Solución: (1. 5). 2). (1. repetir la heurística 1 con varios orígenes. Ejemplo. 4. En cada paso moverse al nodo no visitado más próximo al último nodo seleccionado. Acabamos cuando tengamos n nodos. los algoritmos que no conducen a una solución óptima se llaman algoritmos de aproximación. (3. . Empezando en el nodo 1. ca). a partir de la solución del algoritmo intentar hacer modificaciones locales para mejorar esa solución. (4. an-1) que formen un ciclo hamiltoniano. Los nodos son los candidatos. Sin embargo... cn).

También veremos los diferentes tipos de formas y tamaños o medidas en que se pueden almacenar y representar los datos y estructuras en un algoritmo o programa. también por la propia definición. entre otros.cualquiera de A¶ no tengan ningún vértice común y toda arista de A-A¶ comparta algún vértice común con una arista de A¶. Esto es evidente. En el mismo podremos encontrar los conceptos de algoritmo y algunos de sus componentes. divide y vencerás.análisis y diseño. el voraz. Motivación Como estudiantes de la Facultad de Ciencias y Tecnología " Escuela de Informática y Computación " de la Universidad Dominicana Organización y Métodos O&M con aspiraciones de iniciarnos como Ingeniero en Sistemas y Computación. por lo menos la mitad de los vértices de M deben pertenecer a un recubrimiento. la recursividad e iteración. El procedimiento para construir un ajuste maximizal de un grafo G consistiría en ir tomando aristas de G. Objetivos General : Posibilitar la estudiante alcanzar una visión sistemática de lo que conocemos sobre Los Algoritmos Computacionales. reglas. vital para el desarrollo de aplicaciones para computadorasy el manejo y dominio de la lógica de programación para resolver problemas. Con el objetivoinmediato de aprobar con los mejores meritos la asignatura de Algoritmos Computacionales. normas. En el siguiente trabajopretendemos presentar una serie de conceptoy definiciones propios del estudio de los Algoritmos. los diseños de estos últimos. de una en una y en cualquier orden e ir eliminando las incidentes al conjunto que se esta construyendo hasta recubrir todo en grafo. ya que por la definición de ajuste maximal. Finalmente veremos los que es la verificación y derivación de programas. los vértices incidentes a las aristas de M son un recubrimiento de G. Específicos : Introducir los conceptos propios sobre Algoritmo. que desde su aparición hasta nuestros días es. . tipos de algoritmos de búsqueda y ordenación así como sus aplicaciones. En ese mismo orden encontraremos las diferentes técnicaspara diseñarlos como son el método de la fuerza bruta. De igual forma podremos ver las definiciones y algunas características. En consecuencia. y seguirá siendo. su análisis y diseño. Este nuevo problema garantiza conseguir un recubrimiento que contiene no más de dos vértices del recubrimiento mínimo. su importancia en el mundo de las aplicaciones para computadoras y el manejo de lógica de programación. Para poder aplicar el nuevo problema aproximado. programación dinámica. donde daremos los conceptos básicos de semánticay sus tipos haciendo mayor énfasis en la semántica axiomática. ningún vértice perteneciente a M puede recubrir a mas de una arista en M. de vuelta atrás. así como los típicos ciclos utilizados en algoritmos y programas y los paso a tener en cuenta al momento de desarrollar un algoritmo iterativo o recursivo. Justificacion Es importante el estudio y conocimiento de lo que hoy conocemos como Algoritmos Computacionales. seria necesario demostrar que el conjunto de todos los vértices inciden a las aristas de un ajuste maximal M para un grafo G es un recubrimiento con no mas de dos veces el numero de veces el recubrimiento de tamaño mínimo.

por lo que para llegar a ser un programador eficaz se necesita aprender a resolver problemas de un modo riguroso y sistemático. Algoritmos + Estructuras de Datos = Programas. se le denomina algoritmo. (Fase de codificación. . se considera con Al-Khowarizmi el otro gran padre de la algoritmia ( ciencia que trata de los algoritmos). Ejecución y validación del programa por la computadora. titulo uno de sus mas famosos libros. búsqueda. 3. Visualizar sus ventajas e importancia. el gran matemático griego (del siglo IV antes de Cristo) que invento un método para encontrar el máximo común divisor de dos números. multiplicar y dividir números decimales. Definir sus tipos y variantes. 2. (Análisis del problema y desarrollo del algoritmo). Aunque la popularización del término ha llegado con el advenimiento de la era informática. El eje central de esta metodología es el concepto. Un algoritmo es un método para resolver un problema. La palabra algoritmo se deriva del nombre latinizado del gran Matemático Árabe Mohamed Ibn Al Kow Rizmi. Fue Fibinacci. Esta ecuación será de una de las hipótesis fundamentales consideradas en esta obra. Los pasos para la resolución de un problema son: 1. ya tratado. etc. significándonos que solo se puede llegar a realizar un buen programa con el diseño de un algoritmo y una correcta estructura de datos. matemático persa que vivió durante el siglo IX y alcanzo gran reputación por el enunciado de las reglas para sumar. que describe la secuencia ordenada de pasos que conducen a la solución de un problema dado. de algoritmo. El lenguajealgorítmico es aquel por medio al cual se realiza un análisis previo del problema a resolver y encontrar un método que permita resolverlo. Marco Historico Un algoritmo es un conjunto de operaciones y procedimientosque deben seguirse para resolver un problema. Expresar el algoritmo como un programa de lenguaje de programación adecuado. Diseño de algoritmo. 2. Modula-2 y Oberon. La resolución de un problema exige el diseño de un algoritmo que resuelva el problema propuesto. El conjunto de todas las operaciones a realizar y e orden en que se deben efectuarse. la traducciónal latín del apellido de la palabra algorismus derivo posteriormente en algoritmo.y y y y y y Proporcionar una idea de su uso. Desglosar sus variantes (ordenación. algoritmo proviene de Mohammed alKhowarizmi. Proporcionar conceptos sobre su análisis y diseño.) 3. restar. donde se recogía el sistema de numeración hindú y el concepto del cero. Es un método para resolver un problema mediante una serie de datos precisos. el que tradujo la obra al latín y el inicio con la palabra: Algoritmi Dicit. inventor de Pascal. el cual escribió sobre los años 800 y 825 su obra Quitad Al Mugabala. Euclides. Generalidades El programador de computadoras es ante que nada una personaque resuelve problemas. definidos y finitos. Proporcionar concepto sobre las técnicas de diseño. ). A la metodología necesaria para resolver problemas mediante programas se denomina Metodología de la Programación. El profesor Niklaus Wirth.

inicio leer el pedido examinar la ficha del cliente si el cliente es solvente aceptar pedido. el algoritmo será siempre el mismo. 3. cordero). de modo que sin algoritmo no puede existir un programa. Si se sigue un algoritmo dos veces. Proceso: elaboración de la receta en la cocina. rechazar pedido fin Diseño del Algoritmo: En la etapa de análisis del proceso de programación se determina que hace el programa. pero cualquiera que sea el lenguaje. en caso contrario rechazara el pedido. Los algoritmos son independientes tanto del lenguaje de programación en que se expresan como de la computadoraque lo ejecuta. Esta examina en su banco de datos la ficha del cliente. la . los algoritmos son más importantes que los lenguajes de programación o las computadoras. 4. Ejemplo de Algoritmo: Un cliente ejecuta un pedido a una fábrica. es decir. un aspecto muy importante será el diseño de algoritmos. En cada problema el algoritmo se puede expresar en un lenguaje diferente de programación y ejecutarse en una computadora distinta. Salida: terminación del plato (por ejemplo. Dada la importancia del algoritmo en la ciencia de la computación. debe tener un numero finito de pasos. una receta de un plato de cocina se puede expresar en español. sin embargo. ingles o francés. Tanto el lenguaje de programación como la computadora son los mediospara obtener un fin: conseguir que el algoritmo se ejecute y se efectúe el proceso correspondiente. En el algoritmo de receta de cocina citado anteriormente se tendrá: Entrada: ingrediente y utensilios empleados. 2. Proceso y Salida. Características de los Algoritmos: Las características fundamentales que debe cumplir todo algoritmo son: y y y Un algoritmo debe ser preciso e indicar el orden de realización de cada paso. Así. La definición de un algoritmo debe definir tres partes: Entrada. se debe obtener el mismo resultado cada vez. Los pasos del algoritmo son: 1. En esencia. Redactar el algoritmo correspondiente. 5. o sea. Un algoritmo debe estar definido. en una analogía con la vida diaria. Un lenguaje de programación es tan solo un medio para expresar un algoritmo y una computadora es solo un procesador para ejecutarlo. los pasos para la elaboración del plato se realizaran sin importar el idioma del cocinero. Los métodos mas eficaces para el proceso de diseño se basan en el conocido por Divide y Vencerás.Para llegar a la realización de un programa es necesario el diseño previo de algoritmo. si el cliente es solvente entonces la empresa acepta el pedido. Si se sigue un algoritmo se debe terminar en algún momento. El diseño de la mayoría de los algoritmos requiere creatividady conocimientos profundos de la técnica de la programación. En la etapa de diseño se determina como hace el programa la tarea solicitada. en caso contrario. En la cienciade la computación y en la programación. por ejemplo. Un algoritmo debe ser finito. la solución de un problema se puede expresar mediante un algoritmo.

Comunicaciones. Los módulos pueden ser planeados. etc. Cualquier programa bien diseñado consta de un programa principal (el modulo de nivel mas alto) que llama a sub programas (módulos de nivel mas bajo) que a su vez pueden llamar a otros sub programas. El proceso de romper el problema en cada etapa y expresar cada paso en forma más detallada se denomina refinamiento sucesivo. etc. forma aproximada o algunos casos. su facilidad de programarlo. corto. Eficiencia: Relación entre los recursos consumidos y los productos conseguidos. ¿Cuántos recursos de tiempo y memoria consume el siguiente algoritmo sencillo? i:= 0 a[n+1]:= x repetir i:= i + 1 . Recursos consumidos: Tiempo de ejecución. Lo que se consigue: Resolver un problema de forma exacta. procesadores. Combinar el modulo con los módulos anteriores. Si es necesario. Comprobar el modulo. comprobados y depurados independientemente (incluso por diferentes programadores) y a continuación combinarlos entre si. El diseño del algoritmo es independiente del lenguaje de programación en el que se vaya a codificar posteriormente.resolución de un problema complejo se realiza dividiendo el problema en sub problemas y a continuación dividir estos sub problemas en otros de nivel mas bajo. Criterio empresarial: Maximizar la eficiencia. Los programas estructurados de esta forma se dice que tienen un diseño modular y el método de romper el programa en módulos más pequeño se llama Programación Modular. fácil de entender. 4. Análisis De Algoritmos Recursos De Computadores Y Complejidad Algoritmo: Conjunto de reglas para resolver un problema. robusto. Un algoritmo es mejor cuantos menos recursos consuma. Memoria principal: Entradas/salidas a disco. Cada sub programa es resuelto mediante un modulo (sub programa) que tiene un solo punto de entrada y un solo punto de salida. Su ejecución requiere unos recursos. Recursos consumidos: Ejemplo. codificados. depurar el modulo. Este método se conoce técnicamente como diseño descendente (Top Down) o modular. El proceso implica la ejecución de los siguientes pasos hasta que el programa se termina: y y y y programar modulo. El proceso que convierte los resultados del análisis del problema en un diseño modular con refinamiento sucesivo que permitan una posterior traducción al lenguaje se denomina diseño de algoritmo. hasta que pueda ser implementada una solución en la computadora.

Calcular la media de una matriz de NxM. con los límites del FOR. ¿Existe una cota inferior y superior del número de ejecuciones? ¿Se puede convertir en un FOR? El análisis de algoritmos también puede ser a posteriori: implementar el algoritmo y contar lo que tarda para distintas entradas. En particular...1 ms N= 5.2 s . Tamaño de los datos de entrada. Instrucciones ejecutadas por el algoritmo. -.. Los factores externos no aportan información sobre el algoritmo. ¿Cuánto tiempo. pero ¿qué significa T(N)? Tiempo de ejecución en segundos. Programa "cifras. Ejemplo. de la máquina..exe": N= 4. Bucles FOR: Se pueden expresar como una sumatoria. T(5)= 5 ms N= 6. de lo que haya en a. T(N) = N+1. Peor caso. Mejor caso y peor caso según la condición. con los segundos que tardan las operaciones básicas correspondientes. T(N) = 2N + 4. El ordenador donde lo ejecutemos: 286.. Operaciones de entrada salida: Otra unidad de tiempo. Asignación de tiempos. IF y CASE: Estudiar lo que puede ocurrir. Normalmente usaremos la notación T(N)=. Caso promedio. *. Conclusión: Estudiar la variación del tiempo y la memoria necesitada por un algoritmo respecto al tamaño de la entrada y a los posibles casos. de las estructuras de datos utilizadas. o una constante diferente.): Una unidad de tiempo.. o alguna constante. La implementación que haga el programador del algoritmo. de los tipos de datos. T(6)= 0. Contenido de los datos de entrada. Bucles WHILE y REPEAT: Estudiar lo que puede ocurrir. ¿De qué depende? De lo que valga n y x... T(N) = bN + c. El lenguaje de programación y el compilador usado. Operaciones básicas (+. para el conteo de instrucciones.? Sabemos que cada ejecución lleva un tiempo constante. Algunas reglas básicas. T(4)= 0. externos no aportan información sobre el algoritmo... Media de todos los posibles contenidos. de forma aproximada (y parametrizada). Pentium III. luego se diferencia en una constante con los anteriores. La ejecución más lenta posible. cuántas instrucciones. Cray. :=.. ¿Tardarán todas lo mismo? Ejecuciones del bucle principal. Ejemplo. El contenido favorece una rápida ejecución... En general los recursos dependen de: Factores externos.hasta a[i] = x Respuesta: Depende. Suponiendo que b y c son constantes. ¿Se puede predecir cuándo se cumplirán las condiciones? Llamadas a procedimientos: Calcular primero los procedimientos que no llaman a otros.. Mejor caso.

Dadas f y g de N en R+. para valores suficientemente grandes (asintóticamente) sin considerar constantes. Q (f)=Q (g) g(n) ii) limn¥ ® f(n) = 0 Þ O(f) Í O(g). -g))? P5. "Valores de n sufic. O(f+g) = O(max(f.": no nos importa lo que pase para valores pequeños.g) = O(max(f. 2n+1 Î O(n). Medidas Asintoticas Notación asintótica: El tiempo de ejecución T(n) está dado en base a unas constantes que dependen de factores externos. n Î O(n2) Þ 2n+1 Î O(n2) P2. se cumple: i) O(f) = O(g) Û f Î O(g) y g Î O(f) ii) O(f) Í O(g) Û f Î O(g) ¿La relación de orden entre O(. W (T): Orden inferior de T.": nos quitamos las constantes. O(f)= { t: N ® R+ / $ c Î R+. para valores de n suficientemente grandes.) es completa? Dadas f y g.5 min ¿Qué conclusiones podemos extraer? Análisis a priori: Evitamos la implementación. de N en R+. W (f)=W (g). si el algoritmo es poco eficiente. T(7)= 10 s N= 8.. llamamos orden de f al conjunto de todas las funciones de N en R+ acotadas superiormente por un múltiplo real positivo de f. g)). Dadas f y g. "Funciones acotadas superiormente por un múltiplo de f.. O(T): Orden de complejidad de T. La definición es aplicable a cualquier función de N en R. Q (T): Orden exacto de T. Si f Î O(g) entonces O(f) Í O(g). no sólo tiempos de ejec. Si f Î O(g) y g Î O(h) entonces f Î O(h).. Dadas f y g de N en R+.. Podemos comparar con otros algoritmos. W (f+g) = W (max(f+g)) ¿Y para los Q (f+g)? ¿Es cierto que O(f . Orden de complejidad de f(n): O(f) Dada una función f: N ® R+. Si f Î W (g) y g Î W (h) entonces f Î W (h) Ej. T(8)= 3. ¿se cumple O(f)Í O(g) ó O(g)Í O(f)? P4. ¿Cómo es la relación para los W ? P3.. " n ³ n0: t(n) £ c·f(n) } Nota: O(f) es un conjunto de funciones. Propiedades P1. se cumple: i) limn¥ ® f(n) Î R+ Þ O(f)=O(g). u omega de T. $ n0 Î N. W (g) Í W (f) g(n) . Nos interesa un análisis que sea independiente de esos factores. no una función.N= 7. Grandes. Podemos hacer previsiones. Notaciones asintóticas: Indican como crece T.

O(f)=O(g) Û Q (f)=Q (g) Û f Î Q (g) Û W (f)=W (g) P7. encontrar la función f más simple tal que t Î O(f)..a. k2. . Dadas f y g de N en R+. o variables T(N.. M(B. nm Î N. n2. Ejemplo. . Orden condicionado de f(n): O(f | P) Dada una función f: N ® R+....... k2 ³ n2 . $ n0 Î N. Para cualquier f y g. $ n1. " k1 ³ n1 .. nm) suficientemente grandes.. .m. ¿Qué relación hay entre O(log2 n) y O(log10 n)? P6.n. t(n) = 2n2/5 + 3p /2. t(n) Î O(n2). Algoritmo de búsqueda binaria: Si N es potencia de 2 el estudio se simplifica. llamamos orden de f al conjunto de todas las funciones de Nm en R+ acotadas superiormente por un múltiplo real positivo de f. a. l. ‡Relación de orden entre O(.. y del tiempo de inicialización b y de ejecución de un paso a. ¿Qué relación hay entre los siguientes órdenes? O(n+m).. k2. se cumple: i) limn¥ ® f(n) Î R+ Þ O(f) = O(g) g(n) ii) limn¥ ® f(n) = 0 Þ O(f) Ì O(g) g(n) iii) limn¥ ® f(n) = +¥ Þ O(f) É O(g) g(n) Notación con varios parámetros: En general. llamamos orden de f según P (o condicionado a P) al conjunto: O(f | P)= { t: N ® R+ / $ c Î R+... para funciones con varios parámetros. el tiempo y la memoria consumidos pueden depender de muchos parámetros. T(N) = T(N.xN ® R+) Ej. b) = a·N + b El tiempo depende del tamaño del problema N. k) = kB+l+n+2kn Orden de complejidad de f(n1. tenemos W (f | P) y Q (f | P).. f Î O(g | false). O(n+2m) Notaciones condicionales: En algunos casos interesa estudiar el tiempo sólo para ciertos tamaños de entrada. nm): O(f) Dada una función f: Nm ® R+. ¿O(f) « O(f | P)? Ordenes De Complejidad Uso de los órdenes de complejidad: Dado un tiempo t(n). Ejemplo.. n2.) = Relación de inclusión entre conjuntos. O(f)= { t: Nm ® R+ / $ c Î R+. Ejemplo.." km ³ nm : t(k1. f: Nm ® R+ (f: Nx. O(nm) O(n2)... O(f) = O(f | true). km) £ c·f(k1. y P: N ® B. " n ³ n0: P(n) Þ t(n) £ c·f(n) } De igual forma. Las propiedades se siguen cumpliendo ® Demostrarlo. .. Ej.b). y que más se aproxime asintóticamente. .. Memoria en una tabla hash. km) } De la misma forma. podemos extender los conceptos de W (f) y Q (f). para valores de (n1. Dadas f y g de N en R+. . Podemos suponerlos constantes T(N).P5.

W (f)= { t: N ® R+ / $ c Î R+.. å im Î O(nm+1) i=1 i=1 i=1 Si hacemos una operación para n. d Î R+.. Relación de orden: igual que antes. asintóticamente y salvo constantes. Ejemplo.. Ì O(2n) Ì O(n!) Ì O(nn) ¿Qué pasa con las omegas? ¿Y con los órdenes exactos? El orden de un polinomio anxn+. El acto de diseñar un algoritmo puede considerarse como una tarea que difícilmente podrá ser del todo .. $ n0 Î N.) Ì O(n2) Ì O(n3) Ì . . Técnica de diseño de algoritmos Diseño de Algoritmos: Hasta ahora se han realizado algunos comentarios respecto a la necesidad de diseñar algoritmos correctos y eficientes utilizando los elementos de un lenguaje de programación . $ n0 Î N.. llamamos omega de f al conjunto de todas las funciones de N en R+ acotadas inferiormente por un múltiplo real positivo de f.. llamamos orden exacto de f al conjunto de todas las funciones de N en R+ que crecen igual que f. independientemente de la base. å i = n(n+1)/2 Î O(n2). " n ³ n0: c·f(n) ³ t(n) ³ d·f(n) } Notación o pequeña de f(n): o(f): Dada una función f: N ® R+. Orden exacto de f(n): Q (f): Dada una función f: N ® R+.. t Î O(g) ‡Se cumple que: O(c) = O(d). t(n) = amnm + am-1nm-1 + . +a1n + a0 t(n) Î o(amnm) ¹ o(nm) ¿o(amnm) Í O(amnm)? ¿o(t) Í O(t)? Costa de complejidad con frecuencia Algunas relaciones entre órdenes frecuentes: O(1) Ì O(log n) Ì O(n) Ì O(n·log n) Ì O(n·(log n)2) Ì O(n1.+a1x+a0 es O(xn). para valores de n suficientemente grandes.. Orden inferior u omega de f(n): W (f): Dada una función f: N ® R+. si p es un polinomio de menor grado que q. Q (f) = O(f) Ç W (f) = { t: N ® R+ / $ c.001.. " n ³ n0: t(n) ³ c·f(n) } La notación omega se usa para establecer cotas inferiores del tiempo de ejecución. O(c) Ì O(n) O(cn + b) = O(dn + e) O(p) = O(q). si p y q son polinomios del mismo grado.Es necesario en este momento mencionar algo sobre como hacerlo. siendo c y d constantes positivas. O(p) Ì O(q).±O(f) £ O(g) Û O(f) Í O(g) Û Para toda t Î O(f). 5. llamamos o pequeña de f al conjunto de todas las funciones de N en R+ que crecen igual que f asintóticamente: o(f)= { t: N ® R+ / lim t(n)/f(n) = 1}n¥ ® Esta notación conserva las constantes multiplicativas para el término de mayor orden. otra para n/2. Los logaritmos son del mismo orden. n/4. nnn å 1 = n Î O(n). aparecerá un orden logarítmico O(log2 n)...

automatizada. el uso de parámetros de acumulación al resolver problemas utilizando divide y vencerás. hay problemas cuya solución no puede hallarse sino mediante un proceso de búsqueda. y a pesar de que resulta mas adecuado en bastantes casos utilizar alguno de estos esquemas que realizar un diseño desde cero. tenemos una solución voraz. y el empleode tablas como estructura auxiliar para la resolución eficiente de problemas donde se aplica programación dinámica). su uso adecuado mediante el esquema de búsqueda con retroceso (o backtracking) permite ganar gran eficiencia respecto a soluciones de fuerza bruta. idear un algoritmo continua siendo una labor bastante creativa donde los conocimientos y la experiencia del propio diseñador tiene un papel fundamental. Muchos problemas pueden resolverse buscando una solución fácil y directa pero. podríamos utilizar un algoritmo general llamado algoritmo del museo británico. basado en la descomposición de un problema en subproblemas. su tarea se simplifica. siendo dicha solución finalmente adaptada al dominio original. El conocimiento de técnicas de diseño es solo un primer paso para el diseñador. Una forma de facilitar esta labor consiste en recurrir a técnicas conocidas de diseño de algoritmos. Si puede preverse que decisión conviene en cada etapa para producir cierto tipo de mejor resultado. Consideraciones generales Si el hábil programador dispone de un recetario de algoritmos de donde poder seleccionar el más adecuado para cada problema. se produzca cierto resultado. se decir. Se programa un computador de manera que parta de un conjunto de axioma matemáticos y los que use para reducir aleatoriamente teoremas validos. conviene conocer otros métodos de diseño de algoritmos que también resultan de utilidad práctica. dados uno datos de entrada valido. la solución es dinámica. pero con un poco de análisis puede encontrarse algoritmos más eficientes. Aun así. Este método. Este método de trabajo es practicable. solo puede tomarse tras considerar varias solucionesde otras etapas mas simples. Aprender los principiosbásicos del diseño de algoritmos podemos preguntarnos por un método aceptable. y quizás el mejor. a esquemas muy generales que pueden adaptarse a un problema particular al detallar las partes generales del esquema. Supongamos que disponemos de una especificación precisa. completa y consistente del problema a resolver y queremos obtener un algoritmo en el que. en general. otros son bastante complejos. y a métodos basados en transformaciones del dominio para encontrar una solución mas fácilmente a un problema en un dominio transformado. es organizar el diseño sobre un esquema de algoritmo o una técnica de diseño que haya demostrado su utilidad para otros problemas. si la decisión en una etapa. llamado de fuerza bruta. Nos estamos refiriendo a métodos basados en la mejora de la eficiencia (por ejemplo. a la vez bastante ineficiente. El esquema mas sencillo quizás sea el llamado divide y vencerás. puede ser muy directo. que debe . Si no nos importa la eficiencia del algoritmo. La investigaciónen esta área ha permitido descubrir un conjunto de métodos o esquemas de diseño hacia los cuales puede orientarse la realización de muchos algoritmos. puesto que existe un número reducido de esquema y técnicas de diseño. una tarea difícil. Por ultimo. algunos resultan inmediatos de resolver. a pesar de lo complejas que son las operaciones de búsqueda. El mas entendido. Todo problema algorítmico es un reto para su diseñador. El diseño de un algoritmo que resuelva un problema es. No obstante. Otros esquemas requieren un análisis minucioso del problema de forma que la solución se vaya construyendo en etapas.

con la experiencia. esto no es malo.completarse con otros conocimientos y. pero que debe evitarse siempre que se pueda. En principio. Lo más razonable es comprobar si el vector esta ordenado y. por lo que uno puede sentirse tentado a usar siempre. poco reflexionada. En estos casos. con complejidad logarítmica. sobre todo. . no es un esquema algorítmico. Cada una se ilustra con un ejemplo distinto. es muy probable que no se hayan aprovechado propiedades deducibles del problema y que la solución sea terriblemente ineficiente. y solo se podía usar cuando el vector estuviese ordenado. Ejemplo: Números de Fibonacci Los números de fibonacci suele especificarse como: Fib(0)=1 Fib(1)1 Fib(n+2)=fib(n)+fib(n+1) Esta especificación de los números de fibonacci tienen una formulación recursiva inmediata en estilo funcional. Otro algoritmo realizaba un búsqueda dicotomica o binaria. El algoritmo primero responde a un razonamiento más sencillo. Muchos algoritmos recursivos resultan eficientes. Los parámetros adicionales tienen como misión ir acumulando resultados principales durante el proceso recursivo. aprovechar esta circunstancia para usar el algoritmo más eficiente: el de búsqueda binaria. La función principal simplemente realiza una llamada a esta función auxiliar en los que los parámetros de aquellas se modifican y los parámetros nuevos toman un valor inicial adecuado . dichos algoritmos pueden servir como una primera aproximación al algoritmo definitivo. Uno de ellos realizaba una búsqueda secuencial con complejidad lineal sobre el tamaño del vector y podía usarse con cualquier vector. Por ejemplos: Algunos algoritmos de búsqueda de un elemento en un vector. pero dado que no se ha analizado apenas el problema. pero no todos: hay algunos fácilmente formulables. Una solución por fuerza bruta también puede resultar adecuada como primera aproximación a la solución final. En realidad. una solución funcional a muchos problemas. en caso positivo. pero muy ineficientes. si no mas bien calificativo Para una forma de diseñar algoritmos: tomar una solución directa. Técnicas de los Parámetros Acumuladores y de Tabulacion La recurcion es un mecanismo que permite obtener. la fuerza bruta. Esta es la solución de fuerza bruta: una solución directa. Un modo de evitar problema lo proporciona la técnica de los parámetros acumuladores. pero poco reflexionada. pero debe mejorar su rendimiento para que sea práctico. Veremos dos parámetros para la mejora de eficiencia de algoritmos recursivos: el uso de parámetros acumuladores y el uso de tablas. Parámetros Acumuladores Veamos primero una solución ineficiente que intentaremos mejorar. dad su ineficacia. La función principal usa una función auxiliar que tiene los parámetros de aquellas más algunos adicionales. en combinación con otras contrucciones. porque su desarrollo puede permitir profundizar más sobre el problema y conocer propiedades que sean utilizadas para obtener otra versión más eficiente. Método de fuerza bruta Comenzamos el estudio de esquemas algorítmicos con un método sencillo. cuya idea básica se expone a continuación.

La estrategia voraz aplicada comienza devolviendo. Ejemplo. Se abre el diccionario por la pagina centrar(quedando dividido en dos mitades) y se comprueba si la palabra aparece allí o si es léxico gráficamente anterior o posterior.etc. la planificación en el orden de la ejecución de unos programas en un computador. la ordenación de vectores. se supone que ambos participantes tienen cualidades y preparación similar . resolver independientemente los subproblemas para luego combinar sus soluciones y obtener la solución del problema original. Otra técnica útil es el uso de tablas.Tabulacion No todos los algoritmos recursivos ineficientes pueden optimizarse con la técnica de los parámetros acumuladores. Hay dos participantes (deportistas o equipos. no importa que). El procedimiento se repite sucesivamente hasta encontrar la palabra o decidir que no aparece. se almacena en una tabla. Ejemplo. la moneda de mayor valor ( es decir. Esta técnica también se suele emplear con la programación dinámica. mientras el valor de dicha moneda sea mayor o igual al cambio que resta por dar). que juegan una competición que es ganada por el primero que venza en n partidos. De forma que cada uno tiene un 50% de posibilidades de ganar cada partido. Si no ha encontrado y es anterior se procede a buscarla en la primera mitad. en una maquina expendedora de tabaco). Suponiendo que se disponga de cantidad suficiente de ciertos tipos diferentes de monedas de curso legal. se va procedimiento paso a paso realizándose la mejor elección (usando una función objetivo que respeta un conjunto de restricciones ) de entre las posibles. . como el conocido de la mochila. El proceso finaliza cuando se ha devuelto todo el cambio. De todas formas.Para ello. Ejemplo: Sea el problema de la competición. Método voraz: Este método trata de producir tipo de mejor resultado a partir de conjunto de opciones candidatas . continua aplicándose el mismo criterio para la segunda moneda mas valiosa. Puede emplearse en problemas de optimización. cuando se pueda.. la búsqueda en estructuras ordenadas. Por sencillez . donde puede consultarse otras veces que se necesite. se buscara en la segunda mitad. siendo ( n ) mayor que( 0 ). Divide y vencerás: Consiste en descomponer un problema en un subproblema. en la búsqueda de caminos mínimos sobre grafos. Dar un cambioutilizando el menor número de monedas Considérese ahora el problema de la devolución del cambio al realizar una compra (por ejemplo. la modificación para incorporar probabilidades diferentes es evidente y no complica el problema.B. se trata de dar como cambio la menor cantidad posible usando estos tipos de monedas. Consideraciones y Criterios para Diseñar Algoritmos Algunas consideraciones estilísticas pueden contribuir a mejor la calidadde los algoritmos (y programas ) mediante la reducción del numero de errores que aparecen al desarrollar los. La intención es que la primera vez que se realiza un cálculo. Esta técnica se puede aplicar con éxito a problemas como la multiplicación de matrices. y así sucesivamente. Búsqueda de una palabra en un diccionario Como ejemplo sencillo de aplicación de esta estrategia puede considerarse la búsqueda de una palabra en un diccionariode acuerdo con el siguiente criterio. A. si es posterior.etc.

la tipografía seguida ala hora de escribir nombres de variables. Se supone que un problema de esta clasetiene al menos una solución.. subprogramas. Estilo y calidad de los programas van fuertemente unidos. Los criterios de estilo pueden reflejarse en un conjunto de normas de estilo de codificación. Esta característica hace que aunque el análisis del problema sea arduo. Claridad. La dificultad principal para resolver esta clase de problemas estriba en el análisis necesario para poder formular un algoritmo que halle la solución en varios pasos.También influyen haciendo que nuestro algoritmo resulten más fáciles de leer y entender para otras personas. Puede haber varias soluciones optimas. Pude aparecer obvio. El modo de encolumnar las distintas partes de un algoritmo para facilitar su lectura y comprensión. Algoritmos voraces Esquema voraz Hay muchos problemas en los que se pretende obtener un subconjunto de n elementos que satisfaga ciertas restricciones y que optimice alguna medida. las siguientes respuestas reflejan. 4. el problema incluye restricciones adicionales que limitan el número posible de soluciones. lo ideal es que nuestro algoritmo resulte correcto. Un algoritmo voraz sigue el esquema anterior. cierta medida. etc. Por ejemplo. palabras claves. el algoritmo debe estar bien documentación. En realidad. no hay que desperdiciar estos recursos y tratar de desarrollar algoritmos más eficientes. La eficiencia de un algoritmo se mide por los recursos que este consume. pero con la fortuna de que cada vez que añade un elemento a la solución se tiene la certeza de haber realizado la mejor elección posible. la calidad de un algoritmo tiene muchas facetas y todas ellas importantes. A menudo. la solución voraz siempre . estas normas de estilo se dirigen hacia aspectos como la forma de construir los nombres de variables o tipo de datos que aparezcan. claro. y de acuerdo con los puntos de vista anteriores. 3. el algoritmo no debe desaprovechar recursos. La documentación ayuda a comprender el funcionamiento de los algoritmos. Ante la pregunta ¿Cuáles son las característica de un buen algoritmo?. Ciertos detalles o algunas partes especiales de los mismos pueden olvidarse fácilmente o quedar oscura si no están adecuadamente comentadas. y la normas sobre como y donde deben de introducirse los comentarios. Corrección. estos problemas no se intentan resolver "de golpe ". Normalmente. Ello asegura que tanto algoritmos como programa resulten legibles y puedan modificarse fácilmente en caso de necesidad. 1. Nunca se debe olvidar que la característica más simple e importante de un algoritmo es que funcione. Es más frecuente que el subconjunto de la solución se vaya formando paso a paso. eficiente. encontrando de una sola vez la solución completa y óptima. En particular. Resumiendo. analizando durante cada etapa que elemento conviene añadir a la solución parcial ya existente. A pesar de que con la reducción de los costes del hardware es posible diseñar computadores más rápidos y con más memoria. Eficiencia. Otro ejemplo se da cuando. en cuyo caso no importa cual se elija. el algoritmo debe funcionar. 2. dados unos ficheros almacenados en una cinta de que el tiempo de recuperación de un fichero cualquiera sea el mínimo en promedio. los factores que identifican la calidad en ellos . fiable y fácil de mantener. sea el problema de encontrar un subconjunto de los arcos de un grafo. Generalmente. pero resulta difícil de asegurar en algoritmos complejos. se habla de la memoria y del tiempo de ejecución .

Un conjunto de restricciones sobre el valor de los datos de entrada y sobre la solución final del problema. es definitiva. Según esta descripción.. Podemos representar el esquema voraz de la siguiente forma funcional: FUNCTION Voraz ( candidatos: ( 1. la solución consta de: y y y Un conjunto de candidatos Una función de selección que en cada momento determine que candidato de los aún no usados parece ser el mejor. Por tanto. la dificultad principal al diseñar un algoritmo voraz reside en encontrar un criterio en encontrar un criterio de selección que garantice la optimalidad de la solución. Para facilitar la descripción de este proceso.n ) : ( 1. si satisface las restricciones del problema y. si dicho conjunto no es válido. Por lo que se ha descrito del esquema voraz. debe recordarse que puede haber varios criterios alternativos de selección y que de su . es decir. cada solución válida y completa es optima. es decir.n) -> FUNCTION VorazAcumulador ( candidatos : (1. éste es un proceso repetitivo sencillo que trata sucesivamente los diferentes elementos del problema. De todas formas. La única complicación es comprobar que se siguen satisfaciendo las restricciones del problema. la primera solución encontrada es óptima. el candidato se incorpora definitivamente. si permite formar alguna solución del problema. sino que se utiliza durante el análisis del problema y es determinante en la elección de la función de selección. Inicialmente. Solución : (1. se desecha el candidato. Al contrario. por tanto. nunca cambian de opinión: una vez que un candidato es aceptado o rechazado en la solución. Obviamente. el mejor candidato. el conjunto de candidatos que forman la solución está vacío. Obsérvese que las funciones de validez y completitud no se preocupan de la optimalidad del la solución.resulte sencilla. pero si la función de selección es la adecuada. es decir. A su vez. el problema parte de: y y Una función objetivo que da el valor de una solución. La función objetivo no suele aparecer en el algoritmo final.. En cada paso se intenta añadir el mejor de los candidatos restantes a dicha solución parcial..n). Si el algoritmo voraz se ha diseñado correctamente. Además. permite formar una solución del problema..n) : (1. Si este conjunto ampliado sigue siendo válido. ( ) ) Puede verse por qué estos algoritmos se llaman " voraces " : en cada paso toman el mejor trozo de la solución. ésta es la función por optimizar. solución v (siguiente)) VorazAcumulador (candidatos ± (siguiente).. la decisión. puede llamarse candidato al elemento tratado en cada paso. solución) VorazAcumulador (candidatos. Una función que determine si cierto conjunto de candidatos es válido.n) -> Cadidatos = ( ) v EsSolución ( solución)-> Value siguiente -> seleccionar ( candidatos ) IN EsVálida (solución v ( siguiente)) => VorazAcumulador (candidatos ± (solución).

Una solución viene dad por un conjunto de monedas devuelto tras el desglose. Como ejercicio. Para simplificar. Con esta información se puede comprobar que en este problema están presentes los distintos elementos de la técnica voraz.correcta elección depende que la solución calculada por el algoritmo sea optima. 25. Además.M1 Se supone inicialmente asignados los valores a cada uno de los tipos de monedas. 50. Después se resuelven estos subproblemas y se combinan las soluciones para obtener la solución para el problema original. Valores -> Integer M500 M1 Cantidades -> Integer M500 . Como fila primera se toma la secuencia de los índices de los participantes en cualquier orden. en este caso. Se trata de indicar la cantidad (menor) de monedas de los tipos considerados. La función objetivo cosiste en minimizar la cantidad total de monedas utilizadas en el desglose. cuando un candidato (moneda) se incorpora al conjunto solución. Asimismo. la moneda de mayor valor de entre las candidatas. éste no será nunca excluido de él. tales que sumados sus valores equivalgan al importe. este algoritmo tiene la ventaja de valer para las situaciones en que el número de participantes no es una potencia de dos. Estos valores se definen por medio de un tipo enumerado MONEDAS. y cuyo valor total es igual al importe a desglosar. Es fácil encontrar una solución si en cada etapa se genera el subcalendario correspondiente a un equipo. 5 y 1 pesetas para el desglose. Su declaración es la siguiente: TYPE Monedas -> M500 I M100 I M50 I M25 I M5 I M1. se parte de un conjunto de tipos de monedas válidas. suponemos que manejamos dineroespañol y. es decir. Los elementos de la técnica voraz están presentes en este problema de la siguiente forma: y y y y y El conjunto de candidatos está constituido por cada una de las monedas de los diferentes tipos que se pueden usar para realizar el desglose del importe dado. el lector puede intentar encontrar una solución voraz del problema del calendario. mientras sea posible. se declaran los tipos VALORES y CANTIDADES para representar el valor asignado a cada unidad monetaria y la cantidad de cada tipo de moneda que se devolverá en el desglose. Desglose en monedas Como primer ejemplo introductorio sencillo al que puede aplicarse la técnica voraz. utilizar el menor número de monedas. la tabla de competición se va completando por filas. Para ello. y de un importe. Además. en particular. Cada fila resultante puede tener una complejidad de o (n2). podemos utilizar sólo monedas de 500. Divide Y Vencerás La técnica divide y vencerás consiste en descomponer el problema en un conjunto de subproblemas más pequeños. Hay que desglosar una cantidad en un conjunto de monedas tratando de cumplir alguna condición. 100. ¥ ¥ . se considera el problema de un cambio o desglose en monedas. La función de selección establece que hay que elegir. La condición de factibilidad de la solución siendo construida establece en el desglose debe ser menor o igual que el importe a desglosar. de las que se supone que hay cantidad suficiente para realizar el desglose.

solución) DyVAux (problema. Estos subproblemas se resuelven independientemente y después se combinan sus soluciones parciales para obtener la solución del problema original. subsolucion2 : resultado IF EsPequeño (inferior. resultado FUNCTION DivideYVenceras (problema : dato) : resultado -> EsPequeño (problema) }=> ResolverDirectamente (problema) | VALUE subproblemas -> Partir (problema) IN subproblemas == (subproblema1. DyVAux (problema. el proceso recursivo nunca terminaría. OUT solución : resultado) -> VAR medio: 1. de tipo resultado: TYPEVAR Dato.. subsolucion2. DivideYVenceras (subproblema2)) Se puede hacer una formulación imperativa similar. la técnica de divide y vencerás parte la entrada en k subproblemas. superior. El caso más frecuente es cuando el número de subproblemas es dos. 1.. deben existir algunos pasos sencillos cuya solución pueda calcularse fácil y directamente. Combinar (subsolucion1. superior). en la que se utiliza un vector de tamaño N. La técnica de divide y vencerás es quizás una de las utilizadas debido a su sencillez: si un problema es demasiado grande para resolverlo de una vez. medio+1. Sin embargo..n. N. considerado el problema como de tipo dato y la solución. resultado PROCEDURE DivideYVenceras (IN problema : dato1. inferior. DyVAux (problema.Esquema de Divide y vencerás. superior : 1. subsolucion1). medio. es fácil su generalización a k subproblemas 2<k<=n. IN inferior. escribiremos una formulación más restrictiva pero bastante usual. subsolucion2). TYPEVAR dato.n. superior. dado un problema al resolver planteando en términos de una entrada de tamaño n. Veamos el esquema de divide y vencerás para dos subproblemas. Por supuesto. en caso contrario. inferior. solución) . olución) ELSE Medio := Partir (inferior.N subsolucion1. OUT solución : resultado) -> PROCEDURE DyVAux (IN problema : dato1. superior) THEN ResolverDirectamente (problema. 1<k<=n. Mas formalmente.N.. Esta restricción permite una formulación y resolución recursiva de los subproblemas. se descompone en varias partes más fáciles de resolver. subproblema2) => Combinar (DivideYVenceras (subproblema1) . Este esquema de partición de problemas se denomina esquema de divide y vencerás solo en el caso en que los problemas sean de la misma clase del problema original. Su formación funcional es como sigue.

1<=j<n. en caso contrario donde T(n) es la función de tiempo de DivideYVenceras para entradas de tamaño n. 1<=i<=n. Nótese que. Cada conjunto P(i) consta de (n-1)! Elementos. es general. Por concreción.si n es pequeño T(n) = 2 T(n/2) + f(n). Sin embargo la aplicación de la técnica de divide y vencerás produce una solución mas sencillas aun pero muy eficientes. Se necesitan elaborar n-1 competiciones por participantes. pero es terriblemente ineficiente. 1<= i<=n. se supone que el numero de participantes es una potencia de dos.El esquema general se adapta a un problema concreto al sustituir los metasimbolos EsPequeño. incluyendo en cada fila i algún ejemplo de P(i). El método de fuerza bruta resulta sencillo. ResolverDirectamente. la columna j también contiene números distintos.n}-{i} ahora se completan las filas de la tabla de todas las formas posibles. es decir. Partir y Combinar por funciones o procedimientos concretos. es decir. Para simplificar el problema. para nuestros propósitos resulta indiferente el deporteobjeto de la competición. Solo sirve como solución aquellas combinaciones de fila que cumplan las restricciones enunciadas en el párrafoanterior sobre las columnas de la tabla (las restricciones sobre las filas están garantizadas por el modo de generar los conjuntos P(i)). el tiempo de cómputo de la función DivideYVecneras se describe con la siguiente relación de recurrencia: g(n). así que hablaremos de participantes en vez de deportistas o equipos. Se supone también que cada participante tiene asignado un número comprendido entre 1 y N. puede suponerse que las competiciones se celebran en días sucesivos y que cada participante compite una vez por día. la solución del problema puede representarse en una tabla de dimensión nx(n-1). Elaboración de un Calendario Deportivo: Sea un campeonato deportivo. contiene el numero del participante contra el que el participante i-esimo compite el día j-esimo. g(n) es el tiempo que tarda la función ResolverDirectamente en resolver problemas de pequeño tamaño (normalmente una constante) y f(n) es el tiempo necesario para partir el problema y combinar las subsoluciones. porque el día j-esimo cada participante solo puede competir con otro participante. A su vez. resultan nx(n-1)!=n! formas de rellenar la tabla. Si el tamaño de los dos subproblemas es el mismo (o casi). Por tanto. La eficiencia final del algoritmo depende de la función f(n) concreta que aparezca durante el análisis. Obsérvese que los números de participantes incluidos en la fila i de la tabla son distintos porque el participante i-esimo solo debe competir una vez con cada participante restante. Se dispone de una solución inmediata aplicando fuerza bruta. El elemento (i. para que esta técnica resulte eficiente todos los subproblemas deben ser de tamaño parecido.. El problema consiste en elaborar un calendario de competición de forma que cada participante compita exactamente una vez con cada uno de los demás participantes. días . y sin perdida de generalidad. hay n = 2k participantes para algún entero positivo k. Si hay varios calendarios validos. el conjunto de permutaciones de los números {1. el conjunto P(i) de todas las permutaciones posibles del resto de los participantes con los que debe competir. se elige uno cualquiera. Primero se obtiene para cada participante i. Dado que el numero de participantes de n. La siguiente figura describe visualmente parte de la elaboración de la tabla.j)±esimo de la tabla.

El algoritmo descrito se expresa a continuación.1. El problema puede reducirse a dos sub problemas de tamaño 2k-1 si se elaboran independientemente dos subcalendarios de tamaño 2k x(2k-1 -1): uno para los participantes.. OUT tabla : (1. El caso básico se da cuando solo hay dos participantes. rotando dicha secuencia a la derecha. faltando 2k x2k-1 celdas para completar el calendario total. IN sup :1.N-1) -> PROCEDURE FormaTabla (IN inf : 1.2n .. el resto del calendario se puede construir fácilmente. faltan por elaborar las competiciones cruzadas entre los participantes de numeración inferior y los de numeración superior. ya que a unión de los dos calendarios tiene un tamaño 2k x(2k-1 -1). sucesivamente con los participantes 2k-1 +1. es más complejo. PROCEDURE Calendario ( INOUT tabla : (1.N)1.N.1. El siguiente participante toma esta secuencia y realiza una fácil permutación de la misma que le garantiza el respeto de las restricciones de la solución.. Sin embargo. superior en orden creciente de numeración. Completemos primero la parte de los participantes de numeración inferior. Si el numero de participantes es 2k .. de numeración comprendida entre 1 y 2k-1 y otro para los participantes comprendidos entre 2k-1 +1 y 2k . por ejemplo. es decir.. Este proceso se repite para el resto de los participantes de numeración inferior. para k>1. .N. El subcalendario del primer participante es sencillo porque basta con que compita en días sucesivos con los participantes de numeración.. cuando hay más de dos participantes.. la unión de estos subcalendarios no forma un calendario completo para el campeonato de 2k participantes.N-1) -> VAR ¦ .N. La solución es directa porque se celebra una sola competición entre ambos.. En efecto. El calendario de los participantes de numeración superior se completa de forma similar con los números de los participantes de numeración inferior. El caso recursivo.1 participantes 1 2 2 1 1 2 3 1 2 3 4 2 1 4 3 3 4 1 2 4 3 2 1 1 2 3 4 5 6 7 1 2 3 4 5 6 7 8 2 1 4 3 8 5 6 7 3 4 1 2 7 8 5 6 4 3 2 1 6 7 8 5 5 6 7 8 1 2 3 4 6 5 8 7 4 1 2 3 7 8 5 6 3 4 1 2 8 7 6 5 2 3 4 1 Se distinguen dos casos.N. puede decirse que el "tamaño" del problema es 2k (sabemos que el calendario tendrá un tamaño de 2k x(2k-1 -1) posiciones).N) 1.. Por fortuna.

es decir. Después se genera.sup-1. Ordenación de un Vector por Mezcla: La ordenación de un vector es un problema que se presta fácilmente a la aplicación de la técnica de divide y vencerás.. La idea consiste en añadir inicialmente a la tabla una columna "ficticia" de índice j=0.1.N) -> VAR Medio : 1. medio). sea vi. CompletarTabla (inf. medio. IN inf. medio+1. 1.. medio+1. En esta última etapa. Finalmente se completa la mitad derecha de la tabla (correspondiente al cruce de los dos grupos de equipos cuyos subcalendarios se han generado por divide y vencerás). los componentes tablai..j a partir de las casillas tablak.N IF inf = sup-1 THEN tablainf. que obviamente ya esta ordenado.N.. FormarTabla (medio+1. de acuerdo con las siguientes expresiones de los índices: i = (k + n/2) Mod (n+1) j = (1 + n/2) Mod n De esta forma se rellenan las casillas aun vacías. OrdenarAux (vector. Mezclar (vector.l ya completadas. tabla). mediante divide y vencerás. basta con mezclar los dos subvectores. Veamos otra estrategia..l)..medio : 1. para obtener un único vector ordenado. mediante comparaciones de sus elementos sucesivos. FormarTabla (inf. los valores de las casillas (k.s .m y vm+1. donde se aplica divide y vencerás para resolver el problema y que se aprovecha de la simetría de la solución. medio. medio. que es mucho mas eficiente que la solución de fuerza bruta. tabla) Este sistema de ecuacionesdefina una función de tiempo del orden de O(n2). que almacena los índices de las filas. El algoritmo resultante es: PROCEDURE Ordenar (INOUT v : INTEGER1. inf.N) -> (* ordenación por mezcla *) PROCEDURE OrdenarAux (INOUT Vector : INTEGER1. medio. Este proceso de mezcla es realizado por un procedimiento auxiliar.1 : = sup. la mitad izquierda de la tabla. también de orden de complejidad cuadrática. sup) OrdenarAux (v. La partición puede hacerse por la mitad si se toma un índice m=[(i+s)/2] y dos subvectores vi.. la combinación de los dos subvectores ya ordenados es fácil. Para el caso general.s un vector de índice inferior i e índice superior s. OrdenarAux (vector. sup).N IF inf < sup THEN medio := (inf+sup) Div 2. tablasup.1 := inf ELSE medio := (inf + sup) Div 2. El caso básico corresponde a un subvector de un solo elemento. inf. inf. sup.N. N) .. medio.. tabla). tabla). CompletarTabla (medio+1. sup. sup-1. sup : 1. siendo 1<=k<=n y 0<=l<=(n/2)-1.

La operación de mezcla es proporcional a n. IN sup : INTEGER.. i2.. La matriz productoC=AxB también es una matriz de nxn cuyo elemento (i.= vectori2.sup DO vectorAuxj := vectorindice .medio DO vectorAuxj := vectorindice.sup DO vectorindice := vectorAuxindice El algoritmo resultante es sencillo conceptualmente. Multiplicación de Matrices: Sean dos matrices. es decir.. n =2k para algún k.N. pero mantenga la complejidad asintótica calculada. j : INTEGER. n>1.. i2 := i2 + 1 j := j + FOR índice IN i1. J := j + 1 FOR índice IN i2. de forma que las ecuaciones de recurrencia de la función de tiempo son: T(n) = a. necesita copiar el vector auxiliar completo en el principal. J := j + 1 FOR índice In inf. índice : INTEGER i1 := inf. b=cte Si n es una potencia de 2. resultando: T(n) = 2T(n/2) + bn= =2K T(n/2K) + kbn = an + bn log2 n El algoritmo de ordenación por mezcla es óptimo en tiempo de ejecución. n=1. las ecuaciones anteriores se resuelven por sustituciones sucesivas. Los únicos inconvenientes que presenta es que el procedimiento de mezcla necesita gran capacidad de almacenamiento (para dos copias del vector) y que. IN medio: INTEGER.El procedimiento para realizar la mezcla de los subvectores ordenados es: PROCEDURE Mezclar ( IN inf : INTEGER. Es fácil analizar la complejidad del algoritmo para un vector de longitud n. además de mezclar.. a=cte 2T(n/2) + bn. j := inf. i1 :=i1 + 1 ELSE vectorAuxj . INOUT vector : INTEGER1. de dimensión nxn. WHILE (i1<=medio) ^ (i2<=sup) DO IF vectori1 << vectori2 THEN vectorAuxj :=vectori1. Puede diseñarse un algoritmo de mezcla más complejo que mejore ambos aspectos. i2 := medio + 1. A y B.N) -> VAR vectorAux : INTEGER1. i1.j)-esimo se forma multiplicando cada elemento de la final i-esima de A por el elemento correspondiente de la columna j-esima de B y sumando los productos § .

pero de una manera menos directa que en el caso voraz. El cálculo de cada elemento Cij requiere n multiplicaciones. no se reconsidera en el futuro. la técnica de divide y vencerás sugiere un algoritmo distinto. que existe un entero no negativo k tal que n=2k. Dos submatrices de (n/2)x(n/2) pueden sumarse en un tiempo bn2. de forma que no se ha conseguido ningún ahorro sustancial de tiempo. como inversión de una matriz o hallar su determinante. aunque fuera a costa de un mayor numero de sumas de matrices. Sin embargo. Solamente al final se sabe cuál es la mejor de todas. interesa encontrar algoritmos mas eficientes. El algoritmo anterior. dado que la complejidad respectiva de estas operaciones es O(n3)n y o(n2). pero para n>2 las submatrices Cij se calculan mediante multiplicaciones (recursivas) y sumas de submatrices de dimensión (n/2)x(n/2). Sin embargo. no todos los problemas pueden resolverse de esta manera. La resolución de este sistema de ecuaciones nos dice que O(T(n))=OT(n3). es decir. que n es una potencia de dos. Programación Dinámica Principios de programación dinámica Se ha visto que la técnica voraz se aplica a problemas cuya solución puede formularse como el resultado de una secuencia de decisiones. La programación dinámica (también llamada planificación dinámica) es una técnica de programación que también permite resolver problemas mediante una secuencia de decisiones. pueden añadirse las filas y columnas de ceros necesarias para formar una dimensión que sea potencia de dos. Si el producto AxB tiene la forma: A11 A12 B11 B12 C11 C12 A21 A22 B21 B22 C21 C22 Entonces: C11 = A11*B11 + A12*B21 C12 = A11*B12 + A12*B22 C21 = A21*B11 + A22*B21 C22 = A21*B12 + A22*B22 Para n=2. todo problema resoluble con esta técnica debe de satisfacer el principio de optimalidad. una característica es que el programa "aprende "dinámicamente de las decisiones que toma. Sin embargo. (Si n no es un potencia de dos. asegurando que la secuencia de decisiones es la mejor de las posibles. La existencia de un algoritmo eficiente para la multiplicación (en realidad. conduciendo de forma directa a la solución. La matriz C tiene n2 elementos. proviene directamente de la definición matemática del producto de matrices. El algoritmo de Strassen calcula las cuatro submatrices Cij empleando 7 multiplicaciones y 18 sumas o restas de matrices. No es fácil establecer una definición de la programación dinámica. por sencillez. El método es eficiente porque una vez que se toma una decisión en un paso. para cualquier operación de las anteriores) significaría la existencia de un algoritmo similar para las demás. que podemos llamar algoritmo convencional de multiplicación de matrices. los elementos Cij se calculan mediante algunas multiplicaciones y sumas de números.parciales. Supongamos. Además. Esta vez se necesita producir varias secuencias de decisiones. porque la multiplicación esta relacionada con otras operaciones sobre matrices mas usuales. Este principio establece que "una secuencia óptima de decisiones que resuelve un problema debe cumplir la .) las submatrices A y B pueden partirse en cuatro submatrices de dimensión (n/2)x(n/2). Podría conseguirse mas eficiencia si lográramos realizar menos multiplicaciones de matrices. siendo b alguna constante. así que el tiempo total del algoritmo de multiplicación es de orden O(n3).

1<i<N1. Entonces. La formulación delantera expresa la decisión de Xl . ( Obsérvese que vamos a usar la técnica de resolución de problemas por generalización para después poder realizar una particularización de la solución obtenida.dl. Además. partiendo como estado inicial de Ek-1. tal que Eo es el estado inicial del problema y deben tomarse n decisiones d. Sea D = { v1 .. hay un caso en que la decisión d1 no va seguida por ninguna secuencia de decisiones. además. tiene la ventaja ( quizás paradójica al tratar de un problema más pequeño ) de que proporciona una visión más general del problema en cuestión. si este subproblema de simboliza como problema (k.. La ecuación de recurrencia puede formularse de dos formas: delantera o trasera.. El razonamiento anterior se refiere a la primera decisión d1 tomada desde el estado inicial E0 sin embargo. De esta forma se reduce al número total de subsecuencias generadas. 1<i<n. a partir de la secuencia de decisiones Xi+1 Xn ( es la clase de formulación adoptada hasta ahora ).1 ) debe expresarse en términos de los valores de decisión existente para decisiones d1 y el subproblema problema ( k+1. resultará un total de d secuencias posibles de decisión.) Una solución dinámica para problema ( k. La expresión inicial de la ecuación de recurrencia. En la programación dinámica todos los subproblemas se resuelven de acuerdo con criterio de tamaño creciente y los resultados de subproblemas más pequeños se almacenan en algún tipo de estructura de datos (normalmente tablas) para facilitar la solución de los problemas más grandes.l). Podemos formalizar algo más la idea básica. Supongamos que tenemos un problema que satisface el principio de optimalidad. el número de secuencias de decisión es exponencial sobre el número de decisiones. En resumen. Sea X1 . entonces el problema completo es problema ( l. Algoritmos De Vuelta Atrás Existen un alto número de problemas que pueden formularse como la búsqueda de la mejor solución o del conjunto de todas las soluciones que satisfacen ciertas condiciones. La ecuación general relaciona la secuencia óptima en una etapa i con la decisión tomada en la etapa i y la subsecuencia óptima en la etapa posterior i+1. puede generalizarse la formulación del problema a cualquier subsecuencia de decisiones dk . asimismo.1 ) resultante de aplicar cada valor de decisión. la ecuación de base establece el valor para la etapa n+1 en que no queda ninguna decisión Xi. 1<i<n . ¨ ¨¨ ¨ ¨ . porque si hay d opciones para cada una de las n decisiones.n ). que es problema ( n.Xn la secuencia de decisiones necesaria para resolver el problema. sólo que en orden contrario. del gusto del programador. Eli el estado del problema tras la elección del valor vli 1<i<n1 y Sli una secuencia óptima de decisiones respecto al estao Eli. una secuencia óptima de decisiones respecto a E0 es la mejor secuencias de decisión { Vli Sli }. a partir de la recurrentes con formulación trasera es igual que e la formulación delantera. Tiene sentido centrarse en un subproblema del problema inicial porque éste satisface el principio de optimalidad pero.vn} el conjunto de valores de decisión posibles para la decisión d1. La formulación trasera expresa la decisión de Xi. evitándose una explosión combinatoria en la producción de las secuencias y consiguiéndose soluciones más eficientes en cuanto a tiempo de ejecución. sencillamente. 1<i<n. La elección de una formulación delantera o trasera depende del problema considerado o. 1<i<n.n ). sea. a tomar. 1<k<n.propiedad de que cualquier subsecuencia de decisiones también debe ser óptima respecto al subproblema que resuelva ".. Usando una técnica de fuerza bruta. la aplicación de la técnica de programación dinámica a un problema significa comprobar primero el principio de optimalidad y desarrollar después unas ecuaciones recurrentes del estilo de (1) y (2).

Supongamos que también existe algún predicado R que determina si un camino (x1. 1. Por supuesto. k sirve de cota inferior al retroceso.. Por lo tanto... Retroceso (k+1.k) THEN << guardar µsolucion¶ >>.. Ramificación (Bifurcacion) Y Acotación Los métodos de Ramificación y Acotación constituyen un a variante de las técnicas de retroceso para problemas donde se trata de encontrar el valor máximo o mínimo de cierta función objeto (esto suele suceder en los problemas de programación lineal entera). Sea G(x1. Supongamos que existe algún predicado acotador A tal que A(x1.. En algunos problemas de optimización se conoce un criterio óptimo de selección que puede usarse de forma voraz...xi+1) no puede extenderse para alcanzar un nodo de respuesta. Después simplemente se llama recursivamente al algoritmo para generar los estados descendientes. pues tenemos ya una solucion mayor... los candidatos para la posición i+1 del vector desolucion x1.n son aquellos valores generados por G que satisfacen A. Esquema de Algoritmos de Vuelta Atrás: Sea (x1.. Se sale del bucle FOR cuando no quedan mas valores para solución terminando la llamada actual al algoritmo. debe existir una función de criterios que debe ser satisfecha por cada secuencia solución u optimizada por dichas secuencias solución si solo queremos la mejor.n) -> VAR nodo : elemento FOR noso IN G(solucion. y que al seguir avanzando en el árbol (mediante la aplicación de varios pasos de retrocesos) se alcanza un nodo que requiere k+1 colores.. La técnica de ramificación y acotacotacion aplica de la siguiente manera: Supóngase que al recorrer un árbol y alcanza una hoja se tiene una solucion con k colores.xi) el conjunto de todos los valores posibles de xi+1 tales que (x1.. Algoritmos Heuristicos Existen muchos problemas para los cuales no se conocen algoritmos que puedan encontrar la solución de forma eficiente: problemas NP-completos..xi+1) es falso si el camino (xi. 1..xi+1) es un camino hasta el estado del problema.xi) el camino desde la raíz hasta un nodo de un árbol del espacio de estado. 1. El Algoritmo de Vuelta Atrás se especifica de la forma siguiente: PROCEDURE Retroceso (IN k : INTEGER.xi+1) termina en un nodo de respuesta. pudiéndose aplicar la técnica de programación dinámica. El procedimiento no hace ninguna llamada recursiva cuando k = N+1 o cuando ningún nodo generado por G satisface el elemento posible que satisfacen A se añade una solución particular. se comprueba si se ha encontrado una solucion. Este mismo proceso se repite en el resto de nodos del árbol. Sin embargo... k) THEN IF R(solucion.. . INOUT solucion : elemento1.. En este punto podemos retroceder (y no seguir avanzando por mas ramas). Otros problemas satisfacen el principio de optimalidad.cada solución es el resultado de una secuencia de decisiones.. Así. solucion)... solucion) La llamada inicial del algoritmo es Retroceso(1.. k-1) DO Solucion k := nodo.. evitando así la exploración de gran parte de al estructura. todavía hay otros problemas peores que no queda mas remedio que realizar una búsqueda de la solución.. IF R(solucion..

5)) Coste = 10+15+20+45+50 = 140 .. se basa en un conocimiento intuitivo del programador sobre un determinado problema. Solución: ((2. Acabamos cuando tengamos n nodos. a2. 1) Coste: 15+20+10+45+50=140 Heurística voraz 2 ± Una solución será un conjunto de aristas (a1.La solución exacta puede requerir un orden factorial o exponencial: el problema de la explosión combinatoria. pero garantizando que se forme un ciclo. Es un problema NP. Empezar en un nodo cualquiera.. an-1) que formen un ciclo hamiltoniano.. . Se hace necesario utilizar algoritmos heurísticos: Un algoritmo heurístico (o simplemente heurística) puede producir una buena solución (puede que la óptima) pero también puede que no produzca ninguna solución o dar una solución no muy buena. Factible: una arista se puede añadir a la solución actual si no se forma un ciclo (excepto para la última arista añadida) y si los nodos unidos no tienen grado mayor que 2. (3. c2. 2. Problema de optimización. 3). donde la solución está formada por un grupo de elementos en cierto orden: podemos aplicar el esquema voraz. Empezar con un grafo sin aristas. Solución: (1. sin importar el orden.. 5). 2. 3.. 2).. 4. completo y ponderado G = (V. 4).. 3. ca). Solución: (5. cn). 2) Coste: 30+15+25+10+45=125 Empezando en el nodo 3. A). (1.. . Las aristas son los candidatos. . Hacer igual que en el algoritmo de Kruskal.. el orden de visita de los nodos. Heurística voraz 1 ± Una solución será un cierto orden en el conjunto de nodos (c1. El problema del viajante Problema: Dado un grafo no dirigido. 4. 5. pero necesitamos una solución eficiente. Los nodos son los candidatos. encontrar un ciclo simple de costo mínimo que pase por todos los nodos. Función de selección: de los nodos candidatos seleccionar el más próximo al último (o al primero) de la secuencia actual (c1. ‡Ejemplo. La estructura de algoritmo voraz se puede utilizar para construir procedimientos heurísticos: hablamos de heurísticas voraces. Selección: seleccionar la arista candidata de menor coste. Inicialización: seleccionar un nodo cualquiera. Normalmente. Posibilidades: 1. c2. (1. Ejemplo. En cada paso moverse al nodo no visitado más próximo al último nodo seleccionado. Objetivo: obtener buenas soluciones en un tiempo de ejecución corto. (4. Empezando en el nodo 1.

Se trata de calcular un subconjunto A¶ de aristas tal que dos aristas cualquiera de A¶ no tengan ningún vértice común y toda arista de A-A¶ comparta algún vértice común con una arista de A¶. Algoritmos De Aproximación Dado un problema NP completo. Sin embargo.Conclusiones: Ninguno de los dos algoritmos garantiza una solución óptima.A). los vértices incidentes a las aristas de M son un recubrimiento de G. por lo menos la mitad de los vértices de M deben pertenecer a un recubrimiento. Para este tipo de problemas. ya que por la definición de ajuste maximal. a partir de la solución del algoritmo intentar hacer modificaciones locales para mejorar esa solución. Sin embargo. Para poder aplicar el nuevo problema aproximado. repetir la heurística 1 con varios orígenes. ningún vértice perteneciente a M puede recubrir a mas de una arista en M. Este problema se puede resolver a través de otro aproximado. próximas a la óptima. Esto es evidente. El procedimiento para construir un ajuste maximizal de un grafo G consistiría en ir tomando aristas de G. también por la propia definición. Este nuevo problema garantiza conseguir un recubrimiento que contiene no más de dos vértices del recubrimiento mínimo. En consecuencia. como es calcular el ajuste maximizal del grafo G. . ó bien. se trata de encontrar un conjunto con el menor numero de vértices tal que toda arista sea incidente por lo menos de un vértice de V. Posibles mejoras: buscar heurísticas mejores. seria necesario demostrar que el conjunto de todos los vértices inciden a las aristas de un ajuste maximal M para un grafo G es un recubrimiento con no mas de dos veces el numero de veces el recubrimiento de tamaño mínimo. es probable que no sepamos resolverlo de manera precisa y completa utilizando un algoritmo polimico en tiempo. normalmente ambos dan soluciones buenas. resulta parcialmente interesante que estos garanticen una cota en el margen de imprecisión. A continuación se ilustra este tipo de tratamiento de problemas al problema de recubrimiento de un grafico: Dado un grafo G=(V. los algoritmos que no conducen a una solución óptima se llaman algoritmos de aproximación. de una en una y en cualquier orden e ir eliminando las incidentes al conjunto que se esta construyendo hasta recubrir todo en grafo.

Sign up to vote on this title
UsefulNot useful