You are on page 1of 28

www.monografias.

com

Algoritmos computacionales
Indice

1. Introduccin
2. Marco Historico 3. Generalidades 4. Anlisis De Algoritmos 5. Tcnica de diseo de algoritmos 6. Algoritmos de bsqueda y ordenacin 7. Verificacin y derivacin de programas 8. Anlisis Foda 9. Conclusin 10. Bibliografa 1. Introduccin En el siguiente trabajo pretendemos presentar una serie de concepto y definiciones propios del estudio de los Algoritmos, su anlisis y diseo. En el mismo podremos encontrar los conceptos de algoritmo y algunos de sus componentes, anlisis y diseo. Tambin veremos los diferentes tipos de formas y tamaos 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 tcnicas para disearlos como son el mtodo de la fuerza bruta, el voraz, divide y vencers, programacin dinmica, de vuelta atrs, entre otros. De igual forma podremos ver las definiciones y algunas caractersticas, reglas, normas, tipos de algoritmos de bsqueda y ordenacin as como sus aplicaciones. Finalmente veremos los que es la verificacin y derivacin de programas, donde daremos los conceptos bsicos de semntica y sus tipos haciendo mayor nfasis en la semntica axiomtica, la recursividad e iteracin, los diseos de estos ltimos, as como los tpicos ciclos utilizados en algoritmos y programas y los paso a tener en cuenta al momento de desarrollar un algoritmo iterativo o recursivo. Justificacion Es importante el estudio y conocimiento de lo que hoy conocemos como Algoritmos Computacionales, que desde su aparicin hasta nuestros das es, y seguir siendo; vital para el desarrollo de aplicaciones para computadoras y el manejo y dominio de la lgica de programacin para resolver problemas. Motivacin Como estudiantes de la Facultad de Ciencias y Tecnologa Escuela de Informtica y Computacin de la Universidad Dominicana Organizacin y Mtodos O&M con aspiraciones de iniciarnos como Ingeniero en Sistemas y Computacin. Con el objetivo inmediato de aprobar con los mejores meritos la asignatura de Algoritmos Computacionales. Objetivos General : Posibilitar la estudiante alcanzar una visin sistemtica de lo que conocemos sobre Los Algoritmos Computacionales. Especficos : Introducir los conceptos propios sobre Algoritmo, su importancia en el mundo de las aplicaciones para computadoras y el manejo de lgica de programacin. Proporcionar una idea de su uso. Visualizar sus ventajas e importancia. Definir sus tipos y variantes. Proporcionar conceptos sobre su anlisis y diseo. Proporcionar concepto sobre las tcnicas de diseo. Desglosar sus variantes (ordenacin, bsqueda, etc. ). 2. 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 Matemtico rabe Mohamed

Ibn Al Kow Rizmi, el cual escribi sobre los aos 800 y 825 su obra Quitad Al Mugabala, donde se recoga el sistema de numeracin hind y el concepto del cero. Fue Fibinacci, el que tradujo la obra al latn y el inicio con la palabra: Algoritmi Dicit. El lenguaje algortmico es aquel por medio al cual se realiza un anlisis previo del problema a resolver y encontrar un mtodo 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 mtodo para resolver un problema mediante una serie de datos precisos, definidos y finitos. 3. Generalidades El programador de computadoras es ante que nada una persona que resuelve problemas, por lo que para llegar a ser un programador eficaz se necesita aprender a resolver problemas de un modo riguroso y sistemtico. A la metodologa necesaria para resolver problemas mediante programas se denomina Metodologa de la Programacin. El eje central de esta metodologa es el concepto, ya tratado, de algoritmo. Un algoritmo es un mtodo para resolver un problema. Aunque la popularizacin del trmino ha llegado con el advenimiento de la era informtica, algoritmo proviene de Mohammed al-Khowarizmi, matemtico persa que vivi durante el siglo IX y alcanzo gran reputacin por el enunciado de las reglas para sumar, restar, multiplicar y dividir nmeros decimales; la traduccin al latn del apellido de la palabra algorismus derivo posteriormente en algoritmo. Euclides, el gran matemtico griego (del siglo IV antes de Cristo) que invento un mtodo para encontrar el mximo comn divisor de dos nmeros, se considera con AlKhowarizmi 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, significndonos que solo se puede llegar a realizar un buen programa con el diseo de un algoritmo y una correcta estructura de datos. Esta ecuacin ser de una de las hiptesis fundamentales consideradas en esta obra. La resolucin de un problema exige el diseo de un algoritmo que resuelva el problema propuesto. Error: Reference source not found Los pasos para la resolucin de un problema son: 1. Diseo de algoritmo, que describe la secuencia ordenada de pasos que conducen a la solucin de un problema dado. (Anlisis del problema y desarrollo del algoritmo). 2. Expresar el algoritmo como un programa de lenguaje de programacin adecuado. (Fase de codificacin.) 3. Ejecucin y validacin del programa por la computadora. Para llegar a la realizacin de un programa es necesario el diseo previo de algoritmo, de modo que sin algoritmo no puede existir un programa. Los algoritmos son independientes tanto del lenguaje de programacin en que se expresan como de la computadora que lo ejecuta. En cada problema el algoritmo se puede expresar en un lenguaje diferente de programacin y ejecutarse en una computadora distinta; sin embargo, el algoritmo ser siempre el mismo. As, por ejemplo, en una analoga con la vida diaria, una receta de un plato de cocina se puede expresar en espaol, ingles o francs, pero cualquiera que sea el lenguaje, los pasos para la elaboracin del plato se realizaran sin importar el idioma del cocinero. En la ciencia de la computacin y en la programacin, los algoritmos son ms importantes que los lenguajes de programacin o las computadoras. Un lenguaje de programacin es tan solo un medio para expresar un algoritmo y una computadora es solo un procesador para ejecutarlo. Tanto el lenguaje de programacin como la computadora son los medios para obtener un fin: conseguir que el algoritmo se ejecute y se efecte el proceso correspondiente. Dada la importancia del algoritmo en la ciencia de la computacin, un aspecto muy importante ser el diseo de algoritmos. El diseo de la mayora de los algoritmos requiere creatividad y conocimientos profundos de la tcnica de la programacin. En esencia, la solucin de un problema se puede expresar mediante un algoritmo. Caractersticas de los Algoritmos: Las caractersticas fundamentales que debe cumplir todo algoritmo son: Un algoritmo debe ser preciso e indicar el orden de realizacin 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 algn momento; o

sea, debe tener un numero finito de pasos. La definicin 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: elaboracin de la receta en la cocina. Salida: terminacin del plato (por ejemplo, cordero). Ejemplo de Algoritmo: Un cliente ejecuta un pedido a una fbrica. 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. inicio 2. leer el pedido 3. examinar la ficha del cliente 4. si el cliente es solvente aceptar pedido; en caso contrario, rechazar pedido 5. fin Diseo del Algoritmo: En la etapa de anlisis del proceso de programacin se determina que hace el programa. En la etapa de diseo se determina como hace el programa la tarea solicitada. Los mtodos mas eficaces para el proceso de diseo se basan en el conocido por Divide y Vencers, es decir, la resolucin de un problema complejo se realiza dividiendo el problema en sub problemas y a continuacin dividir estos sub problemas en otros de nivel mas bajo, hasta que pueda ser implementada una solucin en la computadora. Este mtodo se conoce tcnicamente como diseo descendente (Top Down) o modular. El proceso de romper el problema en cada etapa y expresar cada paso en forma ms 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 diseado consta de un programa principal (el modulo de nivel mas alto) que llama a sub programas (mdulos 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 diseo modular y el mtodo de romper el programa en mdulos ms pequeo se llama Programacin Modular. Los mdulos pueden ser planeados, codificados, comprobados y depurados independientemente (incluso por diferentes programadores) y a continuacin combinarlos entre si. El proceso implica la ejecucin de los siguientes pasos hasta que el programa se termina: programar modulo. Comprobar el modulo. Si es necesario, depurar el modulo. Combinar el modulo con los mdulos anteriores. El proceso que convierte los resultados del anlisis del problema en un diseo modular con refinamiento sucesivo que permitan una posterior traduccin al lenguaje se denomina diseo de algoritmo. El diseo del algoritmo es independiente del lenguaje de programacin en el que se vaya a codificar posteriormente. 4. Anlisis De Algoritmos Recursos De Computadores Y Complejidad Algoritmo: Conjunto de reglas para resolver un problema. Su ejecucin requiere unos recursos. Un algoritmo es mejor cuantos menos recursos consuma, su facilidad de programarlo, corto, fcil de entender, robusto, etc. Criterio empresarial: Maximizar la eficiencia.

Eficiencia: Relacin entre los recursos consumidos y los productos conseguidos. Recursos consumidos: Tiempo de ejecucin. 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. Cuntos 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 mquina... En general los recursos dependen de: Factores externos. El ordenador donde lo ejecutemos: 286, Pentium III, Cray,... El lenguaje de programacin y el compilador usado. La implementacin que haga el programador del algoritmo. En particular, de las estructuras de datos utilizadas. Tamao 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 rpida ejecucin. Peor caso. La ejecucin ms lenta posible. Caso promedio. Media de todos los posibles contenidos. Los factores externos no aportan informacin sobre el algoritmo. Conclusin: Estudiar la variacin del tiempo y la memoria necesitada por un algoritmo respecto al tamao de la entrada y a los posibles casos, de forma aproximada (y parametrizada). externos no aportan informacin sobre el algoritmo. Normalmente usaremos la notacin T(N)=..., pero qu significa T(N)? Tiempo de ejecucin en segundos. T(N) = bN + c. Suponiendo que b y c son constantes, con los segundos que tardan las operaciones bsicas correspondientes. Instrucciones ejecutadas por el algoritmo. T(N) = 2N + 4. Tardarn todas lo mismo? Ejecuciones del bucle principal. T(N) = N+1. Cunto tiempo, cuntas instrucciones,...? Sabemos que cada ejecucin lleva un tiempo constante, luego se diferencia en una constante con los anteriores. Asignacin de tiempos, para el conteo de instrucciones. Algunas reglas bsicas. Operaciones bsicas (+, -, *, :=,...): Una unidad de tiempo, o alguna constante. Operaciones de entrada salida: Otra unidad de tiempo, o una constante diferente. Bucles FOR: Se pueden expresar como una sumatoria, con los lmites del FOR. IF y CASE: Estudiar lo que puede ocurrir. Mejor caso y peor caso segn la condicin. Se puede predecir cundo se cumplirn las condiciones? Llamadas a procedimientos: Calcular primero los procedimientos que no llaman a otros. Bucles WHILE y REPEAT: Estudiar lo que puede ocurrir. Existe una cota inferior y superior del nmero de ejecuciones? Se puede convertir en un FOR? El anlisis de algoritmos tambin puede ser a posteriori: implementar el algoritmo y contar lo que tarda para distintas entradas. Ejemplo. Programa cifras.exe: N= 4, T(4)= 0.1 ms N= 5, T(5)= 5 ms N= 6, T(6)= 0.2 s

N= 7, T(7)= 10 s N= 8, T(8)= 3.5 min Qu conclusiones podemos extraer? Anlisis a priori: Evitamos la implementacin, si el algoritmo es poco eficiente. Podemos hacer previsiones. Podemos comparar con otros algoritmos. Medidas Asintoticas Notacin asinttica: El tiempo de ejecucin T(n) est dado en base a unas constantes que dependen de factores externos. Nos interesa un anlisis que sea independiente de esos factores. Notaciones asintticas: Indican como crece T, para valores suficientemente grandes (asintticamente) sin considerar constantes. O(T): Orden de complejidad de T. W(T): Orden inferior de T, u omega de T. Q(T): Orden exacto de T. Orden de complejidad de f(n): O(f) Dada una funcin f: N R+, llamamos orden de f al conjunto de todas las funciones de N en R+ acotadas superiormente por un mltiplo real positivo de f, para valores de n suficientemente grandes. O(f)= { t: N R+ / $ c R+, $ n0 N, " n n0: t(n) cf(n) } Nota: O(f) es un conjunto de funciones, no una funcin. Valores de n sufic. Grandes...: no nos importa lo que pase para valores pequeos. Funciones acotadas superiormente por un mltiplo de f...: nos quitamos las constantes. La definicin es aplicable a cualquier funcin de N en R, no slo tiempos de ejec. Propiedades P1. Si f O(g) y g O(h) entonces f O(h). Si f W(g) y g W(h) entonces f W(h) Ej. 2n+1 O(n), n O(n2) 2n+1 O(n2) P2. Si f O(g) entonces O(f) O(g). Cmo es la relacin para los W? P3. Dadas f y g de N en R+, se cumple: i) O(f) = O(g) f O(g) y g O(f) ii) O(f) O(g) f O(g) La relacin de orden entre O(..) es completa? Dadas f y g, se cumple O(f)O(g) O(g)O(f)? P4. Dadas f y g, de N en R+, O(f+g) = O(max(f, g)). W(f+g) = W(max(f+g)) Y para los Q(f+g)? Es cierto que O(f - g) = O(max(f, -g))? P5. Dadas f y g de N en R+, se cumple: i) limn f(n) R+ O(f)=O(g), W(f)=W(g), Q(f)=Q(g) g(n) ii) limn f(n) = 0 O(f) O(g), W(g) W(f) g(n) P5. Ej. Qu relacin hay entre O(log2 n) y O(log10 n)? P6. Dadas f y g de N en R+, O(f)=O(g) Q(f)=Q(g) f Q(g) W(f)=W(g) P7. Dadas f y g de N en 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)

Notacin con varios parmetros: En general, el tiempo y la memoria consumidos pueden depender de muchos parmetros. f: Nm R+ (f: Nx...m..xN R+) Ej. Memoria en una tabla hash. M(B,n, l, k) = kB+l+n+2kn Orden de complejidad de f(n1, n2, ..., nm): O(f) Dada una funcin f: Nm R+, llamamos orden de f al conjunto de todas las funciones de Nm en R+ acotadas superiormente por un mltiplo real positivo de f, para valores de (n1, ..., nm) suficientemente grandes. O(f)= { t: Nm R+ / $ c R+, $ n1, n2, .., nm N, " k1 n1 , k2 n2 ,..," km nm : t(k1, k2, ..., km) cf(k1, k2, ..., km) } De la misma forma, podemos extender los conceptos de W(f) y Q(f), para funciones con varios parmetros. Las propiedades se siguen cumpliendo Demostrarlo. Ejemplo. T(N) = T(N, a, b) = aN + b El tiempo depende del tamao del problema N, y del tiempo de inicializacin b y de ejecucin de un paso a. Podemos suponerlos constantes T(N), o variables T(N,a,b). Qu relacin hay entre los siguientes rdenes? O(n+m), O(nm) O(n2), O(n+2m) Notaciones condicionales: En algunos casos interesa estudiar el tiempo slo para ciertos tamaos de entrada. Ejemplo. Algoritmo de bsqueda binaria: Si N es potencia de 2 el estudio se simplifica. Orden condicionado de f(n): O(f | P) Dada una funcin f: N R+, y P: N B, llamamos orden de f segn P (o condicionado a P) al conjunto: O(f | P)= { t: N R+ / $ c R+, $ n0 N, " n n0: P(n) t(n) cf(n) } De igual forma, tenemos W(f | P) y Q(f | P). O(f) = O(f | true). Para cualquier f y g, f O(g | false). O(f) O(f | P)? Ordenes De Complejidad Uso de los rdenes de complejidad: Dado un tiempo t(n), encontrar la funcin f ms simple tal que t O(f), y que ms se aproxime asintticamente. Ejemplo. t(n) = 2n2/5 + 3p/2; t(n) O(n2). Relacin de orden entre O(..) = Relacin de inclusin entre conjuntos. O(f) O(g) O(f) O(g) Para toda t O(f), t O(g) Se cumple que: O(c) = O(d), siendo c y d constantes positivas. O(c) O(n) O(cn + b) = O(dn + e) O(p) = O(q), si p y q son polinomios del mismo grado. O(p) O(q), si p es un polinomio de menor grado que q. Orden inferior u omega de f(n): W(f): Dada una funcin f: N R+, llamamos omega de f al conjunto de todas las funciones de N en R+ acotadas inferiormente por un mltiplo real positivo de f, para valores de n suficientemente grandes. W(f)= { t: N R+ / $ c R+, $ n0 N, " n n0: t(n) cf(n) } La notacin omega se usa para establecer cotas inferiores del tiempo de ejecucin. Relacin de orden: igual que antes. Orden exacto de f(n): Q(f):

Dada una funcin f: N R+, llamamos orden exacto de f al conjunto de todas las funciones de N en R+ que crecen igual que f, asintticamente y salvo constantes. Q(f) = O(f) W(f) = = { t: N R+ / $ c, d R+, $ n0 N, " n n0: cf(n) t(n) df(n) } Notacin o pequea de f(n): o(f): Dada una funcin f: N R+, llamamos o pequea de f al conjunto de todas las funciones de N en R+ que crecen igual que f asintticamente: o(f)= { t: N R+ / lim t(n)/f(n) = 1}n Esta notacin conserva las constantes multiplicativas para el trmino de mayor orden. Ejemplo. 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(nlog n) O(n(log n)2) O(n1.001...) O(n2) O(n3) ... O(2n) O(n!) O(nn) Qu pasa con las omegas? Y con los rdenes exactos? El orden de un polinomio anxn+...+a1x+a0 es O(xn). n n n 2); im O(nm+1) 1 = n O(n); i = n(n+1)/2 O(n i=1 i=1 i=1 Si hacemos una operacin para n, otra para n/2, n/4, ..., aparecer un orden logartmico O(log2 n). Los logaritmos son del mismo orden, independientemente de la base. 5. Tcnica de diseo de algoritmos Diseo de Algoritmos: Hasta ahora se han realizado algunos comentarios respecto a la necesidad de disear algoritmos correctos y eficientes utilizando los elementos de un lenguaje de programacin .Es necesario en este momento mencionar algo sobre como hacerlo. El acto de disear un algoritmo puede considerarse como una tarea que difcilmente podr ser del todo automatizada. Todo problema algortmico es un reto para su diseador, algunos resultan inmediatos de resolver, otros son bastante complejos. La investigacin en esta rea ha permitido descubrir un conjunto de mtodos o esquemas de diseo hacia los cuales puede orientarse la realizacin de muchos algoritmos. No obstante, y a pesar de que resulta mas adecuado en bastantes casos utilizar alguno de estos esquemas que realizar un diseo desde cero, idear un algoritmo continua siendo una labor bastante creativa donde los conocimientos y la experiencia del propio diseador tiene un papel fundamental. El diseo de un algoritmo que resuelva un problema es, en general, una tarea difcil. Una forma de facilitar esta labor consiste en recurrir a tcnicas conocidas de diseo de algoritmos, se decir, a esquemas muy generales que pueden adaptarse a un problema particular al detallar las partes generales del esquema. Muchos problemas pueden resolverse buscando una solucin fcil y directa pero, a la vez bastante ineficiente. Este mtodo, llamado de fuerza bruta, puede ser muy directo, pero con un poco de anlisis puede encontrarse algoritmos ms eficientes. El esquema mas sencillo quizs sea el llamado divide y vencers, basado en la descomposicin de un problema en subproblemas. Otros esquemas requieren un anlisis minucioso del problema de forma que la solucin se vaya construyendo en etapas. Si puede preverse que decisin conviene en cada etapa para producir cierto tipo de mejor resultado, tenemos una solucin voraz, si la decisin en una etapa, solo puede tomarse tras considerar varias soluciones de otras etapas mas simples, la solucin es dinmica. Aun as, hay problemas cuya solucin no puede hallarse sino mediante un proceso de bsqueda, a pesar de lo complejas que son las operaciones de bsqueda, su uso adecuado mediante el esquema de bsqueda con retroceso (o backtracking) permite ganar gran eficiencia respecto a soluciones de fuerza bruta. Por ultimo, conviene conocer otros mtodos de diseo de algoritmos que tambin resultan de utilidad prctica.

Nos estamos refiriendo a mtodos basados en la mejora de la eficiencia (por ejemplo, el uso de parmetros de acumulacin al resolver problemas utilizando divide y vencers, y el empleo de tablas como estructura auxiliar para la resolucin eficiente de problemas donde se aplica programacin dinmica), y a mtodos basados en transformaciones del dominio para encontrar una solucin mas fcilmente a un problema en un dominio transformado, siendo dicha solucin finalmente adaptada al dominio original. Consideraciones generales Si el hbil programador dispone de un recetario de algoritmos de donde poder seleccionar el ms adecuado para cada problema, su tarea se simplifica. Supongamos que disponemos de una especificacin precisa, completa y consistente del problema a resolver y queremos obtener un algoritmo en el que, dados uno datos de entrada valido, se produzca cierto resultado. Si no nos importa la eficiencia del algoritmo, podramos utilizar un algoritmo general llamado algoritmo del museo britnico. Se programa un computador de manera que parta de un conjunto de axioma matemticos y los que use para reducir aleatoriamente teoremas validos. Aprender los principios bsicos del diseo de algoritmos podemos preguntarnos por un mtodo aceptable. El mas entendido, y quizs el mejor, es organizar el diseo sobre un esquema de algoritmo o una tcnica de diseo que haya demostrado su utilidad para otros problemas. Este mtodo de trabajo es practicable, puesto que existe un nmero reducido de esquema y tcnicas de diseo. El conocimiento de tcnicas de diseo es solo un primer paso para el diseador, que debe completarse con otros conocimientos y, sobre todo, con la experiencia. Mtodo de fuerza bruta Comenzamos el estudio de esquemas algortmicos con un mtodo sencillo, pero que debe evitarse siempre que se pueda, dad su ineficacia; la fuerza bruta. En realidad, no es un esquema algortmico, si no mas bien calificativo Para una forma de disear algoritmos: tomar una solucin directa, poco reflexionada. En principio, esto no es malo, pero dado que no se ha analizado apenas el problema, es muy probable que no se hayan aprovechado propiedades deducibles del problema y que la solucin sea terriblemente ineficiente. Una solucin por fuerza bruta tambin puede resultar adecuada como primera aproximacin a la solucin final, porque su desarrollo puede permitir profundizar ms sobre el problema y conocer propiedades que sean utilizadas para obtener otra versin ms eficiente. Por ejemplos: Algunos algoritmos de bsqueda de un elemento en un vector. Uno de ellos realizaba una bsqueda secuencial con complejidad lineal sobre el tamao del vector y poda usarse con cualquier vector. Otro algoritmo realizaba un bsqueda dicotomica o binaria, con complejidad logartmica, y solo se poda usar cuando el vector estuviese ordenado. El algoritmo primero responde a un razonamiento ms sencillo, por lo que uno puede sentirse tentado a usar siempre. Esta es la solucin de fuerza bruta: una solucin directa, pero poco reflexionada. Lo ms razonable es comprobar si el vector esta ordenado y, en caso positivo, aprovechar esta circunstancia para usar el algoritmo ms eficiente: el de bsqueda binaria. Tcnicas de los Parmetros Acumuladores y de Tabulacion La recurcion es un mecanismo que permite obtener, en combinacin con otras contrucciones, una solucin funcional a muchos problemas. Muchos algoritmos recursivos resultan eficientes, pero no todos: hay algunos fcilmente formulables, pero muy ineficientes. En estos casos, dichos algoritmos pueden servir como una primera aproximacin al algoritmo definitivo, pero debe mejorar su rendimiento para que sea prctico. Veremos dos parmetros para la mejora de eficiencia de algoritmos recursivos: el uso de parmetros acumuladores y el uso de tablas. Cada una se ilustra con un ejemplo distinto. Parmetros Acumuladores Veamos primero una solucin ineficiente que intentaremos mejorar. Ejemplo: Nmeros de Fibonacci Los nmeros de fibonacci suele especificarse como: Fib(0)=1 Fib(1)1 Fib(n+2)=fib(n)+fib(n+1) Esta especificacin de los nmeros de fibonacci tienen una formulacin recursiva inmediata en estilo

funcional. Un modo de evitar problema lo proporciona la tcnica de los parmetros acumuladores, cuya idea bsica se expone a continuacin. La funcin principal usa una funcin auxiliar que tiene los parmetros de aquellas ms algunos adicionales. La funcin principal simplemente realiza una llamada a esta funcin auxiliar en los que los parmetros de aquellas se modifican y los parmetros nuevos toman un valor inicial adecuado . Los parmetros adicionales tienen como misin ir acumulando resultados principales durante el proceso recursivo. Tabulacion No todos los algoritmos recursivos ineficientes pueden optimizarse con la tcnica de los parmetros acumuladores. Otra tcnica til es el uso de tablas. La intencin es que la primera vez que se realiza un clculo, se almacena en una tabla, donde puede consultarse otras veces que se necesite. Esta tcnica tambin se suele emplear con la programacin dinmica. Ejemplo: Sea el problema de la competicin. Hay dos participantes (deportistas o equipos, no importa que), A,B, que juegan una competicin que es ganada por el primero que venza en n partidos, siendo ( n ) mayor que( 0 ). Por sencillez , se supone que ambos participantes tienen cualidades y preparacin similar . De forma que cada uno tiene un 50% de posibilidades de ganar cada partido. De todas formas, la modificacin para incorporar probabilidades diferentes es evidente y no complica el problema. Divide y vencers: Consiste en descomponer un problema en un subproblema, resolver independientemente los subproblemas para luego combinar sus soluciones y obtener la solucin del problema original. Esta tcnica se puede aplicar con xito a problemas como la multiplicacin de matrices, la ordenacin de vectores, la bsqueda en estructuras ordenadas,etc. Ejemplo. Bsqueda de una palabra en un diccionario Como ejemplo sencillo de aplicacin de esta estrategia puede considerarse la bsqueda de una palabra en un diccionario de acuerdo con el siguiente criterio. Se abre el diccionario por la pagina centrar(quedando dividido en dos mitades) y se comprueba si la palabra aparece all o si es lxico grficamente anterior o posterior. Si no ha encontrado y es anterior se procede a buscarla en la primera mitad., si es posterior, se buscara en la segunda mitad. El procedimiento se repite sucesivamente hasta encontrar la palabra o decidir que no aparece. Mtodo voraz: Este mtodo trata de producir tipo de mejor resultado a partir de conjunto de opciones candidatas .Para ello, se va procedimiento paso a paso realizndose la mejor eleccin (usando una funcin objetivo que respeta un conjunto de restricciones ) de entre las posibles. Puede emplearse en problemas de optimizacin, como el conocido de la mochila, en la bsqueda de caminos mnimos sobre grafos, la planificacin en el orden de la ejecucin de unos programas en un computador,etc. Ejemplo. Dar un cambio utilizando el menor nmero de monedas Considrese ahora el problema de la devolucin del cambio al realizar una compra (por ejemplo, en una maquina expendedora de tabaco). Suponiendo que se disponga de cantidad suficiente de ciertos tipos diferentes de monedas de curso legal, se trata de dar como cambio la menor cantidad posible usando estos tipos de monedas. La estrategia voraz aplicada comienza devolviendo, cuando se pueda, la moneda de mayor valor ( es decir, mientras el valor de dicha moneda sea mayor o igual al cambio que resta por dar), continua aplicndose el mismo criterio para la segunda moneda mas valiosa, y as sucesivamente. El proceso finaliza cuando se ha devuelto todo el cambio. Consideraciones y Criterios para Disear Algoritmos Algunas consideraciones estilsticas pueden contribuir a mejor la calidad de los algoritmos (y programas ) mediante la reduccin del numero de errores que aparecen al desarrollar los. Tambin influyen haciendo que nuestro algoritmo resulten ms fciles de leer y entender para otras personas. Los criterios de estilo pueden reflejarse en un conjunto de normas de estilo de codificacin. Ello asegura que tanto algoritmos como programa resulten legibles y puedan modificarse fcilmente en caso de necesidad. Generalmente, estas normas de estilo se dirigen hacia aspectos como la forma de construir

los nombres de variables o tipo de datos que aparezcan., la tipografa seguida ala hora de escribir nombres de variables, subprogramas, palabras claves, etc. El modo de encolumnar las distintas partes de un algoritmo para facilitar su lectura y comprensin, y la normas sobre como y donde deben de introducirse los comentarios. Estilo y calidad de los programas van fuertemente unidos. Ante la pregunta Cules son las caracterstica de un buen algoritmo?, las siguientes respuestas reflejan, cierta medida, los factores que identifican la calidad en ellos . 1. Correccin, el algoritmo debe funcionar. 2. Nunca se debe olvidar que la caracterstica ms simple e importante de un algoritmo es que funcione. Pude aparecer obvio, pero resulta difcil de asegurar en algoritmos complejos. 3. Eficiencia, el algoritmo no debe desaprovechar recursos. La eficiencia de un algoritmo se mide por los recursos que este consume. En particular, se habla de la memoria y del tiempo de ejecucin . A pesar de que con la reduccin de los costes del hardware es posible disear computadores ms rpidos y con ms memoria, no hay que desperdiciar estos recursos y tratar de desarrollar algoritmos ms eficientes. 4. Claridad, el algoritmo debe estar bien documentacin. La documentacin ayuda a comprender el funcionamiento de los algoritmos. Ciertos detalles o algunas partes especiales de los mismos pueden olvidarse fcilmente o quedar oscura si no estn adecuadamente comentadas. En realidad, y de acuerdo con los puntos de vista anteriores, la calidad de un algoritmo tiene muchas facetas y todas ellas importantes. Resumiendo, lo ideal es que nuestro algoritmo resulte correcto, eficiente, claro, fiable y fcil de mantener. 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. Se supone que un problema de esta clase tiene al menos una solucin. Puede haber varias soluciones optimas, en cuyo caso no importa cual se elija. Por ejemplo, sea el problema de encontrar un subconjunto de los arcos de un grafo. Otro ejemplo se da cuando, dados unos ficheros almacenados en una cinta de que el tiempo de recuperacin de un fichero cualquiera sea el mnimo en promedio. A menudo, el problema incluye restricciones adicionales que limitan el nmero posible de soluciones. Normalmente, estos problemas no se intentan resolver de golpe , encontrando de una sola vez la solucin completa y ptima. Es ms frecuente que el subconjunto de la solucin se vaya formando paso a paso, analizando durante cada etapa que elemento conviene aadir a la solucin parcial ya existente. La dificultad principal para resolver esta clase de problemas estriba en el anlisis necesario para poder formular un algoritmo que halle la solucin en varios pasos. Un algoritmo voraz sigue el esquema anterior, pero con la fortuna de que cada vez que aade un elemento a la solucin se tiene la certeza de haber realizado la mejor eleccin posible. Esta caracterstica hace que aunque el anlisis del problema sea arduo, la solucin voraz siempre resulte sencilla. La nica complicacin es comprobar que se siguen satisfaciendo las restricciones del problema. Por lo que se ha descrito del esquema voraz, ste es un proceso repetitivo sencillo que trata sucesivamente los diferentes elementos del problema. Para facilitar la descripcin de este proceso, puede llamarse candidato al elemento tratado en cada paso. Inicialmente, el conjunto de candidatos que forman la solucin est vaco. En cada paso se intenta aadir el mejor de los candidatos restantes a dicha solucin parcial. Si este conjunto ampliado sigue siendo vlido, es decir, si satisface las restricciones del problema y, por tanto, permite formar una solucin del problema, el candidato se incorpora definitivamente. Al contrario, si dicho conjunto no es vlido, se desecha el candidato. Si el algoritmo voraz se ha diseado correctamente, la primera solucin encontrada es ptima. Por tanto, la dificultad principal al disear un algoritmo voraz reside en encontrar un criterio en encontrar un criterio de seleccin que garantice la optimalidad de la solucin. Segn esta descripcin, el problema parte de: Una funcin objetivo que da el valor de una solucin. Obviamente, sta es la funcin por optimizar. Un conjunto de restricciones sobre el valor de los datos de entrada y sobre la solucin final del problema. A su vez, la solucin consta de: Un conjunto de candidatos Una funcin de seleccin que en cada momento determine que candidato de los an no usados parece ser el mejor.

Una funcin que determine si cierto conjunto de candidatos es vlido; es decir, si permite formar alguna solucin del problema. Obsrvese que las funciones de validez y completitud no se preocupan de la optimalidad del la solucin, pero si la funcin de seleccin es la adecuada, cada solucin vlida y completa es optima. Podemos representar el esquema voraz de la siguiente forma funcional: FUNCTION Voraz ( candidatos: ( 1..n ) : ( 1..n) -> FUNCTION VorazAcumulador ( candidatos : (1..n), Solucin : (1..n) : (1..n) -> Cadidatos = ( ) v EsSolucin ( solucin)-> Value siguiente -> seleccionar ( candidatos ) IN EsVlida (solucin v ( siguiente)) => VorazAcumulador (candidatos (solucin), solucin v (siguiente)) VorazAcumulador (candidatos (siguiente), solucin) VorazAcumulador (candidatos, ( ) ) Puede verse por qu estos algoritmos se llaman voraces : en cada paso toman el mejor trozo de la solucin; es decir, el mejor candidato. Adems, nunca cambian de opinin: una vez que un candidato es aceptado o rechazado en la solucin, la decisin, es definitiva. La funcin objetivo no suele aparecer en el algoritmo final, sino que se utiliza durante el anlisis del problema y es determinante en la eleccin de la funcin de seleccin. De todas formas, debe recordarse que puede haber varios criterios alternativos de seleccin y que de su correcta eleccin depende que la solucin calculada por el algoritmo sea optima. Como ejercicio, el lector puede intentar encontrar una solucin voraz del problema del calendario. Es fcil encontrar una solucin si en cada etapa se genera el subcalendario correspondiente a un equipo; es decir, la tabla de competicin se va completando por filas. Como fila primera se toma la secuencia de los ndices de los participantes en cualquier orden. Cada fila resultante puede tener una complejidad de o (n2). Adems, este algoritmo tiene la ventaja de valer para las situaciones en que el nmero de participantes no es una potencia de dos. Desglose en monedas Como primer ejemplo introductorio sencillo al que puede aplicarse la tcnica voraz, se considera el problema de un cambio o desglose en monedas. Hay que desglosar una cantidad en un conjunto de monedas tratando de cumplir alguna condicin; en este caso, utilizar el menor nmero de monedas. Para ello, se parte de un conjunto de tipos de monedas vlidas, de las que se supone que hay cantidad suficiente para realizar el desglose, y de un importe. Se trata de indicar la cantidad (menor) de monedas de los tipos considerados, tales que sumados sus valores equivalgan al importe. Para simplificar, suponemos que manejamos dinero espaol y, en particular, podemos utilizar slo monedas de 500, 100, 50, 25, 5 y 1 pesetas para el desglose. Estos valores se definen por medio de un tipo enumerado MONEDAS. Asimismo, 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. Su declaracin es la siguiente: TYPE Monedas -> M500 I M100 I M50 I M25 I M5 I M1, Valores -> Integer M500M1 Cantidades -> Integer M500.M1 Se supone inicialmente asignados los valores a cada uno de los tipos de monedas. Los elementos de la tcnica voraz estn presentes en este problema de la siguiente forma: 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. Una solucin viene dad por un conjunto de monedas devuelto tras el desglose, y cuyo valor total es igual al importe a desglosar. La condicin de factibilidad de la solucin siendo construida establece en el desglose debe ser menor o igual que el importe a desglosar. La funcin de seleccin establece que hay que elegir, mientras sea posible, la moneda de mayor valor de entre las candidatas. La funcin objetivo cosiste en minimizar la cantidad total de monedas utilizadas en el desglose. Con esta informacin se puede comprobar que en este problema estn presentes los distintos

elementos de la tcnica voraz. Adems, cuando un candidato (moneda) se incorpora al conjunto solucin, ste no ser nunca excluido de l. Divide Y Vencers La tcnica divide y vencers consiste en descomponer el problema en un conjunto de subproblemas ms pequeos. Despus se resuelven estos subproblemas y se combinan las soluciones para obtener la solucin para el problema original. Esquema de Divide y vencers. La tcnica de divide y vencers es quizs una de las utilizadas debido a su sencillez: si un problema es demasiado grande para resolverlo de una vez, se descompone en varias partes ms fciles de resolver. Mas formalmente, dado un problema al resolver planteando en trminos de una entrada de tamao n, la tcnica de divide y vencers parte la entrada en k subproblemas, 1<k<=n. Estos subproblemas se resuelven independientemente y despus se combinan sus soluciones parciales para obtener la solucin del problema original. Este esquema de particin de problemas se denomina esquema de divide y vencers solo en el caso en que los problemas sean de la misma clase del problema original. Esta restriccin permite una formulacin y resolucin recursiva de los subproblemas. Por supuesto, deben existir algunos pasos sencillos cuya solucin pueda calcularse fcil y directamente; en caso contrario, el proceso recursivo nunca terminara. El caso ms frecuente es cuando el nmero de subproblemas es dos. Veamos el esquema de divide y vencers para dos subproblemas; es fcil su generalizacin a k subproblemas 2<k<=n. Su formacin funcional es como sigue, considerado el problema como de tipo dato y la solucin, de tipo resultado: TYPEVAR Dato, resultado FUNCTION DivideYVenceras (problema : dato) : resultado -> EsPequeo (problema) }=> ResolverDirectamente (problema) | VALUE subproblemas -> Partir (problema) IN subproblemas == (subproblema1, subproblema2) => Combinar (DivideYVenceras (subproblema1) , DivideYVenceras (subproblema2)) Se puede hacer una formulacin imperativa similar. Sin embargo, escribiremos una formulacin ms restrictiva pero bastante usual, en la que se utiliza un vector de tamao N. TYPEVAR dato, resultado PROCEDURE DivideYVenceras (IN problema : dato1..n, OUT solucin : resultado) -> PROCEDURE DyVAux (IN problema : dato1..n, IN inferior, superior : 1..N, OUT solucin : resultado) -> VAR medio: 1..N subsolucion1, subsolucion2 : resultado IF EsPequeo (inferior, superior) THEN ResolverDirectamente (problema, inferior, superior, olucin) ELSE Medio := Partir (inferior, superior); DyVAux (problema, inferior, medio, subsolucion1); DyVAux (problema, medio+1, superior, subsolucion2); Combinar (subsolucion1, subsolucion2, solucin) DyVAux (problema, 1, N, solucin) El esquema general se adapta a un problema concreto al sustituir los metasimbolos EsPequeo, ResolverDirectamente, Partir y Combinar por funciones o procedimientos concretos. Si el tamao de los dos subproblemas es el mismo (o casi), el tiempo de cmputo de la funcin DivideYVecneras se describe con la siguiente relacin de recurrencia: g(n),si n es pequeo T(n) = 2 T(n/2) + f(n), en caso contrario donde T(n) es la funcin de tiempo de DivideYVenceras para entradas de tamao n, g(n) es el tiempo

que tarda la funcin ResolverDirectamente en resolver problemas de pequeo tamao (normalmente una constante) y f(n) es el tiempo necesario para partir el problema y combinar las subsoluciones. La eficiencia final del algoritmo depende de la funcin f(n) concreta que aparezca durante el anlisis. Ntese que, es general, para que esta tcnica resulte eficiente todos los subproblemas deben ser de tamao parecido. Elaboracin de un Calendario Deportivo: Sea un campeonato deportivo; para nuestros propsitos resulta indiferente el deporte objeto de la competicin, as que hablaremos de participantes en vez de deportistas o equipos. El problema consiste en elaborar un calendario de competicin de forma que cada participante compita exactamente una vez con cada uno de los dems participantes. Por concrecin, y sin perdida de generalidad, puede suponerse que las competiciones se celebran en das sucesivos y que cada participante compite una vez por da. Para simplificar el problema, se supone que el numero de participantes es una potencia de dos; es decir, hay n = 2k participantes para algn entero positivo k. Se supone tambin que cada participante tiene asignado un nmero comprendido entre 1 y N. Se necesitan elaborar n-1 competiciones por participantes. Por tanto, la solucin del problema puede representarse en una tabla de dimensin nx(n1). El elemento (i,j)esimo de la tabla, 1<= i<=n, 1<=j<n, contiene el numero del participante contra el que el participante i-esimo compite el da j-esimo. Obsrvese que los nmeros 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. A su vez, la columna j tambin contiene nmeros distintos, porque el da j-esimo cada participante solo puede competir con otro participante. Se dispone de una solucin inmediata aplicando fuerza bruta. Primero se obtiene para cada participante i, 1<=i<=n, el conjunto P(i) de todas las permutaciones posibles del resto de los participantes con los que debe competir, es decir, el conjunto de permutaciones de los nmeros {1..n}-{i} ahora se completan las filas de la tabla de todas las formas posibles, incluyendo en cada fila i algn ejemplo de P(i). Solo sirve como solucin aquellas combinaciones de fila que cumplan las restricciones enunciadas en el prrafo anterior sobre las columnas de la tabla (las restricciones sobre las filas estn garantizadas por el modo de generar los conjuntos P(i)). Si hay varios calendarios validos, se elige uno cualquiera. El mtodo de fuerza bruta resulta sencillo, pero es terriblemente ineficiente. Cada conjunto P(i) consta de (n-1)! Elementos. Dado que el numero de participantes de n, resultan nx(n-1)!=n! formas de rellenar la tabla. Sin embargo la aplicacin de la tcnica de divide y vencers produce una solucin mas sencillas aun pero muy eficientes. La siguiente figura describe visualmente parte de la elaboracin de la tabla.

participantes

1 2

das 1 2 1

1 2 3 4

1 2 1 4 3

2 3 4 1 2

3 4 3 2 1

1 2 3 4 5 6 7 8

1 2 1 4 3 6 5 8 7

2 3 4 1 2 7 8 5 6

3 4 3 2 1 8 7 6 5

4 5 8 7 6 1 4 3 2

5 6 5 8 7 2 1 4 3

6 7 6 5 8 3 2 1 4

7 8 7 6 5 4 3 2 1

Se distinguen dos casos. El caso bsico se da cuando solo hay dos participantes. La solucin es directa porque se celebra una sola competicin entre ambos. El caso recursivo, cuando hay ms de dos participantes, es ms complejo. Si el numero de participantes es 2k , para k>1, puede decirse que el tamao del problema es 2k (sabemos que el calendario tendr un tamao de 2k x(2k-1 -1) posiciones). El problema puede reducirse a dos sub problemas de tamao 2k-1 si se elaboran independientemente dos subcalendarios de tamao 2k x(2k-1 -1): uno para los participantes, de numeracin comprendida entre 1 y 2k-1 y otro para los participantes comprendidos entre 2k-1 +1 y 2k . Sin embargo, la unin de estos subcalendarios no forma un calendario completo para el campeonato de 2k participantes, ya que a unin de los dos calendarios tiene un tamao 2k x(2k-1 -1), faltando 2k x2k-1 celdas para completar el calendario

total. En efecto, faltan por elaborar las competiciones cruzadas entre los participantes de numeracin inferior y los de numeracin superior. Por fortuna, el resto del calendario se puede construir fcilmente. Completemos primero la parte de los participantes de numeracin inferior. El subcalendario del primer participante es sencillo porque basta con que compita en das sucesivos con los participantes de numeracin, superior en orden creciente de numeracin; es decir, sucesivamente con los participantes 2k-1 +1,.,2n . El siguiente participante toma esta secuencia y realiza una fcil permutacin de la misma que le garantiza el respeto de las restricciones de la solucin; por ejemplo, rotando dicha secuencia a la derecha. Este proceso se repite para el resto de los participantes de numeracin inferior. El calendario de los participantes de numeracin superior se completa de forma similar con los nmeros de los participantes de numeracin inferior. El algoritmo descrito se expresa a continuacin. PROCEDURE Calendario ( INOUT tabla : (1..N)1..N,1..N-1) -> PROCEDURE FormaTabla (IN inf : 1..N, IN sup :1..N, OUT tabla : (1..N) 1..N,1..N-1) -> VAR medio : 1..N IF inf = sup-1 THEN tablainf.1 : = sup; tablasup.1 := inf ELSE medio := (inf + sup) Div 2; FormarTabla (inf, medio, tabla); FormarTabla (medio+1, sup, tabla); CompletarTabla (inf, medio, medio,sup-1, medio+1, tabla); CompletarTabla (medio+1, sup, medio, sup-1, inf, tabla) Este sistema de ecuaciones defina una funcin de tiempo del orden de O(n2), que es mucho mas eficiente que la solucin de fuerza bruta. Veamos otra estrategia, tambin de orden de complejidad cuadrtica, donde se aplica divide y vencers para resolver el problema y que se aprovecha de la simetra de la solucin. La idea consiste en aadir inicialmente a la tabla una columna ficticia de ndice j=0, que almacena los ndices de las filas. Despus se genera, mediante divide y vencers, la mitad izquierda de la tabla. 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 vencers). En esta ltima etapa, los valores de las casillas (k,l), siendo 1<=k<=n y 0<=l<=(n/2)-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 vacas, es decir, los componentes tablai,j a partir de las casillas tablak,l ya completadas. Ordenacin de un Vector por Mezcla: La ordenacin de un vector es un problema que se presta fcilmente a la aplicacin de la tcnica de divide y vencers. El caso bsico corresponde a un subvector de un solo elemento, que obviamente ya esta ordenado. Para el caso general, sea vi..s un vector de ndice inferior i e ndice superior s. La particin puede hacerse por la mitad si se toma un ndice m=[(i+s)/2] y dos subvectores vi..m y vm+1..s . la combinacin de los dos subvectores ya ordenados es fcil. basta con mezclar los dos subvectores, mediante comparaciones de sus elementos sucesivos, para obtener un nico vector ordenado. Este proceso de mezcla es realizado por un procedimiento auxiliar. El algoritmo resultante es: PROCEDURE Ordenar (INOUT v : INTEGER1..N) -> (* ordenacin por mezcla *) PROCEDURE OrdenarAux (INOUT Vector : INTEGER1..N,1..N, IN inf, sup : 1..N) -> VAR Medio : 1..N

IF inf < sup THEN medio := (inf+sup) Div 2; OrdenarAux (vector, inf, medio); OrdenarAux (vector, medio+1, sup); Mezclar (vector, inf, medio, sup) OrdenarAux (v, 1, N) El procedimiento para realizar la mezcla de los subvectores ordenados es: PROCEDURE Mezclar ( IN inf : INTEGER, IN medio: INTEGER, IN sup : INTEGER, INOUT vector : INTEGER1..N) -> VAR vectorAux : INTEGER1..N, i1, i2, j : INTEGER, ndice : INTEGER i1 := inf; i2 := medio + 1; j := inf; WHILE (i1<=medio) ^ (i2<=sup) DO IF vectori1 << vectori2 THEN vectorAuxj :=vectori1; i1 :=i1 + 1 ELSE vectorAuxj ;= vectori2; i2 := i2 + 1 j := j + 1 FOR ndice IN i1..medio DO vectorAuxj := vectorindice; J := j + 1 FOR ndice IN i2..sup DO vectorAuxj := vectorindice ; J := j + 1 FOR ndice In inf..sup DO vectorindice := vectorAuxindice El algoritmo resultante es sencillo conceptualmente. Es fcil analizar la complejidad del algoritmo para un vector de longitud n. La operacin de mezcla es proporcional a n, de forma que las ecuaciones de recurrencia de la funcin de tiempo son: T(n) = a, n=1, a=cte 2T(n/2) + bn, n>1, b=cte Si n es una potencia de 2; es decir, n =2k para algn k, las ecuaciones anteriores se resuelven por sustituciones sucesivas, resultando: T(n) = 2T(n/2) + bn==2K T(n/2K) + kbn = an + bn log2 n El algoritmo de ordenacin por mezcla es ptimo en tiempo de ejecucin. Los nicos inconvenientes que presenta es que el procedimiento de mezcla necesita gran capacidad de almacenamiento (para dos copias del vector) y que, adems de mezclar, necesita copiar el vector auxiliar completo en el principal. Puede disearse un algoritmo de mezcla ms complejo que mejore ambos aspectos, pero mantenga la complejidad asinttica calculada. Multiplicacin de Matrices: Sean dos matrices, A y B, de dimensin nxn. La matriz producto C=AxB tambin es una matriz de nxn cuyo elemento (i,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. El clculo de cada elemento Cij requiere n multiplicaciones. La matriz C tiene n2 elementos, as que el tiempo total del algoritmo de multiplicacin es de orden O(n3).

El algoritmo anterior, que podemos llamar algoritmo convencional de multiplicacin de matrices, proviene directamente de la definicin matemtica del producto de matrices. Sin embargo, la tcnica de divide y vencers sugiere un algoritmo distinto. Supongamos, por sencillez, que n es una potencia de dos; es decir, que existe un entero no negativo k tal que n=2k. (Si n no es un potencia de dos, pueden aadirse las filas y columnas de ceros necesarias para formar una dimensin que sea potencia de dos.) las submatrices A y B pueden partirse en cuatro submatrices de dimensin (n/2)x(n/2). 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, los elementos Cij se calculan mediante algunas multiplicaciones y sumas de nmeros, pero para n>2 las submatrices Cij se calculan mediante multiplicaciones (recursivas) y sumas de submatrices de dimensin (n/2)x(n/2). Dos submatrices de (n/2)x(n/2) pueden sumarse en un tiempo bn2, siendo b alguna constante. La resolucin de este sistema de ecuaciones nos dice que O(T(n))=OT(n3), de forma que no se ha conseguido ningn ahorro sustancial de tiempo. Sin embargo, interesa encontrar algoritmos mas eficientes, porque la multiplicacin esta relacionada con otras operaciones sobre matrices mas usuales, como inversin de una matriz o hallar su determinante. La existencia de un algoritmo eficiente para la multiplicacin (en realidad, para cualquier operacin de las anteriores) significara la existencia de un algoritmo similar para las dems. Podra conseguirse mas eficiencia si logrramos realizar menos multiplicaciones de matrices, 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). El algoritmo de Strassen calcula las cuatro submatrices Cij empleando 7 multiplicaciones y 18 sumas o restas de matrices. Programacin Dinmica Principios de programacin dinmica Se ha visto que la tcnica voraz se aplica a problemas cuya solucin puede formularse como el resultado de una secuencia de decisiones. El mtodo es eficiente porque una vez que se toma una decisin en un paso, no se reconsidera en el futuro, conduciendo de forma directa a la solucin. Sin embargo, no todos los problemas pueden resolverse de esta manera, asegurando que la secuencia de decisiones es la mejor de las posibles. La programacin dinmica (tambin llamada planificacin dinmica) es una tcnica de programacin que tambin permite resolver problemas mediante una secuencia de decisiones, pero de una manera menos directa que en el caso voraz. Esta vez se necesita producir varias secuencias de decisiones. Solamente al final se sabe cul es la mejor de todas. No es fcil establecer una definicin de la programacin dinmica; una caracterstica es que el programa aprende dinmicamente de las decisiones que toma. Adems, todo problema resoluble con esta tcnica debe de satisfacer el principio de optimalidad. Este principio establece que una secuencia ptima de decisiones que resuelve un problema debe cumplir la propiedad de que cualquier subsecuencia de decisiones tambin debe ser ptima respecto al subproblema que resuelva . Usando una tcnica de fuerza bruta, el nmero de secuencias de decisin es exponencial sobre el nmero de decisiones, porque si hay d opciones para cada una de las n decisiones, resultar un total de d secuencias posibles de decisin. En la programacin dinmica todos los subproblemas se resuelven de acuerdo con criterio de tamao creciente y los resultados de subproblemas ms pequeos se almacenan en algn tipo de estructura de datos (normalmente tablas) para facilitar la solucin de los problemas ms grandes. De esta forma se reduce al nmero total de subsecuencias generadas, evitndose una explosin combinatoria en la produccin de las secuencias y consiguindose soluciones ms eficientes en cuanto a tiempo de ejecucin.

Podemos formalizar algo ms la idea bsica. Supongamos que tenemos un problema que satisface el principio de optimalidad, tal que Eo es el estado inicial del problema y deben tomarse n decisiones d, 1<i<n. sea D = { v1..vn} el conjunto de valores de decisin posibles para la decisin d1. sea, asimismo, Eli el estado del problema tras la eleccin del valor vli 1<i<n1 y Sli una secuencia ptima de decisiones respecto al estao Eli. Entonces, una secuencia ptima de decisiones respecto a E0 es la mejor secuencias de decisin { Vli Sli }, 1<i<N1. El razonamiento anterior se refiere a la primera decisin d1 tomada desde el estado inicial E0 sin embargo, puede generalizarse la formulacin del problema a cualquier subsecuencia de decisiones dk..,dl, 1<k<n, partiendo como estado inicial de Ek-1. si este subproblema de simboliza como problema (k,l), entonces el problema completo es problema ( l,n ). Tiene sentido centrarse en un subproblema del problema inicial porque ste satisface el principio de optimalidad pero, adems, tiene la ventaja ( quizs paradjica al tratar de un problema ms pequeo ) de que proporciona una visin ms general del problema en cuestin. ( Obsrvese que vamos a usar la tcnica de resolucin de problemas por generalizacin para despus poder realizar una particularizacin de la solucin obtenida.) Una solucin dinmica para problema ( k,1 ) debe expresarse en trminos de los valores de decisin existente para decisiones d1 y el subproblema problema ( k+1,1 ) resultante de aplicar cada valor de decisin. La expresin inicial de la ecuacin de recurrencia, hay un caso en que la decisin d1 no va seguida por ninguna secuencia de decisiones, que es problema ( n,n ). En resumen, la aplicacin de la tcnica de programacin dinmica a un problema significa comprobar primero el principio de optimalidad y desarrollar despus unas ecuaciones recurrentes del estilo de (1) y (2). La ecuacin general relaciona la secuencia ptima en una etapa i con la decisin tomada en la etapa i y la subsecuencia ptima en la etapa posterior i+1. la ecuacin de base establece el valor para la etapa n+1 en que no queda ninguna decisin Xi, 1<i<n, a tomar. La ecuacin de recurrencia puede formularse de dos formas: delantera o trasera. Sea X1..Xn la secuencia de decisiones necesaria para resolver el problema. La formulacin delantera expresa la decisin de Xl , 1<i<n, a partir de la secuencia de decisiones Xi+1Xn ( es la clase de formulacin adoptada hasta ahora ). La formulacin trasera expresa la decisin de Xi, 1<i<n , a partir de la recurrentes con formulacin trasera es igual que e la formulacin delantera, slo que en orden contrario. La eleccin de una formulacin delantera o trasera depende del problema considerado o, sencillamente, del gusto del programador. Algoritmos De Vuelta Atrs Existen un alto nmero de problemas que pueden formularse como la bsqueda de la mejor solucin o del conjunto de todas las soluciones que satisfacen ciertas condiciones. Adems, cada solucin es el resultado de una secuencia de decisiones. Por supuesto, debe existir una funcin de criterios que debe ser satisfecha por cada secuencia solucin u optimizada por dichas secuencias solucin si solo queremos la mejor. En algunos problemas de optimizacin se conoce un criterio ptimo de seleccin que puede usarse de forma voraz. Otros problemas satisfacen el principio de optimalidad, pudindose aplicar la tcnica de programacin dinmica. Sin embargo, todava hay otros problemas peores que no queda mas remedio que realizar una bsqueda de la solucin. Esquema de Algoritmos de Vuelta Atrs: Sea (x1,...,xi) el camino desde la raz hasta un nodo de un rbol del espacio de estado. Sea G(x1...xi) el conjunto de todos los valores posibles de xi+1 tales que (x1,...,xi+1) es un camino hasta el estado del problema. Supongamos que existe algn predicado acotador A tal que A(x1,...,xi+1) es falso si el camino (xi,...,xi+1) no puede extenderse para alcanzar un nodo de respuesta. Por lo tanto, los candidatos para la posicin i+1 del vector desolucion x1..n son aquellos valores generados por G que satisfacen A. Supongamos que tambin existe algn predicado R que determina si un camino (x1,...,xi+1) termina en un nodo de respuesta. El Algoritmo de Vuelta Atrs se especifica de la forma siguiente: PROCEDURE Retroceso (IN k : INTEGER, INOUT solucion : elemento1...n) -> VAR nodo : elemento FOR noso IN G(solucion, 1, k-1) DO Solucion k := nodo; IF R(solucion, 1, k) THEN

IF R(solucion, << guardar Retroceso

1,k) THEN solucion >>; (k+1, solucion)

La llamada inicial del algoritmo es Retroceso(1, solucion). El procedimiento no hace ninguna llamada recursiva cuando k = N+1 o cuando ningn nodo generado por G satisface el elemento posible que satisfacen A se aade una solucin particular, se comprueba si se ha encontrado una solucion. Despus simplemente se llama recursivamente al algoritmo para generar los estados descendientes. Se sale del bucle FOR cuando no quedan mas valores para solucin terminando la llamada actual al algoritmo. Ramificacin (Bifurcacion) Y Acotacin Los mtodos de Ramificacin y Acotacin constituyen un a variante de las tcnicas de retroceso para problemas donde se trata de encontrar el valor mximo o mnimo de cierta funcin objeto (esto suele suceder en los problemas de programacin lineal entera). La tcnica de ramificacin y acotacotacion aplica de la siguiente manera: Supngase que al recorrer un rbol y alcanza una hoja se tiene una solucion con k colores, y que al seguir avanzando en el rbol (mediante la aplicacin de varios pasos de retrocesos) se alcanza un nodo que requiere k+1 colores. En este punto podemos retroceder (y no seguir avanzando por mas ramas), pues tenemos ya una solucion mayor. As, k sirve de cota inferior al retroceso. Este mismo proceso se repite en el resto de nodos del rbol, evitando as la exploracin de gran parte de al estructura. Algoritmos Heuristicos Existen muchos problemas para los cuales no se conocen algoritmos que puedan encontrar la solucin de forma eficiente: problemas NP-completos. La solucin exacta puede requerir un orden factorial o exponencial: el problema de la explosin combinatoria. Se hace necesario utilizar algoritmos heursticos: Un algoritmo heurstico (o simplemente heurstica) puede producir una buena solucin (puede que la ptima) pero tambin puede que no produzca ninguna solucin o dar una solucin no muy buena. Normalmente, se basa en un conocimiento intuitivo del programador sobre un determinado problema. La estructura de algoritmo voraz se puede utilizar para construir procedimientos heursticos: hablamos de heursticas voraces. Objetivo: obtener buenas soluciones en un tiempo de ejecucin corto. El problema del viajante Problema: Dado un grafo no dirigido, completo y ponderado G = (V, A), encontrar un ciclo simple de costo mnimo que pase por todos los nodos. Es un problema NP, pero necesitamos una solucin eficiente. Problema de optimizacin, donde la solucin est formada por un grupo de elementos en cierto orden: podemos aplicar el esquema voraz. Posibilidades: 1. Los nodos son los candidatos. Empezar en un nodo cualquiera. En cada paso moverse al nodo no visitado ms prximo al ltimo nodo seleccionado. 2. Las aristas son los candidatos. Hacer igual que en el algoritmo de Kruskal, pero garantizando que se forme un ciclo. Heurstica voraz 1 Una solucin ser un cierto orden en el conjunto de nodos (c1, c2, ..., cn), el orden de visita de los nodos. Inicializacin: seleccionar un nodo cualquiera. Funcin de seleccin: de los nodos candidatos seleccionar el ms prximo al ltimo (o al primero) de la secuencia actual (c1, c2, ..., ca). Acabamos cuando tengamos n nodos. Ejemplo. Empezando en el nodo 1. Solucin: (1, 4, 5, 3, 2)

Coste: 30+15+25+10+45=125 Empezando en el nodo 3. Solucin: (5, 4, 3, 2, 1) Coste: 15+20+10+45+50=140 Heurstica voraz 2 Una solucin ser un conjunto de aristas (a1, a2, ..., an-1) que formen un ciclo hamiltoniano, sin importar el orden. Empezar con un grafo sin aristas. Seleccin: seleccionar la arista candidata de menor coste. Factible: una arista se puede aadir a la solucin actual si no se forma un ciclo (excepto para la ltima arista aadida) y si los nodos unidos no tienen grado mayor que 2. Ejemplo. Solucin: ((2, 3), (4, 5), (3, 4), (1, 2), (1, 5)) Coste = 10+15+20+45+50 = 140 Conclusiones: Ninguno de los dos algoritmos garantiza una solucin ptima. Sin embargo, normalmente ambos dan soluciones buenas, prximas a la ptima. Posibles mejoras: buscar heursticas mejores; repetir la heurstica 1 con varios orgenes; bien, a partir de la solucin del algoritmo intentar hacer modificaciones locales para mejorar esa solucin. Algoritmos De Aproximacin Dado un problema NP completo, es probable que no sepamos resolverlo de manera precisa y completa utilizando un algoritmo polimico en tiempo. Para este tipo de problemas, los algoritmos que no conducen a una solucin ptima se llaman algoritmos de aproximacin. Sin embargo, resulta parcialmente interesante que estos garanticen una cota en el margen de imprecisin. A continuacin se ilustra este tipo de tratamiento de problemas al problema de recubrimiento de un grafico: Dado un grafo G=(V,A), se trata de encontrar un conjunto con el menor numero de vrtices tal que toda arista sea incidente por lo menos de un vrtice de V. Este problema se puede resolver a travs de otro aproximado, como es calcular el ajuste maximizal del grafo G. Se trata de calcular un subconjunto A de aristas tal que dos aristas cualquiera de A no tengan ningn vrtice comn y toda arista de A-A comparta algn vrtice comn con una arista de A. Este nuevo problema garantiza conseguir un recubrimiento que contiene no ms de dos vrtices del recubrimiento mnimo. El procedimiento para construir un ajuste maximizal de un grafo G consistira en ir tomando aristas de G, de una en una y en cualquier orden e ir eliminando las incidentes al conjunto que se esta construyendo hasta recubrir todo en grafo. Para poder aplicar el nuevo problema aproximado, seria necesario demostrar que el conjunto de todos los vrtices 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 tamao mnimo. Esto es evidente, ya que por la definicin de ajuste maximal, los vrtices incidentes a las aristas de M son un recubrimiento de G. tambin por la propia definicin, ningn vrtice perteneciente a M puede recubrir a mas de una arista en M. En consecuencia, por lo menos la mitad de los vrtices de M deben pertenecer a un recubrimiento. 6. Algoritmos de bsqueda y ordenacin En muchas situaciones de programacin es necesario repetir ciertos procedimientos hasta alcanzar un punto en que no se puede o no se desea continuar. Esta repeticin de tareas puede llevarse a cabo bsicamente de dos maneras diferentes: la iteracin y la recursin. Como se supone que en cada repeticin se procesa un estado diferente de cosas -sin lo cual el proceso tendera al infinito-, ambos mtodos presentan tambin alguna forma de control de fin de tarea. La idea bsica en un algoritmo iterativo es que la repeticin de la tarea se controla desde afuera. Se ejecuta un conjunto de acciones en forma completa, se verifica la condicin de salida y si es necesario se vuelve a ejecutar el conjunto de acciones en forma completa. El orden en que se ejecuta y evala determina que el algoritmo sea de evaluacin previa (primero se evala la condicin de salida y luego se ejecutan las acciones) o de evaluacin posterior (primero se ejecutan las acciones y luego se evala el resultado). En ambos casos, sin embargo, el control de las repeticiones es exterior al grupo principal de acciones. En un algoritmo recursivo, en cambio, la tarea se controla desde adentro. Se comienza a ejecutar un conjunto de acciones, pero antes de finalizar se evala si se ha llegado a la condicin de salida; si no es

as, se contina ordenando una nueva ejecucin del mismo conjunto de acciones. Finalmente se concluye con la tarea iniciada. Dicho en otros trminos, el procedimiento se llama repetidas veces a s mismo, y el control de esas llamadas forma parte del grupo principal de acciones. Por otra parte, si bien hay problemas que se resuelven ms directamente en forma iterativa y otros que son ms naturalmente recursivos, ambas tcnicas son compatibles e intercambiables, por lo que todo algoritmo recursivo puede transformarse en iterativo y viceversa. Algoritmos De Bsqueda Cuando se trata de buscar un valor en un arreglo ordenado de datos, el algoritmo de bsqueda binaria es el ms frecuentemente utilizado. La idea central de este algoritmo es comparar el elemento ubicado en el lugar central del arreglo con el valor buscado. Si el elemento central es igual al valor buscado la bsqueda finaliza con xito. Si no es as, puede ocurrir o bien que el elemento central sea mayor que el buscado -en cuyo caso el elemento coincidente debe estar en la mitad inferior del arreglo- o bien que sea menor -y el elemento coincidente se encuentra en la mitad superior. En ambos casos se prosigue la bsqueda en la mitad que corresponde, si es que quedan elementos en esa direccin, o bien se finaliza la bsqueda sin xito, en caso contrario. Existe naturalmente una solucin recursiva, ya que si el valor buscado no es hallado en la posicin del centro se repite el mismo procedimiento con una de las mitades del arreglo, y as hasta que se encuentre el valor o no queden ms "mitades". Comprese esto con el problema de las bolillas dentro de las cajas, en el cual la "bolilla blanca" sera el valor buscado y la "caja interior" sera la mitad que se debe seguir examinando. En ocasiones es necesario determinar no slo si el valor buscado se halla en el arreglo, sino adems saber en qu posicin est (o debera estar, si es que no existe). Por ejemplo, si se desea insertar un nuevo valor en un arreglo ordenado, una solucin eficaz es "buscar" el valor en el arreglo (aunque se sepa de antemano que no se encuentra) para determinar la posicin correcta en la que debe ser insertado. En esos casos se debe informar por algn medio (generalmente un puntero pasado como parmetro o una variable global) cul es la posicin lgica del elemento buscado dentro del arreglo. Ejemplo de un Algoritmo de Bsqueda A modo de ejemplo se presenta una versin de la funcin int busbin (int *vec, unsigned tam, int val, unsigned *ord); sta realiza una bsqueda binaria del elemento val en el vector de enteros apuntado por vec de tam elementos y deja en la memoria apuntada por ord la posicin lgica que tiene (o debera tener) el elemento buscado. Retorna 1 si el elemento es hallado o 0 en caso contrario. Para calcular el elemento mitad del vector se desplaza tam un bit a la derecha, lo que equivale a dividirlo en dos, pero resulta mucho ms rpido para el procesador que la operacin de divisin. int busbin (int *vec, unsigned tam, int val, unsigned *ord) {if (!(vec && tam && ord)) return 0; unsigned mitad = tam >> 1; // Divide tam en 2 desplazando un bit a la// derecha. Es ms rpido que tam / 2. if (vec [mitad] == valor) { *ord += mitad; return 1; } if (vec [mitad] < valor) { mitad++; *ord += mitad; vec += mitad; tam -= mitad; } else tam = mitad; return tam? busbin (vec, tam, va, ord): 0;} Algoritmos De Ordenacion Se presentan aqu dos mtodos muy utilizados para obtener el ordenamiento de un conjunto de datos: el algoritmo de ordenamiento por insercin y el algoritmo conocido como quick sort (ordenamiento rpido). Estos dos algoritmos son ilustrativos, adems, porque el algoritmo de ordenamiento por insercin es esencialmente iterativo, mientras que el algoritmo de quick sort es esencialmente recursivo. A continuacin se comentan las caractersticas de ambos algoritmos para ordenar en forma ascendente los valores dentro de un vector en memoria. Siguiendo este ejemplo, para obtener ordenamientos descendentes basta cambiar el sentido de las comparaciones por desigualdad, y para otro tipo de soporte de datos (archivos en disco, por ejemplo) los cambios se referirn principalmente al modo de leer y escribir los datos. Ordenacin por Insercin: La idea central de este algoritmo es recorrer secuencialmente y hacia delante el conjunto de datos comparando cada elemento con el anterior. Si el elemento actual es igual o mayor que el anterior

entonces ese par de datos se encuentra en la secuencia correcta, por lo que no hay que modificar nada. Si, en cambio, el actual es menor que el anterior, significa que el actual est fuera de secuencia, por lo que debe ser insertado en el lugar correcto entre los valores que han quedado atrs. Una vez resuelta esta cuestin, se repite el proceso con el elemento siguiente del conjunto hasta que no haya ms elementos. Dos caractersticas surgen directamente de esta descripcin: 1) Si hay que comparar cada valor con el anterior, entonces se debe comenzar el proceso por el segundo elemento, ya que es el primero en tener uno anterior. 2) Si se van reinsertando correctamente "hacia atrs" los valores a medida que se avanza (o si se avanza sin reinsertar porque no es necesario), entonces los elementos anteriores al actual ya estn ordenados. La tarea de reinsertar un elemento "hacia atrs" cuando se descubre que est fuera de secuencia es accesoria y puede ser realizada por una funcin auxiliar. Esta funcin auxiliar se puede implementar de varias maneras, pero todas ellas deben partir de la certeza de que ese subconjunto de elementos ya est ordenado. A continuacin se presentan una implementacin de la funcin principal int *ordins (int *vec, unsigned tam); y dos implementaciones alternativas de la funcin auxiliar void insertar (int *ult, unsigned tam); La funcin ordins () ordena por insercin el vector de enteros apuntado por vec de tamao tam y retorna vec, mientras que ambas versiones de insertar (), ubican el valor contenido en el elemento apuntado por ult entre los tam elementos ordenados que han quedado atrs. Ambas funciones auxiliares son estticas -esto es, de uso "privado" dentro del mdulo donde estn insertas- ya que la tarea que realizan es subsidiaria y dependiente de la funcin ordins (). int *ordenar (int *vec, unsigned tam) {int *ant = vec, *act = vec + 1;unsigned i;for (i = 1; i < tam; i++, ant++, act++) if (*act < *ant) insertar (act, i);return vec;} La primera versin de insertar () es tpicamente iterativa y efecta una especie de rotacin de los valores de los elementos. Primeramente resguarda en la variable local auxiliar aux el valor del tem a reinsertar -que se encuentra en *ult- y a continuacin procede a mover una posicin hacia delante cada uno de los elementos anteriores a aux retrocediendo en el vector hasta que no hay ms elementos o encuentra uno que no es mayor que aux. Finalmente reinserta el valor de aux en el lugar donde se encontraba el ltimo elemento removido. static void insertar (int *ult, unsigned tam) {int *ant = ult - 1; // ant apunta siempre al tem anterior a ult. int aux = *ult; // aux contiene el valor a reinsertar. do *(ult--) = *(ant--); // Evaluacin posterior porque ya se sabe que el while (--tam && aux < *ant); // primer tem anterior a ult es mayor que *ult. *ult = aux; // Restituye el valor de aux en la ltima} // posicin vacante. La segunda versin de insertar () recurre a su vez a la funcin auxiliar de bsqueda binaria busbin (), con el fin de determinar la posicin que debe ocupar el elemento *ult entre los anteriores a ult. Para ello inicializa las variables globales estticas valor y orden, que son utilizadas por busbin () para conocer el elemento buscado e informar su posicin. Obsrvese que para que esta versin de insertar () pueda acceder a otras funciones y variables globales estticas, debe estar incluida a su vez en el mismo mdulo de cdigo que ellas. Luego de obtener a travs de busbin () el lugar que debe ocupar el nuevo tem, calcula la cantidad de elementos a desplazar y -como la primera versin- mueve una posicin hacia delante cada uno de los elementos anteriores a ult retrocediendo en el vector hasta llegar a la posicin correcta. Ya no necesita comparar y contar puesto que, al conocer la cantidad de elementos a desplazar, slo necesita contar. Finalmente reinserta el valor de aux en el lugar donde estaba el ltimo elemento removido. static void insertar (int *ult, unsigned tam) {unsigned _ord = 0; // _ord contendr la posicin correcta de *ult. int *ant = ult - 1; // ant apunta al tem anterior a ult. valor = *ult; // Inicializa las variables globales estticas orden = &_ord; // que utilizar busbin (). if (--tam) // Si hay ms de un elemento llama a busbin () busbin (ant - tam, tam); // con la direccin inicial del vector. tam -= _ord; // Descuenta de tam la posicin del nuevo tem. do *(ult--) = *(ant--); // Desplaza la cantidad necesaria de elementos

while (tam--); *ult = valor;

// hacia delante y restituye el valor de valor // en la ltima posicin vacante.}

La ventaja de la primera versin es que es autnoma, ya que no depende de otras funciones ni variables globales estticas, por lo que puede ser incluida en cualquier mdulo de cdigo. Presenta sin embargo el inconveniente de que tiene que comparar una y otra vez cada elemento del arreglo para encontrar su posicin correcta. En vectores de gran tamao esto puede resentir en forma notable la eficiencia. La segunda versin, en cambio, soluciona el problema de las comparaciones sucesivas utilizando un algoritmo de bsqueda ms eficiente, aunque esto la obliga a convivir en el mismo mdulo con otras funciones y variables globales estticas de las cuales depende. Algoritmo de Quick Sort: La idea central de este algoritmo es la siguiente: si se toma un conjunto de elementos desordenados y se ubica uno cualquiera de ellos -llamado pivote- en una posicin tal que todos los que estn antes sean menores o iguales y todos los que estn despus sean mayores, entonces esa posicin particular sera la correcta para ese elemento si el conjunto estuviera ordenado. Asimismo se verifica que el conjunto ha quedado dividido en dos partes: en la primera estn todos los elementos menores o iguales al pivote y en la segunda todos los mayores. Esto permite aplicar recursivamente el mismo procedimiento en ambas partes del conjunto hasta que ste quede completamente ordenado. La tarea de dividir el conjunto de datos en dos grupos en torno al pivote es accesoria y puede ser realizada por una funcin auxiliar. Esta funcin auxiliar se puede implementar de varias maneras, pero todas ellas deben informar de algn modo en qu posicin ha quedado ubicado el pivote. Al igual que busbin (), la funcin qsort () es recursiva, y cada llamada provocar que la funcin se llame "internamente" a s misma varias veces. Los valores de los parmetros vec y tam seguramente variarn entre una llamada y otra, ya que son los que definen la parte del arreglo que se ordenar cada vez. Sin embargo, tanto los controles de que los parmetros sean legales como el retorno de la funcin con la direccin original del vector deben hacerse slo una vez. Para evitar tener que hacer estos controles redundantes en cada llamada recursiva, la tarea se divide entre dos funciones. La primera est declarada pblicamente como int *qsort (int *vec, unsigned tam); No es recursiva y slo realiza las tareas que deben ser ejecutadas una sola vez: verifica que vec y tam sean legales y llama a la segunda funcin, que es la que completa la tarea. Si vec o tam son ilegales la funcin retorna vec sin hacer nada ms. La segunda funcin, definida como void _qsort (int *vec, unsigned tam); Es esttica (por lo tanto inaccesible desde fuera del mdulo), y es la que realmente lleva a cabo la tarea recursiva de ordenamiento. Recibe los parmetros vec y tam, que varan entre una llamada y otra, pero que tienen siempre valores legales. A continuacin se presentan dos pequeos mdulos de librera con una versin optimizada de la funcin: el mdulo qsort.h contiene simplemente la declaracin, mientras que el mdulo qsort.cpp incluye la implementacin de la funcin principal int *qsort (int *vec, unsigned tam); y una implementacin de las dos funciones auxiliares int dividir (int *vec, unsigned tam); void _qsort (int *vec, unsigned tam); La funcin qsort () verifica la validez de los parmetros vec y tam y llama a _qsort () antes de retornar vec. La funcin _qsort () ordena por el algoritmo de quick sort el vector de enteros apuntado por vec de tamao tam, llamando a su vez a la funcin dividir (). sta divide los tam elementos del vector apuntado por vec en dos grupos alrededor de un pivote y retorna la cantidad de elementos del primer grupo -que incluye al pivote. Ambas funciones auxiliares son estticas -esto es, de uso "privado" dentro del mdulo donde estn insertas- ya que la tarea que realizan es subsidiaria y dependiente de la funcin qsort (). 7. Verificacin y derivacin de programas Conceptos Basicos La definicin del significado de un elemento del lenguaje se puede realizar de distintas formas, cada una de las cuales define una semntica diferente del lenguaje. En esta leccin se van a introducir los conceptos ms importantes de algunas de estas formas semnticas, y se van a tratar ms extensamente los conceptos de correccin, verificacin y prueba, ya mencionados en la leccin.

Semntica: Ahondando en la situacin de la introduccin anterior sobre la definicin del lenguaje pascal, se puede conjeturar que la manera informar de definir el significado de las construcciones del lenguaje es insatisfactoria. El motivo es la falta de precisin con la que se define el significado de dichos conceptos, lo cual deja abierta como posibilidad que dicho significado dependa de la maquina donde se utilice el lenguaje. Otro problema importante es la ambigedad del lenguaje natural, que permite que distintos implementadotes o programadores entiendan de modo distintos una definicin. Acerca de este tema, el lenguaje pascal vuelve a servirnos de ejemplos. Hasta hace no mucho tiempo exista una gran variedad de versiones del mismo, cada una realizada especficamente. Dependiendo del objetivo prioritario que se presenta cubrir al dar el significado de un lenguaje podemos encontrar diversas aproximaciones. Entre todas ellas, las ms frecuentemente utilizadas son la sematica operacional, la sematica declarativa y la sematica axiomatica. Veamos a continuacin una peque son la sematica operacional, la sematica declarativa y la sematica axiomatica. Veamos a continuacin una pequea introduccin a cada una de estas aproximaciones. Semntica operacional: La semntica operacional define el significado de un lenguaje de programacin en trminos de los cambios de estado que producen las instrucciones primitivas del lenguaje. Estos cambios no se reflejan directamente en la maquina real, sino en una maquina (virtual) abstracta asociada que sirve como instrumento de conexin con aquella. Expresado de otra forma, podemos decir que la semntica operacional define el significado de un programa en trminos del efecto producido por la ejecucin paso a paso del mismo, de tal modo que la especificacin de las instrucciones del lenguaje mediante instrucciones primitivas de la maquina abstracta es, precisamente, la definicin semntica del mismo. A pesar de la aparente simplicidad de este formalismo, este tipo de semntica no describe con igual claridad todo tipo de lenguaje de programacin. El motivo es que el mecanismo que emplean los distintos lenguajes de programacin para realizar un cmputo no siempre puede expresarse de una manera clara, comprensible y concisa. Semntica denotacional: La semntica denotacional define unas aplicaciones (funciones) de valoracin semntica que asignan a cada construccin denotada tal objeto matemtico que modela su significado. Se dice que la construccin denota tal objeto o que este objeto es la denotacin de dicha construccin. En otras palabras, la semntica denotacional indica que funcin matemtica se obtiene a la salida ante unas entradas del programa, sin preocuparse de la ejecucin paso a paso del programa. Existe una variante de esta semntica que es la semntica algebraica, en la que se utiliza conceptos algebraicos a la hora de modelar el significado de las construcciones. El primer paso a realizar en la definicin de la semntica denotacional de un determinado lenguaje es el establecimiento de un dominio semantico al que pertenecern los resultados obtenidos de la evaluacin de las construcciones del lenguaje. Esta evaluacin es proporcionada por un conjunto de funciones de significado cuyo dominio esta constituido por el conjunto de construcciones del lenguaje y cuyo rango (o imajen) viene dado por el dominio semantico. Este tipo de semntica dotan de significado a los elementos del lenguaje de una manera mas formal y abstracta, pero sin embargo tambin necesitan un mayor conocimiento de conceptos matemticos, que no tienen por que ser bsicos ni elementales. Recursividad: Una funcin recursiva es una funcin que se define en trminos de si misma., es decir, en su cuerpo aparece alguna aplicacin suya. La recursividad es un mecanismo que se usa cuando hay que repetir cierto tratamiento o clculo pero el nmero de repeticiones es variable. De hecho ya se han visto definiciones recursivas, el tipo suma permite definir tipos de datos recursivos, como el tipo de lista. La definicin del tipo lista permite repetir la adicin de elementos a una lista. el numero de adicciones es variable y determina el numero final de elementos de lista. Iteracin: Una instruccin iterativa engloba una secuencia de instrucciones que se escribe una sola vez, pero permite que se ejecute varias veces. Una instruccin iterativa tambin se llama Bucle. Las instrucciones englobadas suelen denominarse cuerpo del bucle; cada ejecucin del cuerpo de un bucle se llama iteracin del mismo. Hay varios formatos de bucles que vemos a continuacin. Una instruccin LOOP tiene el siguiente formato:

LOOP <Instruccin> Su efecto es ejecutar eternamente la instruccin englobada. Sin embargo, puede terminarse la ejecucin del bucle si se ejecuta una instruccin especial, formada por la palabra clave EXIT. Obsrvese que la instruccin EXIT debe ir incluida dentro de una instruccin condicional; en caso contrario, el bucle LOOP terminara su ejecucin al llegar a ella, realizando una iteracin como mucho. Pero esto no tiene mucho sentido, porque si se hubiera querido realizar una sola ejecucin de dichas instrucciones, no se hubieran incluido en una instruccin iterativa. La instruccin EXIT no puede usarse en ninguna de las dos clases de bucles que se exponen a continuacin. Una instruccin WHILE tiene el siguiente formato: WHILE <condicin>DO <Instruccin> La ejecucin de una instruccin WHILE comienza evaluando la condicin booleana. Si es cierta, se ejecuta la secuencia de instrucciones y se comienza de nuevo. Si la condicin es falsa, la ejecucin del WHILE termina y el algoritmo contina por la instruccin siguiente al bucle. La instruccin FOR tiene el siguiente formato: FOR <variable> IN <subrango>BY<expresin entera>DO <Instruccin> La instruccin FOR usa una variable, llamada variable de ndice, que toma distintos valores en las sucesivas ejecuciones del cuerpo. La variable de ndice debe ser entera, enumerada o subrango. Los valores que toma la variable de ndice se indica mediante un subrango del mismo tipo y un incremento. El subrango se expresa de la manera usual: un valor inicial y un valor final separados por dos puntos. El incremento viene dado por una expresin entera; puede suprimirse, en cuyo caso se supone que es igual a uno. Al comenzar la ejecucin del bucle, la variable ndice toma el valor inicial del subrango y se evala la expresin entera para determinar el incremento. Veamos el resto del comportamiento del bucle cuando el tipo de la variable ndice es un subrango entero. Tras cada iteracin, el valor del ndice se actualiza, sumndose a su valor el incremento. Si el incremento es positivo, solo se realiza la siguiente iteracin si el valor de la variable ndice es menor o igual que el valor final del subrango; por el contrario, si el incremento es negativo, solo se itera de nuevo cuando su valor es mayor o igual que el valor del final del subrango. Si la variable es enumerada o de un subrango enumerado, el comportamiento del bucle es parecido. Un valor es menor que otro si tiene un ordinal menor. El incremento de un valor enumerado produce otro valor cuyo ordinal es mayor que el inicial en la cantidad expresada por el incremento. Semantica Axiomatica La semntica axiomatica asociada a cada construccin del lenguaje un axioma lgico que relaciona el estado del computo (valores que tienen las variables utilizadas) antes y despus de ejecutar esta construccin. Existen distintas semnticas, axiomatica, de la que la mas conocida es la introducida por el sistema formal de hoare y que es utilizada para definir el significado de lenguaje imperativos (por ejemplo, pascal). El mtodo axiomatico expresa la semntica de un lenguaje de programacin asociado al lenguaje una teora matemtica o sistema formal que permita demostrar propiedades de los programas escritos en ese lenguaje. Esta aproximacin formal contrasta con el mtodo denotacional mostrando anteriormente, que asocia a cada construccin del lenguaje una denotacin (significado) en un intento de encontrar un modelo matemtico (coleccin abstracta de objetos matemticos) del lenguaje. Un sistema formal puede entenderse como un metalenguaje que pose su propia sintaxis y semntica. Desde el punto de vista sintctico, es necesario definir una gramtica en la que se reflejen las contrucciones validas del sistema formal, normalmente se suele emplear la sintaxis sde la lgica de predicado de primer orden ampliada com. expresiones aritmticas y de teora de conjuntos. Una vez fijada la sintaxis a emplear, un sistema formal se define mediante un conjunto de axiomas (propiedades ciertas escritas en forma de sentencias logicas) que expresen las propiedades de las construcciones bsicas y un conjuntos de reglas de inferencias (forma de deducir una propiedades de otras) que permitan deducir las propiedades de construcciones mas complejas. Las definiciones de sistemas formales para lenguajes funcionales suele hacerse fundamentalmente para demostrar propiedades que tiene que ver con el tipo de una expresin y de las subexpresiones que la componen.

Diseo De Algoritmos Recursivos Las definiciones recursivas pueden resultar sorprendentes a primera vista.Incluso puede dar lugar a funciones que nunca terminen (intiles como algoritmos), Sin embargo, usadas juiciosamente son un instrumento potentisimo de diseo de algoritmos. En primer lugar, hay que identificar el proceso repetitivo por realizar. En segundo lugar, hay que considerar que una funcin recursiva solo es til si su evaluacin termina. Clasificacin Segn el nmero de llamadas recursivas realizadas, se distinguen tres clases: Recursividad lineal: El cuerpo de la funcin contiene una llamada recursiva. Son las funciones recursivas. Son las funciones recursivas ms sencillas. Todas las funciones especificadas en este capitulo son recursivas lineales. Un caso importante de recursividad lineal aparece cuando la expresin ms externa del caso recursivo de la funcin es la misma llamada recursiva. Esta clase de recursividad se llama recursividad de cola. Recursividad no lineal. El cuerpo de la funcin contiene varias llamadas recursivas. Lo mas frecuente que contenga dos llamadas recursivas, en cuyo caso se habla de recursividad binaria. Recursividad mutua: Es un caso curioso de recurcion, una funcin no contienen ninguna llamada recursiva, pero durante la evaluacin de su aplicacin surgen llamadas recursivas. Auque a primera vista parezca imposible obtenrsete comportamiento, la recursividad puede conseguirse indirectamente si hay dos funciones que se llaman entre si. Otra clasificacin basada en el formato de los parmetros de las llamadas recursivas. Recursividad estructural: Las sucesivas llamadas recursivas sobre un dato se hacen siguiendo la estructura recursiva del mismo. En el caso de los elementos enteros, una recurcion estructurar significa que el valor se vaya decrementando en uno. Recurcion bien fundada: Aunque hablando con propiedad, cualquier recursividad esta bien fundada, suele utilizarse este trmino para aquellas recursividades que no son estructurales. Un ejemplo de funcin recursiva bien es invertir Entero, donde el parmetro entero se divide entre diez. La primera clasificacin dada es til para decidir si es conveniente usar una definicin recursiva o iterativa en los algoritmos imperactivo. La segunda clasificacin es til para decidir el principio de induccin necesaria para necesaria para verificar el algoritmo. Diseo De Algoritmos Iterativos Cada clase de bucle resulta til en situaciones diferentes. El bucle FOR se utiliza cuando se conoce el nmero de iteraciones que se quiere realizar. El bucle WHILE es usado en las otras situaciones en que no se conoce el nmero de iteraciones. El bucle LOOP es til cuando puede haber varias condiciones de salida del bucle, situadas en diferentes partes del cuerpo, o cuando la condicin de salida no esta al comienzo del bucle. Sin embargo, conocer la instruccin iterativa que mas conviene para un algoritmo es solo el comienzo de la construccin de la instruccin. Es conveniente tener algunas guas para el diseo de algoritmos iterativos. El diseo de un algoritmo iterativo se hace sobre una base distinta de la de uno recursivo. En los algoritmos imperativos se tiene disponible toda la informacin del problema en las variables. Por esta razn, es til partir los datos del problema en dos: La parte que representa el problema aun no resuelto. La parte que representa el problema ya resuelto; es decir, el resultado ya calculado. Una vez que se han distinguido estas dos partes, el bucle se construye a partir de tres decisiones hechas sobre dicha particin: a) Fijar la situacin inicial. El problema a resolver se encuentra en los parmetros de entrada o de entrada/salida; si estos datos quieren modificarse durante el algoritmo, deben copiarse en variables auxiliares. tambin hay que dar un valor inicial a las variables que representan la solucin vaca. b) Formar el cuerpo del bucle. Para ello puede usarse un razonamiento parecido al recursivo. Se supone, por generalidad, que la iteracin se encuentra en un estado intermedio. Debe entonces determinarse que hacer en una iteracin para avanzar en la resolucin del problema. c) Determinar la condicin de terminacin. Corresponde a la situacin en que se ha hallado la solucin completa. Esta parte esta totalmente relacionada con la eleccin de la instruccin iterativa. Segn la forma de la iteracin, se elige un bucle FOR, WHILE o LOOP, como se

describi antes. Normalmente, la terminacin del bucle puede especificarse de forma sencilla, incluso en casos relativamente complicados. Por ejemplo, cuando se tiene un bucle WHILE con una condicin compuesta es posible que pueda usarse la tcnica del centinela para obtener una especificacin ms sencilla. Algo con lo que hay que tener especial cuidado es la terminacin de los bucles. Esta es fcil de determinar en un algoritmo recursivo porque basta con tomar una medida de los parmetros y comprobar que disminuye en cada llamada recursiva, de forma que se acerca al tamao de los casos bsicos. En una solucin iterativa se razona igual, pero la tarea es algo mas complicada porque el control del proceso repetitivo no tiene parmetros, sino que se hace a partir de la informacin contenida en las variables. 8. Anlisis Foda Introduccin: El anlisis FODA es una herramienta que permite conformar un cuadro de la situacin actual de la empresa u organizacin, permitiendo de esta manera obtener un diagnstico preciso que permita en funcin de ello tomar decisiones acordes con los objetivos y polticas formulados. El trmino FODA es una sigla conformada por las primeras letras de las palabras Fortalezas, Oportunidades, Debilidades y Amenazas (en ingls SWOT: Strenghts, Weaknesses, Oportunities, Threats). De entre estas cuatro variables, tanto fortalezas como debilidades son internas de la organizacin, por lo que es posible actuar directamente sobre ellas. En cambio las oportunidades y las amenazas son externas, por lo que en general resulta muy difcil poder modificarlas. Fortalezas: son las capacidades especiales con que cuenta la empresa, y por los que cuenta con una posicin privilegiada frente a la competencia. Recursos que se controlan, capacidades y habilidades que se poseen, actividades que se desarrollan positivamente, etc. Oportunidades: son aquellos factores que resultan positivos, favorables, explotables, que se deben descubrir en el entorno en el que acta la empresa, y que permiten obtener ventajas competitivas. Debilidades: son aquellos factores que provocan una posicin desfavorable frente a la competencia. recursos de los que se carece, habilidades que no se poseen, actividades que no se desarrollan positivamente, etc. Amenazas: son aquellas situaciones que provienen del entorno y que pueden llegar a atentar incluso contra la permanencia de la organizacin. Anlisis: El Anlisis FODA es un concepto muy simple y claro, pero detrs de su simpleza residen conceptos fundamentales de la Administracin. Intentar desguazar el FODA para exponer sus partes fundamentales. Tenemos un objetivo: convertir los datos del universo (segn lo percibimos) en informacin, procesada y lista para la toma de decisiones (estratgicas en este caso). En trminos de sistemas, tenemos un conjunto inicial de datos (universo a analizar), un proceso (anlisis FODA) y un producto, que es la informacin para la toma de decisiones (el informe FODA que resulta del anlisis FODA). Sostengo que casi cualquier persona puede hacer un anlisis FODA. Digo casi porque esa persona tiene que tener la capacidad de distinguir en un sistema: 1. Lo relevante de lo irrelevante 2. Lo externo de lo interno 3. Lo bueno de lo malo Parece fcil, verdad? Pongmoslo en otras palabras: el FODA nos va a ayudar a analizar nuestra empresa siempre y cuando podamos responder tres preguntas: Lo que estoy analizando, es relevante? Est fuera o dentro de la empresa? Es bueno o malo para mi empresa? Estas tres preguntas no son otra cosa que los tres subprocesos que se ven en el proceso central del dibujo de arriba. Pasemos a explicar: La relevancia es el primer proceso y funciona como filtro: no todo merece ser elevado a componente del anlisis estratgico. Es sentido comn ya que en todos los rdenes de la vida es fundamental distinguir lo relevante de lo irrelevante. En FODA este filtro reduce nuestro universo de anlisis disminuyendo nuestra necesidad de procesamiento (que no es poca cosa). Ejemplos: dudosamente sea una ventaja comparativa el sistema de limpieza de baos de una

petroqumica, o el color de los monitores, o si el papel que se usa es carta o A4. Parece tonto, pero es increble la cantidad de veces que a los seres humanos nos cuesta distinguir lo principal de lo accesorio, ya sea en una discusin, una decisin o donde sea. Claro que la relevancia de algo depende de dnde estemos parados, y este concepto de relatividad es importante. La higiene de los baos puede ser clave en un Hospital o un Hotel. El orden en el que se hacen los pasos al efectuar una compraventa no es tan importante como los pasos que toman los bomberos para apagar un incendio. La disciplina y la autoridad formal son dejadas de lado en muchas empresas de la Nueva Economa... pero a un ejrcito en batalla eso puede costarle la vida. Es por eso que quien hace un anlisis FODA debe conocer el negocio (ni ms ni menos que saber de lo que est hablando). Filtrados los datos slo nos queda clasificarlos. Aplicando el sentido comn, podemos construir una matriz con dos dimensiones (dentro/fuera, bueno/malo): Exterior Interior Positivas Oportunidades Fortalezas Negativas Amenazas Debilidades

Quien haya inventado el Anlisis FODA eligi para cada interseccin una palabra: as la interseccin de bueno y exterior es una oportunidad, mientras que las cuestiones positivas del interior de nuestra empresa son una fortaleza, y as sucesivamente. Distinguir entre el adentro y el afuera de la empresa a veces no es tan fcil como parece. Es fcil decir que desde el punto de vista de la Ferrari, M. Schumager es una fortaleza (interna), y que si M. Hakkinen se queda sin empleo en su escudera, ser una Oportunidad (externa) para la Ferrari. Pero el control de un recurso escaso (petrleo) o un proveedor exclusivo estn fsicamente fuera de mi empresa... y sin embargo son Fortalezas. La clave est en adoptar una visin de sistemas y saber distinguir los lmites del mismo. Para esto hay que tener en cuenta, no la disposicin fsica de los factores, sino el control que yo tenga sobre ellos. Recordando una vieja definicin de lmite: lo que me afecta y controlo, es interno al sistema. Lo que me afecta pero est fuera de mi control, es ambiente (externo). Slo nos queda la dimensin positivo/negativo, que aparentemente no debera ofrecer dificultad, pero hay que tener cuidado. El competitivo ambiente de los negocios est lleno de maniobras, engaos, etc. En la Segunda Guerra Mundial, el Eje estaba feliz de que el desembarco de los Aliados fuera en Calais, porque tena muchas fortalezas en ese caso. Pero el da D fue en Normanda y por eso hoy el mundo es lo que es. Las circunstancias pueden cambiar de un da para el otro tambin en el interior de la empresa: la Fortaleza de tener a ese joven y sagaz empleado puede convertirse en grave Debilidad si se marcha (y peor si se va con la competencia). Y la Debilidad de tener a un empleado prximo a jubilarse y a quien le cuesta adaptarse a las nuevas tecnologas puede revelarse como Fortaleza demasiado tarde... cuando se retira y nos damos cuenta de que dependamos de l porque era el nico que saba dnde estaba todo y cmo se hacen las cosas. La sagacidad del empresario debe convertir las Amenazas en Oportunidades y las Debilidades en Fortalezas. Ejemplos: Asociarnos con nuestra competencia de toda la vida para enfrentar a un enemigo ms pesado; pasar a un empleado desestructurado y extrovertido de una tarea organizativa que hace mal, a la lnea de fuego de atencin al pblico. Las posibilidades son muchas. Y esos son los tres pasos necesarios para analizar la situacin actual de la organizacin mediante el Anlisis FODA. El Anlisis FODA de este trabajo: Fortaleza: Los conceptos que se nos encomendaron investigar, estn desarrollados de forma amplia y lgica. Tiene un contenido y una presentacin al nivel de los que significa ser estudiante universitario de un 7mo cuatrimestre de Ing. En Sistemas. Continuidad y constancia de la estructura, calidad y cantidad de contenido que los dems trabajos entregados, a dems de mejoras considerables, lo cual nos garantiza obtener calificaciones similares o superiores a las ya obtenidazas de referidos trabajos. Oportunidades: Debido a las mejoras realizadas al mismo y una mejor coordinacin y participacin de los integrantes del grupo este se concluir en menor tiempo y as podremos completar el procedimiento correcto de entrega de trabajos de esta materia.

Debilidades: A causa de la dificultad para conseguir la informacin solicitada algunos de los conceptos relacionados con los problemas, tipos, etc. No se encuentran en nuestro trabajo. Amenazas: Que las debilites de nuestro trabajo influyan considerablemente en la evaluacin del mismo provocando que las expectativas y el esfuerzo realizados por los que participamos en el mismo no lleguen a cumplirse. 9. Conclusin Luego de realizar este trabajo hemos visto como los algoritmos son una de las herramientas ms complejas y aplicables en el rea de la informtica y el mundo de los computadores. Pudimos comprobar que mientras ms potente, completo y eficiente es el computador o la aplicacin que corre sobre el mismo mas grande, complejo y exacto es el algoritmo que utiliza. Las tcnicas de desarrollo de algoritmos nos permiten encontrar la mejor solucion a los problemas que se nos presentan y deben ser solucionados por el computador, estas tcnicas estn orientadas para utilizarse en cada uno de los niveles de complejidad y variedad o alternativas para las cuales se aplican los algoritmos. Un algoritmo es el conjunto de operaciones y procedimientos que deben seguirse para resolver un problema, es por ellos que debemos estudiarlos y conocerlos. 10. Bibliografa Correa Uribe, Guillermo. Desarrollo de Algoritmos y sus aplicaciones, Editora MacGraw - Hill Inc. USA, III Edicin. Abril/1992, Colombia. pp. 251. Glvez, Javier. Gonzles, Juan. Algortmica, Anlisis y Diseo de Algoritmos, Editora RA-MA (AddisonWesley Iberiamericana), II Edicin. Septiembre/1993, USA. pp 502. Matas, Cristian Manual de Informtica Educativa, Editora Taller. 2da. Edicin. Julio/1999. Sto. Dgo. R.D. pp 260. Sean, James A. Anlisis y Diseo de Sistemas de Informacin, Editora MacGraw - Hill Inc. USA, 2 ta. Edicin. Diciembre/1998, Mxico. pp 941. World Wide Wed: www.altavista.com www.elrincondelvago.com www.aulaclick.com

Trabajo enviado por: Ing. Domingo de los Santos. mingolito@hotmail.com Ingeniero en Sistemas.

You might also like