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.

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

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

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

+a1x+a0 es O(xn). independientemente de la base. llamado de fuerza bruta. å i = n(n+1)/2 Î O(n2).. .. 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. n/4.. Este método.. 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 . " 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+. se decir. a esquemas muy generales que pueden adaptarse a un problema particular al detallar las partes generales del esquema. otros son bastante complejos. Los logaritmos son del mismo orden.001. nnn å 1 = n Î O(n).. å im Î O(nm+1) i=1 i=1 i=1 Si hacemos una operación para n. +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. El acto de diseñar un algoritmo puede considerarse como una tarea que difícilmente podrá ser del todo automatizada.Es necesario en este momento mencionar algo sobre como hacerlo. Muchos problemas pueden resolverse buscando una solución fácil y directa pero.. 5. Ejemplo.. t(n) = amnm + am-1nm-1 + . El esquema mas sencillo quizás sea el llamado divide y vencerás.) Ì O(n2) Ì O(n3) Ì . una tarea difícil. basado en la descomposición de un problema en . algunos resultan inmediatos de resolver. pero con un poco de análisis puede encontrarse algoritmos más eficientes. aparecerá un orden logarítmico O(log2 n). otra para n/2.. Una forma de facilitar esta labor consiste en recurrir a técnicas conocidas de diseño de algoritmos. puede ser muy directo. No obstante... y a pesar de que resulta mas adecuado en bastantes casos utilizar alguno de estos esquemas que realizar un diseño desde cero. El diseño de un algoritmo que resuelva un problema es. a la vez bastante ineficiente. Ì O(2n) Ì O(n!) Ì O(nn) ¿Qué pasa con las omegas? ¿Y con los órdenes exactos? El orden de un polinomio anxn+. d Î R+. en general.. idear un algoritmo continua siendo una labor bastante creativa donde los conocimientos y la experiencia del propio diseñador tiene un papel fundamental. $ n0 Î N. 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. Todo problema algorítmico es un reto para su diseñador.Q (f) = O(f) Ç W (f) = { t: N ® R+ / $ c.

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

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

cuando se pueda. 2. mientras el valor de dicha moneda sea mayor o igual al cambio que resta por dar). Método voraz: Este método trata de producir tipo de mejor resultado a partir de conjunto de opciones candidatas . la moneda de mayor valor ( es decir. Nunca se debe olvidar que la característica más simple e importante de un algoritmo es que funcione. cierta medida. subprogramas. y así sucesivamente. palabras claves. Esta técnica se puede aplicar con éxito a problemas como la multiplicación de matrices. Puede emplearse en problemas de optimización. Estilo y calidad de los programas van fuertemente unidos. 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.etc.. También influyen haciendo que nuestro algoritmo resulten más fáciles de leer y entender para otras personas. 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. El proceso finaliza cuando se ha devuelto todo el cambio. la tipografía seguida ala hora de escribir nombres de variables. si es posterior. Ejemplo. estas normas de estilo se dirigen hacia aspectos como la forma de construir los nombres de variables o tipo de datos que aparezcan.subproblemas para luego combinar sus soluciones y obtener la solución del problema original. el algoritmo debe funcionar. El procedimiento se repite sucesivamente hasta encontrar la palabra o decidir que no aparece. se buscara en la segunda mitad. Los criterios de estilo pueden reflejarse en un conjunto de normas de estilo de codificación. la planificación en el orden de la ejecución de unos programas en un computador. 1. Ante la pregunta ¿Cuáles son las característica de un buen algoritmo?. la búsqueda en estructuras ordenadas..etc. Ejemplo. se trata de dar como cambio la menor cantidad posible usando estos tipos de monedas. Ello asegura que tanto algoritmos como programa resulten legibles y puedan modificarse fácilmente en caso de necesidad. El modo de encolumnar las distintas partes de un algoritmo para facilitar su lectura y comprensión. etc. Generalmente. las siguientes respuestas reflejan. pero resulta difícil de asegurar en algoritmos complejos. Corrección. Si no ha encontrado y es anterior se procede a buscarla en la primera mitad.Para ello. Suponiendo que se disponga de cantidad suficiente de ciertos tipos diferentes de monedas de curso legal. La estrategia voraz aplicada comienza devolviendo. Pude aparecer obvio. los factores que identifican la calidad en ellos . 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. y la normas sobre como y donde deben de introducirse los comentarios. la ordenación de vectores. 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. continua aplicándose el mismo criterio para la segunda moneda mas valiosa. en una maquina expendedora de tabaco). como el conocido de la mochila. . 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.

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

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

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

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

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

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

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

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

vn} el conjunto de valores de decisión posibles para la decisión d1. De esta forma se reduce al número total de subsecuencias generadas. pero de una manera menos directa que en el caso voraz. 1<i<n. No es fácil establecer una definición de la programación dinámica. como inversión de una matriz o hallar su determinante. Usando una técnica de fuerza bruta. Además. Sea D = { v1 . una característica es que el programa "aprende "dinámicamente de las decisiones que toma. Sin embargo. para cualquier operación de las anteriores) significaría la existencia de un algoritmo similar para las demás. siendo b alguna constante. Entonces. La existencia de un algoritmo eficiente para la multiplicación (en realidad.. Solamente al final se sabe cuál es la mejor de todas. porque si hay d opciones para cada una de las n decisiones. La resolución de este sistema de ecuaciones nos dice que O(T(n))=OT(n3). 1<i<N1. 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. 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. asegurando que la secuencia de decisiones es la mejor de las posibles. el número de secuencias de decisión es exponencial sobre el número de decisiones. de forma que no se ha conseguido ningún ahorro sustancial de tiempo. 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. Podemos formalizar algo más la idea básica. Dos submatrices de (n/2)x(n/2) pueden sumarse en un tiempo bn2. asimismo. los elementos Cij se calculan mediante algunas multiplicaciones y sumas de números. resultará un total de d secuencias posibles de decisión. interesa encontrar algoritmos mas eficientes. conduciendo de forma directa a la solución. 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. Sin embargo. porque la multiplicación esta relacionada con otras operaciones sobre matrices mas usuales. 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. El algoritmo de Strassen calcula las cuatro submatrices Cij empleando 7 multiplicaciones y 18 sumas o restas de matrices. no se reconsidera en el futuro.Para n=2. 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. aunque fuera a costa de un mayor numero de sumas de matrices. dado que la complejidad respectiva de estas operaciones es O(n3)n y o(n2). tal que Eo es el estado inicial del problema y deben tomarse n decisiones d. Supongamos que tenemos un problema que satisface el principio de optimalidad. todo problema resoluble con esta técnica debe de satisfacer el principio de optimalidad. una secuencia óptima de decisiones respecto a E0 es la mejor secuencias de decisión { Vli Sli }. El método es eficiente porque una vez que se toma una decisión en un paso. sea. Esta vez se necesita producir varias secuencias de decisiones. Podría conseguirse mas eficiencia si lográramos realizar menos multiplicaciones de matrices. pero para n>2 las submatrices Cij se calculan mediante multiplicaciones (recursivas) y sumas de submatrices de dimensión (n/2)x(n/2).

n ).n ).Xn la secuencia de decisiones necesaria para resolver el problema. Por lo tanto. Sea G(x1.) Una solución dinámica para problema ( k.... que es problema ( n. 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.. sólo que en orden contrario.. 1<i<n. cada solución es el resultado de una secuencia de decisiones. Otros problemas satisfacen el principio de optimalidad. La expresión inicial de la ecuación de recurrencia.. La elección de una formulación delantera o trasera depende del problema considerado o..xi+1) no puede extenderse para alcanzar un nodo de respuesta. partiendo como estado inicial de Ek-1....1 ) debe expresarse en términos de los valores de decisión existente para decisiones d1 y el subproblema problema ( k+1.. todavía hay otros problemas peores que no queda mas remedio que realizar una búsqueda de la solución. 1<k<n. El Algoritmo de Vuelta Atrás se especifica de la forma siguiente: PROCEDURE Retroceso (IN k : INTEGER. pudiéndose aplicar la técnica de programación dinámica. 1<i<n. Supongamos que existe algún predicado acotador A tal que A(x1.... La formulación delantera expresa la decisión de Xl . 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. puede generalizarse la formulación del problema a cualquier subsecuencia de decisiones dk . la ecuación de base establece el valor para la etapa n+1 en que no queda ninguna decisión Xi.xi+1) es un camino hasta el estado del problema. La ecuación de recurrencia puede formularse de dos formas: delantera o trasera. INOUT solucion : elemento1.. entonces el problema completo es problema ( l. hay un caso en que la decisión d1 no va seguida por ninguna secuencia de decisiones. además.xi) el conjunto de todos los valores posibles de xi+1 tales que (x1. Por supuesto...xi+1) termina en un nodo de respuesta.. Esquema de Algoritmos de Vuelta Atrás: Sea (x1.xi+1) es falso si el camino (xi. a partir de la recurrentes con formulación trasera es igual que e la formulación delantera.. a tomar.. a partir de la secuencia de decisiones Xi+1 Xn ( es la clase de formulación adoptada hasta ahora ). Sin embargo.xi) el camino desde la raíz hasta un nodo de un árbol del espacio de estado. La formulación trasera expresa la decisión de Xi. 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.dl. los candidatos para la posición i+1 del vector desolucion x1.l). Además.n) -> ¤ ¤¤ ¤ . 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. 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).. si este subproblema de simboliza como problema (k... ( 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. En resumen.. sencillamente.n son aquellos valores generados por G que satisfacen A.. En algunos problemas de optimización se conoce un criterio óptimo de selección que puede usarse de forma voraz.. Tiene sentido centrarse en un subproblema del problema inicial porque éste satisface el principio de optimalidad pero. 1<i<n .1 ) resultante de aplicar cada valor de decisión. Supongamos que también existe algún predicado R que determina si un camino (x1.. del gusto del programador..El razonamiento anterior se refiere a la primera decisión d1 tomada desde el estado inicial E0 sin embargo.

Es un problema NP. 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). Así. 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. k-1) DO Solucion k := nodo. pero necesitamos una solución eficiente. pues tenemos ya una solucion mayor. Después simplemente se llama recursivamente al algoritmo para generar los estados descendientes. En este punto podemos retroceder (y no seguir avanzando por mas ramas). Objetivo: obtener buenas soluciones en un tiempo de ejecución corto. Normalmente. Algoritmos Heuristicos Existen muchos problemas para los cuales no se conocen algoritmos que puedan encontrar la solución de forma eficiente: problemas NP-completos. La solución exacta puede requerir un orden factorial o exponencial: el problema de la explosión combinatoria. Problema de optimización. Posibilidades: . A). evitando así la exploración de gran parte de al estructura. solucion) La llamada inicial del algoritmo es Retroceso(1. 1. IF R(solucion.k) THEN << guardar µsolucion¶ >>. El problema del viajante Problema: Dado un grafo no dirigido. solucion). Este mismo proceso se repite en el resto de nodos del árbol. 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. Se sale del bucle FOR cuando no quedan mas valores para solución terminando la llamada actual al algoritmo. se comprueba si se ha encontrado una solucion. Retroceso (k+1. k) THEN IF R(solucion. completo y ponderado G = (V. 1. 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. k sirve de cota inferior al retroceso.VAR nodo : elemento FOR noso IN G(solucion. 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. 1. donde la solución está formada por un grupo de elementos en cierto orden: podemos aplicar el esquema voraz. La estructura de algoritmo voraz se puede utilizar para construir procedimientos heurísticos: hablamos de heurísticas voraces. encontrar un ciclo simple de costo mínimo que pase por todos los nodos. se basa en un conocimiento intuitivo del programador sobre un determinado problema.

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

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. entre otros. En consecuencia. Finalmente veremos los que es la verificación y derivación de programas.análisis y diseño. también por la propia definición. 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.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¶. De igual forma podremos ver las definiciones y algunas características. vital para el desarrollo de aplicaciones para computadorasy el manejo y dominio de la lógica de programación para resolver problemas. Este nuevo problema garantiza conseguir un recubrimiento que contiene no más de dos vértices del recubrimiento mínimo. 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. y seguirá siendo. por lo menos la mitad de los vértices de M deben pertenecer a un recubrimiento. 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. su importancia en el mundo de las aplicaciones para computadoras y el manejo de lógica de programación. En el mismo podremos encontrar los conceptos de algoritmo y algunos de sus componentes. . 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. reglas. Esto es evidente. Específicos : Introducir los conceptos propios sobre Algoritmo. la recursividad e iteración. En ese mismo orden encontraremos las diferentes técnicaspara diseñarlos como son el método de la fuerza bruta. ningún vértice perteneciente a M puede recubrir a mas de una arista en M. Objetivos General : Posibilitar la estudiante alcanzar una visión sistemática de lo que conocemos sobre Los Algoritmos Computacionales. normas. el voraz. donde daremos los conceptos básicos de semánticay sus tipos haciendo mayor énfasis en la semántica axiomática. tipos de algoritmos de búsqueda y ordenación así como sus aplicaciones. Para poder aplicar el nuevo problema aproximado. En el siguiente trabajopretendemos presentar una serie de conceptoy definiciones propios del estudio de los Algoritmos. divide y vencerás. de vuelta atrás. que desde su aparición hasta nuestros días es. El procedimiento para construir un ajuste maximizal de un grafo G consistiría en ir tomando aristas de G. los vértices incidentes a las aristas de M son un recubrimiento de G. Con el objetivoinmediato de aprobar con los mejores meritos la asignatura de Algoritmos Computacionales. ya que por la definición de ajuste maximal. Justificacion Es importante el estudio y conocimiento de lo que hoy conocemos como Algoritmos Computacionales. programación dinámica. su análisis y diseño.

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

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

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

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

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

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

nnn å 1 = n Î O(n). siendo c y d constantes positivas. $ n0 Î N. 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. " n ³ n0: t(n) ³ c·f(n) } La notación omega se usa para establecer cotas inferiores del tiempo de ejecución..+a1x+a0 es O(xn).. para valores de n suficientemente grandes.Es necesario en este momento mencionar algo sobre como hacerlo. 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 ..±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). Los logaritmos son del mismo orden. independientemente de la base. Ejemplo... si p es un polinomio de menor grado que q... otra para n/2. El acto de diseñar un algoritmo puede considerarse como una tarea que difícilmente podrá ser del todo . Orden exacto de f(n): Q (f): Dada una función f: N ® R+. $ n0 Î N.001... å im Î O(nm+1) i=1 i=1 i=1 Si hacemos una operación para 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. si p y q son polinomios del mismo grado. asintóticamente y salvo constantes.. Orden inferior u omega de f(n): W (f): Dada una función f: N ® R+. Q (f) = O(f) Ç W (f) = { t: N ® R+ / $ c. Relación de orden: igual que antes. " 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+.. å i = n(n+1)/2 Î O(n2). W (f)= { t: N ® R+ / $ c Î R+. llamamos orden exacto de f al conjunto de todas las funciones de N en R+ que crecen igual que f. . n/4. O(p) Ì O(q). d Î R+. aparecerá un orden logarítmico O(log2 n). t Î O(g) ‡Se cumple que: O(c) = O(d). Ì O(2n) Ì O(n!) Ì O(nn) ¿Qué pasa con las omegas? ¿Y con los órdenes exactos? El orden de un polinomio anxn+. 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. 5.) Ì O(n2) Ì O(n3) Ì .

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

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

donde puede consultarse otras veces que se necesite. El proceso finaliza cuando se ha devuelto todo el cambio. siendo ( n ) mayor que( 0 ).B. se trata de dar como cambio la menor cantidad posible usando estos tipos de monedas. la moneda de mayor valor ( es decir. . se almacena en una tabla. la búsqueda en estructuras ordenadas. si es posterior. Ejemplo: Sea el problema de la competición. que juegan una competición que es ganada por el primero que venza en n partidos. y así sucesivamente. De todas formas. resolver independientemente los subproblemas para luego combinar sus soluciones y obtener la solución del problema original. Esta técnica también se suele emplear con la programación dinámica. cuando se pueda. Ejemplo. mientras el valor de dicha moneda sea mayor o igual al cambio que resta por dar). De forma que cada uno tiene un 50% de posibilidades de ganar cada partido. Divide y vencerás: Consiste en descomponer un problema en un subproblema. El procedimiento se repite sucesivamente hasta encontrar la palabra o decidir que no aparece. la ordenación de vectores.Tabulacion No todos los algoritmos recursivos ineficientes pueden optimizarse con la técnica de los parámetros acumuladores. La estrategia voraz aplicada comienza devolviendo. Hay dos participantes (deportistas o equipos. se buscara en la segunda mitad. en una maquina expendedora de tabaco).. la planificación en el orden de la ejecución de unos programas en un computador.etc. Si no ha encontrado y es anterior se procede a buscarla en la primera mitad. como el conocido de la mochila. se supone que ambos participantes tienen cualidades y preparación similar . Por sencillez .Para ello. continua aplicándose el mismo criterio para la segunda moneda mas valiosa. Puede emplearse en problemas de optimización. Ejemplo. la modificación para incorporar probabilidades diferentes es evidente y no complica el problema. 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. Método voraz: Este método trata de producir tipo de mejor resultado a partir de conjunto de opciones candidatas . 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. A. 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. no importa que). La intención es que la primera vez que se realiza un cálculo. Suponiendo que se disponga de cantidad suficiente de ciertos tipos diferentes de monedas de curso legal. 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. 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. en la búsqueda de caminos mínimos sobre grafos.etc. Otra técnica útil es el uso de tablas. Esta técnica se puede aplicar con éxito a problemas como la multiplicación de matrices.

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

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

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

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

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

es más complejo. Si el numero de participantes es 2k . la unión de estos subcalendarios no forma un calendario completo para el campeonato de 2k participantes. faltan por elaborar las competiciones cruzadas entre los participantes de numeración inferior y los de numeración superior. El subcalendario del primer participante es sencillo porque basta con que compita en días sucesivos con los participantes de numeración.. Sin embargo.2n .N.1.. ya que a unión de los dos calendarios tiene un tamaño 2k x(2k-1 -1). por ejemplo.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. es decir. OUT tabla : (1. El algoritmo descrito se expresa a continuación. sucesivamente con los participantes 2k-1 +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. El caso recursivo.N) 1. faltando 2k x2k-1 celdas para completar el calendario total. La solución es directa porque se celebra una sola competición entre ambos. Por fortuna. Completemos primero la parte de los participantes de numeración inferior..N-1) -> VAR ¦ . En efecto. para k>1. IN sup :1. cuando hay más de dos participantes. ..N)1. de numeración comprendida entre 1 y 2k-1 y otro para los participantes comprendidos entre 2k-1 +1 y 2k .N.N-1) -> PROCEDURE FormaTabla (IN inf : 1.1.. El caso básico se da cuando solo hay dos participantes. superior en orden creciente de numeración. rotando dicha secuencia a la derecha. 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.N... el resto del calendario se puede construir fácilmente... PROCEDURE Calendario ( INOUT tabla : (1.N. 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. 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). Este proceso se repite para el resto de los participantes de numeración inferior.

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

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

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

La ecuación de recurrencia puede formularse de dos formas: delantera o trasera.l). El razonamiento anterior se refiere a la primera decisión d1 tomada desde el estado inicial E0 sin embargo. Sea D = { v1 . 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). Además. a tomar... a partir de la secuencia de decisiones Xi+1 Xn ( es la clase de formulación adoptada hasta ahora ).vn} el conjunto de valores de decisión posibles para la decisión d1. la ecuación de base establece el valor para la etapa n+1 en que no queda ninguna decisión Xi. puede generalizarse la formulación del problema a cualquier subsecuencia de decisiones dk . 1<i<n . partiendo como estado inicial de Ek-1. 1<i<n.. La formulación delantera expresa la decisión de Xl .dl. ¨ ¨¨ ¨ ¨ . De esta forma se reduce al número total de subsecuencias generadas. el número de secuencias de decisión es exponencial sobre el número de decisiones. sea. Tiene sentido centrarse en un subproblema del problema inicial porque éste satisface el principio de optimalidad pero. La expresión inicial de la ecuación de recurrencia. a partir de la recurrentes con formulación trasera es igual que e la formulación delantera. 1<i<N1. Usando una técnica de fuerza bruta. 1<i<n. resultará un total de d secuencias posibles de decisión. si este subproblema de simboliza como problema (k. sencillamente.) Una solución dinámica para problema ( k. Supongamos que tenemos un problema que satisface el principio de optimalidad. Sea X1 . del gusto del programador. 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. que es problema ( n. Entonces.n ). sólo que en orden contrario.n ). 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. 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.Xn la secuencia de decisiones necesaria para resolver el problema. La elección de una formulación delantera o trasera depende del problema considerado o. entonces el problema completo es problema ( l. En resumen. asimismo. La formulación trasera expresa la decisión de Xi. ( 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.1 ) debe expresarse en términos de los valores de decisión existente para decisiones d1 y el subproblema problema ( k+1. 1<i<n. 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. además. 1<k<n. Podemos formalizar algo más la idea básica. tal que Eo es el estado inicial del problema y deben tomarse n decisiones d.1 ) resultante de aplicar cada valor de decisión.propiedad de que cualquier subsecuencia de decisiones también debe ser óptima respecto al subproblema que resuelva ". una secuencia óptima de decisiones respecto a E0 es la mejor secuencias de decisión { Vli Sli }.. 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. hay un caso en que la decisión d1 no va seguida por ninguna secuencia de decisiones. 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. porque si hay d opciones para cada una de las n decisiones.

El Algoritmo de Vuelta Atrás se especifica de la forma siguiente: PROCEDURE Retroceso (IN k : INTEGER.. Otros problemas satisfacen el principio de optimalidad. Sin embargo. Sea G(x1. Por lo tanto....cada solución es el resultado de una secuencia de decisiones. Se sale del bucle FOR cuando no quedan mas valores para solución terminando la llamada actual al algoritmo. Después simplemente se llama recursivamente al algoritmo para generar los estados descendientes. k sirve de cota inferior al retroceso. todavía hay otros problemas peores que no queda mas remedio que realizar una búsqueda de la solución. En algunos problemas de optimización se conoce un criterio óptimo de selección que puede usarse de forma voraz. En este punto podemos retroceder (y no seguir avanzando por mas ramas). Algoritmos Heuristicos Existen muchos problemas para los cuales no se conocen algoritmos que puedan encontrar la solución de forma eficiente: problemas NP-completos.. IF R(solucion.xi) el conjunto de todos los valores posibles de xi+1 tales que (x1... solucion) La llamada inicial del algoritmo es Retroceso(1.xi+1) es falso si el camino (xi... Supongamos que existe algún predicado acotador A tal que A(x1.xi+1) no puede extenderse para alcanzar un nodo de respuesta. solucion). Así. INOUT solucion : elemento1. se comprueba si se ha encontrado una solucion.n son aquellos valores generados por G que satisfacen A.. evitando así la exploración de gran parte de al estructura.. 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.. Por supuesto. Este mismo proceso se repite en el resto de nodos del árbol. 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. Esquema de Algoritmos de Vuelta Atrás: Sea (x1. 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.... Retroceso (k+1. .. los candidatos para la posición i+1 del vector desolucion x1. k-1) DO Solucion k := nodo.. Supongamos que también existe algún predicado R que determina si un camino (x1.xi+1) es un camino hasta el estado del problema. k) THEN IF R(solucion. 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).xi+1) termina en un nodo de respuesta.xi) el camino desde la raíz hasta un nodo de un árbol del espacio de estado. pudiéndose aplicar la técnica de programación dinámica. pues tenemos ya una solucion mayor. 1...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.k) THEN << guardar µsolucion¶ >>. 1....

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

próximas a la óptima. normalmente ambos dan soluciones buenas. .Conclusiones: Ninguno de los dos algoritmos garantiza una solución óptima. A continuación se ilustra este tipo de tratamiento de problemas al problema de recubrimiento de un grafico: Dado un grafo G=(V.A). es probable que no sepamos resolverlo de manera precisa y completa utilizando un algoritmo polimico en tiempo. por lo menos la mitad de los vértices de M deben pertenecer a un recubrimiento. Para poder aplicar el nuevo problema aproximado. En consecuencia. también por la propia definición. 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. El procedimiento para construir un ajuste maximizal de un grafo G consistiría en ir tomando aristas de G. los vértices incidentes a las aristas de M son un recubrimiento de G. los algoritmos que no conducen a una solución óptima se llaman algoritmos de aproximación. a partir de la solución del algoritmo intentar hacer modificaciones locales para mejorar esa solució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. como es calcular el ajuste maximizal del grafo G. Este problema se puede resolver a través de otro aproximado. repetir la heurística 1 con varios orígenes. 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¶. ya que por la definición de ajuste maximal. Sin embargo. resulta parcialmente interesante que estos garanticen una cota en el margen de imprecisión. Este nuevo problema garantiza conseguir un recubrimiento que contiene no más de dos vértices del recubrimiento mínimo. Sin embargo. 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. Algoritmos De Aproximación Dado un problema NP completo. Posibles mejoras: buscar heurísticas mejores. ó bien. Esto es evidente. Para este tipo de problemas. ningún vértice perteneciente a M puede recubrir a mas de una arista en M.