Documentos de Académico
Documentos de Profesional
Documentos de Cultura
PDF generado usando el kit de herramientas de fuente abierta mwlib. Ver http://code.pediapress.com/ para mayor informacin. PDF generated at: Mon, 06 Jan 2014 22:21:32 UTC
Contenidos
Artculos
Introduccin
Algoritmo Heurstica Teora de la complejidad computacional 1 1 8 11 18 18 20 21 22 22 25 27 31 31 32 42 50 50 52 59 74 74 87
Crecimiento de finciones
Cota superior asinttica Cota inferior asinttica Cota ajustada asinttica
Ordenamiento
Algoritmo de ordenamiento Heapsort Quicksort
Estructuras de datos
Estructura de datos Pila (informtica) Cola (informtica)
rboles de bsqueda
rbol (informtica) rbol binario rbol binario de bsqueda
Referencias
Fuentes y contribuyentes del artculo Fuentes de imagen, Licencias y contribuyentes 98 99
Licencias de artculos
Licencia
100
Introduccin
Algoritmo
En matemticas, lgica, ciencias de la computacin y disciplinas relacionadas, un algoritmo (del griego y latn, dixit algorithmus y este a su vez del matemtico persa Al-Juarismi) es un conjunto prescrito de instrucciones o reglas bien definidas, ordenadas y finitas que permite realizar una actividad mediante pasos sucesivos que no generen dudas a quien deba realizar dicha actividad.[1] Dados un estado inicial y una entrada, siguiendo los pasos sucesivos se llega a un estado final y se obtiene una solucin. Los algoritmos son el objeto de estudio de la algoritmia. En la vida cotidiana, se emplean algoritmos frecuentemente para resolver problemas. Algunos ejemplos son los manuales de usuario, que muestran algoritmos para usar un aparato, o las instrucciones que recibe un trabajador por parte de su patrn. Algunos ejemplos en matemtica son el algoritmo de multiplicacin, para calcular el producto, el algoritmo de la divisin para calcular el cociente de dos nmeros, el algoritmo de Euclides para obtener el mximo comn divisor de dos enteros positivos, o el mtodo de Gauss para resolver un sistema lineal de ecuaciones.
Definicin formal
En general, no existe ningn consenso definitivo en cuanto a la definicin formal de algoritmo. Muchos autores los sealan como listas de instrucciones para resolver un clculo o un problema abstracto, es decir, que un nmero finito de pasos convierten los datos de un problema (entrada) en una solucin (salida). Sin embargo cabe notar que algunos algoritmos no necesariamente tienen que terminar o resolver un problema en particular. Por ejemplo, una versin modificada de la criba de Eratstenes que nunca termine de calcular nmeros primos no deja de ser un algoritmo. A lo largo de la historia varios autores han tratado de definir formalmente a los algoritmos utilizando modelos matemticos. Esto fue realizado por Alonzo Church en 1936 con el concepto de "calculabilidad efectiva" basada en su clculo lambda y por Alan Turing basndose en la mquina de Turing. Los dos enfoques son equivalentes, en el sentido en que se pueden resolver exactamente los mismos problemas con ambos enfoques. . Sin embargo, estos modelos estn sujetos a un tipo particular de datos como son nmeros, smbolos o grficas mientras que, en general, los algoritmos funcionan sobre una vasta cantidad de estructuras de datos. En general, la parte comn en todas las definiciones se puede resumir en las siguientes tres propiedades siempre y cuando no consideremos algoritmos paralelos: Tiempo secuencial. Un algoritmo funciona en tiempo discretizado paso a paso, definiendo as una secuencia de estados "computacionales" por cada entrada vlida (la entrada son los datos que se le suministran al algoritmo antes de comenzar). Estado abstracto. Cada estado computacional puede ser descrito formalmente utilizando una estructura de primer orden y cada algoritmo es independiente de su implementacin (los algoritmos son objetos abstractos)
Algoritmo de manera que en un algoritmo las estructuras de primer orden son invariantes bajo isomorfismo. Exploracin acotada. La transicin de un estado al siguiente queda completamente determinada por una descripcin fija y finita; es decir, entre cada estado y el siguiente solamente se puede tomar en cuenta una cantidad fija y limitada de trminos del estado actual. En resumen, un algoritmo es cualquier cosa que funcione paso a paso, donde cada paso se pueda describir sin ambigedad y sin hacer referencia a una computadora en particular, y adems tiene un lmite fijo en cuanto a la cantidad de datos que se pueden leer/escribir en un solo paso. Esta amplia definicin abarca tanto a algoritmos prcticos como aquellos que solo funcionan en teora, por ejemplo el mtodo de Newton y la eliminacin de Gauss-Jordan funcionan, al menos en principio, con nmeros de precisin infinita; sin embargo no es posible programar la precisin infinita en una computadora, y no por ello dejan de ser algoritmos. En particular es posible considerar una cuarta propiedad que puede ser usada para validar la tesis de Church-Turing de que toda funcin calculable se puede programar en una mquina de Turing (o equivalentemente, en un lenguaje de programacin suficientemente general): Aritmetizabilidad. Solamente operaciones innegablemente calculables estn disponibles en el paso inicial.
Algoritmo
Diagrama de flujo
Los diagramas de flujo son descripciones grficas de algoritmos; usan smbolos conectados con flechas para indicar la secuencia de instrucciones y estn regidos por ISO. Los diagramas de flujo son usados para representar algoritmos pequeos, ya que abarcan mucho espacio y su construccin es laboriosa. Por su facilidad de lectura son usados como introduccin a los algoritmos, descripcin de un lenguaje y descripcin de procesos a personas ajenas a la computacin. Los algoritmos pueden ser expresados de muchas maneras, incluyendo al lenguaje natural, pseudocdigo, diagramas de flujo y lenguajes de programacin entre otros. Las descripciones en lenguaje natural tienden a ser ambiguas y extensas. El usar pseudocdigo y diagramas de flujo evita muchas ambigedades del lenguaje natural. Dichas expresiones son formas ms estructuradas para representar algoritmos; no obstante, se mantienen independientes de un lenguaje de programacin especfico.
Diagrama de flujo que expresa un algoritmo para calcular la raz cuadrada de un nmero
Pseudocdigo
El pseudocdigo (falso lenguaje, el prefijo pseudo significa falso) es una descripcin de alto nivel de un algoritmo que emplea una mezcla de lenguaje natural con algunas convenciones sintcticas propias de lenguajes de programacin, como asignaciones, ciclos y condicionales, aunque no est regido por ningn estndar. Es utilizado para describir algoritmos en libros y publicaciones cientficas, y como producto intermedio durante el desarrollo de un algoritmo, como los diagramas de flujo, aunque presentan una ventaja importante sobre estos, y es que los algoritmos descritos en pseudocdigo requieren menos espacio para representar instrucciones complejas. El pseudocdigo est pensado para facilitar a las personas el entendimiento de un algoritmo, y por lo tanto puede omitir detalles irrelevantes que son necesarios en una implementacin. Programadores diferentes suelen utilizar convenciones distintas, que pueden estar basadas en la sintaxis de lenguajes de programacin concretos. Sin embargo, el pseudocdigo, en general, es comprensible sin necesidad de conocer o utilizar un entorno de programacin especfico, y es a la vez suficientemente estructurado para que su implementacin se pueda hacer directamente a partir de l. As el pseudodocdigo cumple con las funciones antes mencionadas para representar algo abstracto los protocolos son los lenguajes para la programacin. Busque fuentes ms precisas para tener mayor comprensin del tema.
Sistemas formales
La teora de autmatas y la teora de funciones recursivas proveen modelos matemticos que formalizan el concepto de algoritmo. Los modelos ms comunes son la mquina de Turing, mquina de registro y funciones -recursivas. Estos modelos son tan precisos como un lenguaje mquina, careciendo de expresiones coloquiales o ambigedad, sin embargo se mantienen independientes de cualquier computadora y de cualquier implementacin.
Implementacin
Muchos algoritmos son ideados para implementarse en un programa. Sin embargo, los algoritmos pueden ser implementados en otros medios, como una red neuronal, un circuito elctrico o un aparato mecnico y elctrico. Algunos algoritmos inclusive se disean especialmente para implementarse usando lpiz y papel. El algoritmo de multiplicacin tradicional, el algoritmo de Euclides, la criba de Eratstenes y muchas formas de resolver la raz
Variables
Son elementos que toman valores especficos de un tipo de datos concreto. La declaracin de una variable puede realizarse comenzando con var. Principalmente, existen dos maneras de otorgar valores iniciales a variables: 1. Mediante una sentencia de asignacin. 2. Mediante un procedimiento de entrada de datos (por ejemplo: 'read'). Ejemplo: ... i:=1; read(n); while i < n do begin (* cuerpo del bucle *) i := i + 1 end; ...
Estructuras secuenciales
La estructura secuencial es aquella en la que una accin sigue a otra en secuencia. Las operaciones se suceden de tal modo que la salida de una es la entrada de la siguiente y as sucesivamente hasta el fin del proceso. La asignacin de esto consiste, en el paso de valores o resultados a una zona de la memoria. Dicha zona ser reconocida con el nombre de la variable que recibe el valor. La asignacin se puede clasificar de la siguiente forma: 1. 2. 3. 4. Simples: Consiste en pasar un valor constante a una variable (a 15) Contador: Consiste en usarla como un verificador del nmero de veces que se realiza un proceso (a a + 1) Acumulador: Consiste en usarla como un sumador en un proceso (a a + b) De trabajo: Donde puede recibir el resultado de una operacin matemtica que involucre muchas variables (a c + b*2/4).
Un ejemplo de estructura secuencial, como obtener la rea de un tringulo: Inicio ... float b, h, a; printf("Diga la base"); scanf("%f", &b); printf("Diga la altura"); scanf("%f", &h); a = (b*h)/2; printf("El rea del tringulo es %f", a) ... Fin
Algoritmo
Anlisis de algoritmos
Como medida de la eficiencia de un algoritmo, se suelen estudiar los recursos (memoria y tiempo) que consume el algoritmo. El anlisis de algoritmos se ha desarrollado para obtener valores que de alguna forma indiquen (o especifiquen) la evolucin del gasto de tiempo y memoria en funcin del tamao de los valores de entrada. El anlisis y estudio de los algoritmos es una disciplina de las ciencias de la computacin y, en la mayora de los casos, su estudio es completamente abstracto sin usar ningn tipo de lenguaje de programacin ni cualquier otra implementacin; por eso, en ese sentido, comparte las caractersticas de las disciplinas matemticas. As, el anlisis de los algoritmos se centra en los principios bsicos del algoritmo, no en los de la implementacin particular. Una forma de plasmar (o algunas veces "codificar") un algoritmo es escribirlo en pseudocdigo o utilizar un lenguaje muy simple tal como Lexico, cuyos cdigos pueden estar en el idioma del programador. Algunos escritores restringen la definicin de algoritmo a procedimientos que deben acabar en algn momento, mientras que otros consideran procedimientos que podran ejecutarse eternamente sin pararse, suponiendo el caso en el que existiera algn dispositivo fsico que fuera capaz de funcionar eternamente. En este ltimo caso, la finalizacin con xito del algoritmo no se podra definir como la terminacin de este con una salida satisfactoria, sino que el xito estara definido en funcin de las secuencias de salidas dadas durante un periodo de vida de la ejecucin del algoritmo. Por ejemplo, un algoritmo que verifica que hay ms ceros que unos en una secuencia binaria infinita debe ejecutarse siempre para que pueda devolver un valor til. Si se implementa correctamente, el valor devuelto por el algoritmo ser vlido, hasta que evale el siguiente dgito binario. De esta forma, mientras evala la siguiente secuencia podrn leerse dos tipos de seales: una seal positiva (en el caso de que el nmero de ceros sea mayor que el de unos) y una negativa en caso contrario. Finalmente, la salida de este algoritmo se define como la devolucin de valores exclusivamente positivos si hay ms ceros que unos en la secuencia y, en cualquier otro caso, devolver una mezcla de seales positivas y negativas.
Algoritmo
Ejemplo de algoritmo
El problema consiste en encontrar el mximo de un conjunto de nmeros. Para un ejemplo ms complejo vase Algoritmo de Euclides.
que pertenece al conjunto . Para encontrar el elemento mximo, se asume que el primer elemento ( ) es el mximo; luego, se recorre el conjunto y se compara cada valor con el valor del mximo nmero encontrado hasta ese momento. En el caso que un elemento sea mayor que el mximo, se asigna su valor al mximo. Cuando se termina de recorrer la lista, el mximo nmero que se ha encontrado es el mximo de todo el conjunto.
Descripcin formal
El algoritmo puede ser escrito de una manera ms formal en el siguiente pseudocdigo:
Algoritmo Encontrar el mximo de un conjunto funcin max( // )
para
si
hasta
hacer entonces
devolver
Sobre la notacin: "" representa una asignacin: significa que la variable toma el valor de ; "devolver" termina el algoritmo y devuelve el valor a su derecha (en este caso, el mximo de ).
Implementacin
En lenguaje C++: int max(int c[], int n) { int i, m = c[0]; for (i = 1; i < n; i++) if (c[i] > m) m = c[i]; return m; }
Algoritmo
Referencias
[1] Real Academia Espaola. Diccionario de la lengua espaola (http:/ / buscon. rae. es/ draeI/ SrvltGUIBusUsual?TIPO_HTML=2& TIPO_BUS=3& LEMA=algoritmo) "Conjunto ordenado y finito de operaciones que permite hallar la solucin de un problema."
Bibliografa
Fundamentos de Algoritmia, G. Brassard y P. Bratley. (ISBN 848966000X) The Art of Computer Programming, Knuth, D. E. [quien fue tambin, el creador del TeX] Introduction to Algorithms (2nd ed), Cormen, T. H., Leiserson, C. E., Rivest, R. L. y Stein, C. Introduction to Algorithms. A Creative Approach, Mamber, U. Algorithms in C (3r ed), Sedgewick, R. (tambin existen versiones en C++ y Java) The Design and Analysis of Computer Algorithms, Aho, A.
Enlaces externos
Wikilibros Wikilibros alberga un libro o manual sobre Algoritmia.
Wikcionario tiene definiciones para algoritmo.Wikcionario Portal de algoritmia (http://www.algoritmia.net) Tcnicas de Diseo de Algoritmos (http://www.lcc.uma.es/~av/Libro/) manual que explica y ejemplifica los distintos paradigmas de diseo de algoritmos. Rosa Guerequeta y Antonio Vallecillo (profesores de la Universidad de Mlaga). Transparencias de la asignatura "Esquemas Algortmicos", Campos, J. (http://webdiis.unizar.es/asignaturas/ EDA/) Apuntes y problemas de Algortmica por Domingo Gimnez Cnovas (http://dis.um.es/~domingo/alg.html) Curso de Diseo de Algoritmos de Carlos Pes (http://www.carlospes.com/curso_de_algoritmos/) Algoritmos y Diagramas de Flujo (http://snippets-tricks.org/algoritmos-y-diagramas-de-flujo/)
Heurstica
Heurstica
Se puede definir Heurstica como un arte, tcnica o procedimiento prctico o informal, para resolver problemas.[1] Alternativamente, se puede definir como un conjunto de reglas metodolgicas no necesariamente forzosas, positivas y negativas, que sugieren o establecen cmo proceder y qu problemas evitar a la hora de generar soluciones y elaborar hiptesis.[2] Es generalmente considerado que la capacidad heurstica es un rasgo caracterstico de los humanos[3] desde cuyo punto de vista puede describirse como el arte y la ciencia del descubrimiento y de la invencin o de resolver problemas mediante la creatividad y el pensamiento lateral o pensamiento divergente. Segn el matemtico George Plya[4] la base de la heurstica est en la experiencia de resolver problemas y en ver cmo otros lo hacen. Consecuentemente se dice que hay bsquedas ciegas, bsquedas heursticas (basadas en la experiencia) y bsquedas racionales. La palabra heurstica procede del trmino griego ,[5] que significa hallar, inventar (etimologa que comparte con eureka[6]). La palabra heurstica aparece en ms de una categora gramatical. Cuando se usa como sustantivo, identifica el arte o la ciencia del descubrimiento, una disciplina susceptible de ser investigada formalmente. Cuando aparece como adjetivo, se refiere a cosas ms concretas, como estrategias heursticas, reglas heursticas o silogismos y conclusiones heursticas. Claro est que estos dos usos estn ntimamente relacionados ya que la heurstica usualmente propone estrategias heursticas que guan el descubrimiento. La popularizacin del concepto se debe a George Plya, con su libro Cmo resolverlo (How to solve it). Habiendo estudiado tantas pruebas matemticas desde su juventud, quera saber cmo los matemticos llegan a ellas. El libro contiene la clase de recetas heursticas que trataba de ensear a sus alumnos de matemticas. Cuatro ejemplos extrados de l ilustran el concepto mejor que ninguna definicin: Si no consigues entender un problema, dibuja un esquema. Si no encuentras la solucin, haz como si ya la tuvieras y mira qu puedes deducir de ella (razonando a la inversa). Si el problema es abstracto, prueba a examinar un ejemplo concreto. Intenta abordar primero un problema ms general (es la paradoja del inventor: el propsito ms ambicioso es el que tiene ms posibilidades de xito).
Matemtica
En la matemtica, la heurstica existe desde la Grecia antigua. Sin embargo, la formalizacin y el alto grado de rigor en matemtica le ha restado importancia al estudio del descubrimiento, considerndolo ms bien de inters para la psicologa. Aunque existe el campo de la teora de la demostracin, ste nada tiene que ver con encontrar patrones de demostracin o reglas para encontrar las demostraciones de los teoremas. La palabra heurus proviene del griego erus. Hay trabajos de Poincar, Hadamard y Polya sobre la creacin en matemtica. Al respecto el libro "Razonamiento plausible " de George Polya, describe las posibilidades de creacin en la diversas ramas de la matemtica y trabajos concretos de algunos matemticos.
Psicologa
En psicologa la heurstica se relaciona con la creatividad y se ha propuesto que sea aquella regla sencilla y eficiente para orientar la toma de decisiones y para explicar en un plano prctico cmo las personas llegan a un juicio o solucionan un problema. Usualmente una heurstica opera cuando un problema es complejo o el problema trae informacin incompleta. En general, una heurstica puede considerarse como un atajo a los procesos mentales activos y, por lo tanto, es una medida que ahorra o conserva recursos mentales. Las heursticas funcionan efectivamente en la mayora de las circunstancias, sin embargo, tambin pueden conducir a errores sistemticos en la
Heurstica toma de decisiones o el desarrollo de juicios. La ideacin de soluciones heursticas frecuentemente arranca de un razonamiento por analoga. Un ejemplo de un atajo mental es el uso de un estereotipo. Cuando se juzga a un individuo basndose en la descripcin estereotpica de un grupo al cual pertenece, el uso del estereotipo puede resultar en un error, ya que el individuo puede ser poco representativo del estereotipo. Sin embargo la heurstica, aunque imperfecta, puede seguir siendo vlida si el estereotipo es estadsticamente lo bastante correcto. As, los posibles errores puntuales quedan sobradamente compensados por los ms frecuentes aciertos. stos son obtenidos, adems, mediante una regla relativamente sencilla que ahorra recursos mentales y acelera de forma significativa la toma de decisiones, lo que en ciertas situaciones puede resultar crtico (por ejemplo cuando la integridad fsica, mental o econmica del individuo est en juego).
Ingeniera
Artculo principal: Heurstica (ingeniera) En ingeniera, una heurstica es un mtodo basado en la experiencia que puede utilizarse como ayuda para resolver problemas de diseo, desde calcular los recursos necesarios hasta en planear las condiciones de operacin de los sistemas. Mediante el uso de heursticas, es posible resolver ms rpidamente problemas conocidos o similares a otros conocidos. Existen varios mtodos heursticos disponibles para los ingenieros como, por ejemplo, el Anlisis modal de fallos y efectos y los rboles de fallo. En el primero se depende de un grupo de ingenieros experimentados que evalan los problemas y fallos, los ordenan segn su importancia y recomiendan soluciones. Otros, como los mtodos de ingeniera forense, son una amplia fuente de informacin para la investigacin de problemas y responsables, y se basan en la heurstica del eslabn ms dbil y en la eliminacin de causas improbables. El conocimiento de qu causas son probables y cules no, forma una heurstica aprendida por la profesin durante muchos aos, ms que un conocimiento cientfico aplicado. Dado que las heursticas pueden equivocarse, es fundamental conocer los casos en los que son aplicables y los lmites a su uso. En general, en la ingeniera deben considerarse como ayudas o apoyos para hacer estimaciones rpidas y diseos preliminares, pero no como justificaciones finales de un diseo o proyecto u otros.
Heurstica Estrategias heursticas: se comportan como recursos organizativos del proceso de resolucin, que contribuyen especialmente a determinar la va de solucin del problema abordado. Existen dos estrategias: El trabajo hacia adelante: se parte de lo dado para realizar las reflexiones que han de conducir a la solucin del problema: hiptesis. El trabajo hacia atrs: se examina primeramente lo que se busca y, apoyndose en los conocimientos que se tienen, se analizan posibles resultados intermedios de lo que se puede deducir lo buscado, hasta llegar a los dados.
10
Otras acepciones
Una teora cientfica tiene un alto valor heurstico si es capaz de generar nuevas ideas o inducir nuevas invenciones. Para ello, sin ser irrelevante, no es imprescindible que la teora sea cierta o incierta. Parafraseando a Sartre; merced a su capacidad heurstica, pese a las predeterminaciones genticas y otros condicionamientos, es probable que el ser humano (valga la aparente paradoja de la frase) est condenado a ser libre de las limitaciones que el medio le impone. Mirndola desde los conceptos subyacentes, la propuesta heurstica es la capacidad del ser humano para cambiar su conducta, con el fin de resolver situaciones problemticas.
Referencias
* Moustakas, Clark. "Heuristic Research: Design, Methodology and Applications." California: Sage Publications, 1990.
http:/ / www.
openisbn.com/isbn/0803938829/
[1] Glosario: Arte o tcnica de la bsqueda o investigacin. Mtodo heurstico, por oposicin al didctico o de enseanza. en Heurstica (http:/ / lengua-y-literatura. glosario. net/ terminos-filosoficos/ heurstica-5819. html) [2] Roberto Gmez L (http:/ / www. eumed. net/ cursecon/ libreria/ rgl-evol/ 2. 4. 6. htm), citando a Imre Lakatos en EVOLUCIN CIENTFICA Y METODOLGICA DE LA ECONOMA] 2.4.6. LOS PROGRAMAS DE INVESTIGACIN CIENTFICA DE LKATOS. [3] Epistemowikia: Por heurstica entendemos una estrategia, mtodo, criterio o truco usado para hacer ms sencilla la solucin de problemas difciles. El conocimiento heurstico es un tipo especial de conocimiento usado por los humanos para resolver problemas complejos. en Heurstica (http:/ / campusvirtual. unex. es/ cala/ epistemowikia/ index. php?title=Heurstica) [4] G Plya: (1945) "How to solve it", traducido al castellano como Cmo resolverlo (1965) [5] Segn la Real Academia, (http:/ / lema. rae. es/ drae/ ?val=heurstica) (consultado el 29 de abril de 2009). [6] Real Academia (http:/ / buscon. rae. es/ draeI/ SrvltConsulta?TIPO_BUS=3& LEMA=eureka) (consultado el 29 de abril de 2009).
11
Historia
Antes de que se realizaran investigaciones en torno a la complejidad de los algoritmos, se crearon los cimientos de esta teora por varios investigadores. Uno de los aportes ms influyentes fue la definicin de las Mquinas de Turing en 1936, las cuales resultaron ser una nocin de computadora muy flexible y robusta. A medida que las computadoras se desarrollaban en los 40's y los 50's, la Mquina de Turing demostr ser el modelo terico correcto de cmputo. Sin embargo, rpidamente se descubri que el modelo bsico de la Mquina de Turing fallaba al cuantificar el tiempo y la memoria requerida por una computadora, un problema crtico hoy en da, y an ms en aquellos tiempos. La idea de medir el tiempo y espacio como una funcin de la longitud de la entrada, se origin a principios de los 60's por Hartmanis and Stearns, y as, naci la teora de la complejidad computacional. En los inicios, los investigadores trataban de entender las nuevas medidas de complejidad, y cmo se relacionaban unas con otras. En 1965, Edmonds defini un "buen" algoritmo como uno con un tiempo de ejecucin acotado por un polinomio, es decir, con un tiempo de ejecucin polinmico.[1] Esto condujo al surgimiento de uno de los conceptos ms importantes de la teora de la complejidad computacional: la NP-completitud y su pregunta fundamental, si P=NP. El campo comenz a florecer cuando el investigador norteamericano Stephen Cook, trabajando de manera independiente al investigador sovitico Leonid Levin, probaron que existen problemas relevantes que son NP-completos. En 1972, Richard Karp llev esta idea un paso ms adelante, demostrando que 21 problemas combinatorios y de teora de grafos, caracterizados por ser computacionalmente intratables, eran NP-completos. Tambin en los 70's, se produjo un crecimiento de las clases de complejidad a medida que los investigadores trataban de comprender los distintos modelos de cmputo existentes. En los 80's, se produjo un auge de los modelos finitos, que analizaban el proceso de cmputo de una manera inherentemente distinta. Surgi un nuevo acercamiento a problemas como P=NP, y an cuando estos modelos tenan sus limitaciones separando las clases de complejidad, esta aproximacin introdujo tcnicas combinatorias que permitieron un mejor entendimiento de los lmites de estos modelos.
Teora de la complejidad computacional Ya en los 90's, se estudiaron nuevos modelos de cmputo como las computadoras cunticas, donde una misma tarea puede tener diferente complejidad en la computacin clsica y en la computacin cuntica. Sin embargo, existen varias limitantes, entre ellas, la de desarrollar un hardware para este modelo, y que se requieren grandes cantidades de espacio para realizar los clculos.
12
Problema computacional
Un problema computacional constituye una pregunta a ser respondida, teniendo generalmente varios parmetros, o variables libres, cuyos valores no se han especificado. Un problema se describe mediante: 1. Una descripcin general de todos sus parmetros (pueden ser de entrada o de salida). 2. Una sentencia que describa las propiedades que la respuesta, o la solucin, debe cumplir. Una instancia de un problema se obtiene cuando se especifican valores particulares para todos los parmetros del problema. Por ejemplo, consideremos el problema del test de primalidad. La instancia es un nmero (e.g. 15) y la solucin es "s" si el nmero es primo, y "no" en caso contrario. Visto de otra manera, la instancia es una entrada particular del problema, y la solucin es la salida correspondiente para la entrada dada.
Problemas de decisin
Un problema de decisin es un tipo especial de problema computacional cuya respuesta es solamente "s" o "no" (o, de manera ms formal, "1" o "0"). Un problema de decisin pudiera verse como un lenguaje formal, donde los elementos que pertenecen al lenguaje son las instancias del problema cuya respuesta es "s", los que no pertenecen al lenguaje son aquellas instancias cuya respuesta es "no". El objetivo es decidir, con la ayuda de un algoritmo, si una determinada entrada es un elemento del lenguaje formal considerado. Si el algoritmo devuelve como respuesta "s", se dice que el algoritmo acepta la entrada, de lo contrario se dice que la rechaza. Los problemas de decisin constituyen uno de los principales objetos de estudio de la teora de la complejidad computacional, pues la NP-completitud se aplica directamente a estos tipos de problemas en vez de a problemas de optimizacin. Estos problemas tienen gran importancia porque casi todo problema puede transformarse en un problema de decisin.
Algoritmos
Podemos decir informalmente, que los algoritmos son procedimientos paso-a-paso para resolver problemas. Se puede pensar en ellos como simples programas de computadora, escritos en un lenguaje artificial especfico.[2] Se dice que un algoritmo resuelve un problema A, si dicho algoritmo se puede aplicar a cualquier instancia I de A, y se garantiza que siempre produce una solucin para dicha instancia. De manera general, nos interesa encontrar el algoritmo ms "eficiente" para resolver cierto problema. En su sentido ms amplio, la nocin de eficiencia involucra a todos los recursos computacionales necesarios para la ejecucin de un algoritmo. Por algoritmo "ms eficiente" usualmente nos referimos al ms rpido. Debido a que los requerimientos de tiempo son usualmente un factor dominante cuando se trata de determinar si un algoritmo es lo suficientemente eficiente para ser til en la prctica, nos concentraremos en este recurso.
13
Clases de complejidad
Una clase de complejidad es un conjunto de problemas que poseen la misma complejidad computacional.
14
Mquina de Turing no determinista Tiempof(n) Mquina de Turing no determinista Tiempo poly(n) Mquina de Turing no determinista Tiempo 2poly(n) Mquina de Turing determinista Mquina de Turing determinista Mquina de Turing determinista Mquina de Turing determinista Espaciof(n) Espacio O(log n) Espacio poly(n) Espacio 2poly(n)
Mquina de Turing no determinista Espaciof(n) Mquina de Turing no determinista Espacio O(log n) Mquina de Turing no determinista Espacio poly(n) Mquina de Turing no determinista Espacio 2poly(n)
15
La pregunta P=NP
La relacin entre las clases P y NP es fundamental para la teora de la NP-completitud. Intuitivamente, creemos que P es un subconjunto de NP. Y efectivamente, cada problema de decisin resuelto por un algoritmo de tiempo polinomial determinista, tambin puede ser resuelto por un algoritmo de tiempo polinomial no determinista. Simplemente se necesita observar que cualquier algoritmo determinista puede ser utilizado en la etapa de verificacin de un algoritmo no determinista. Si B es un problema de P, y A es un algoritmo de tiempo polinomial para B, entonces se puede construir un algoritmo de tiempo polinomial no determinista para B, simplemente utilizando A en la etapa de verificacin e ignorando la etapa de adivinacin. Por tanto, si B pertenece a P, entonces B tambin pertenece a NP. La pregunta P=NP es una de las ms importantes en el campo de las ciencias de la computacin, debido a las grandes repercusiones que habran, en caso de encontrarse una solucin. Si P=NP, cualquier problema polinmicamente verificable fuera polinmicamente decidible. La mayora de los investigadores creen que estas clases no son iguales, porque se han realizado bastantes esfuerzos para encontrar algoritmos de tiempo polinomial para varios problemas en NP, sin xito. Los investigadores tambin han tratado de probar que las clases son distintas, pero eso conllevara a mostrar que no existe un algoritmo "eficiente" para reemplazar a la bsqueda por fuerza bruta.
NP-Completitud
Reduccin polinomial
Una reduccin es una transformacin de un problema en otro problema. Intuitivamente, un problema Q puede ser reducido a otro problema Q', si cualquier instancia del problema Q puede ser "fcilmente" expresada como una instancia del problema Q', y cuya solucin proporcione una solucin para la instancia de Q.[6] Existen muchos tipos de reducciones: basadas en el mtodo de reduccin, como las reducciones de Cook, las reducciones de Karp y las reducciones de Levin, y las basadas en la cota de la complejidad, como la reduccin en tiempo polinomial o la reduccin de espacio logartmica. Una de las reducciones ms utilizadas es la reduccin en tiempo polinomial, lo cual significa que el proceso de reduccin toma un tiempo polinomial.
Problemas NP-completos
Las reducciones en tiempo polinomial nos dotan de elementos para probar, de una manera formal, que un problema es al menos tan difcil que otro, con una diferencia de un factor polinomial. Estas son esenciales para definir a los problemas NP-completos, adems de ayudar a comprender los mismos. La clase de los problemas NP-completos contiene a los problemas ms difciles en NP, en el sentido de que son los que estn ms lejos de estar en P. Debido a que el problema P=NP no ha sido resuelto, el hecho de reducir un problema B, a otro problema A, indicara que no se conoce solucin en tiempo polinomial para A. Esto es debido a que una solucin en tiempo polinomial para A, tendra como consecuencia la existencia de una solucin polinomial para B. De manera similar, debido a que todos los problemas NP pueden ser reducidos a este conjunto, encontrar un problema NP-completo que pueda ser resuelto en un tiempo polinomial significara que P=NP.
Importancia de la NP-Completitud
Quizs la razn de mayor peso por la cual los cientficos de la computacin creen que P es distinto de NP, es la existencia de la clase de problemas "NP-completos". Esta clase tiene la curiosa propiedad de que si algn problema NP-completo puede ser resuelto en tiempo polinomial, entonces todo problema en NP tiene una solucin en tiempo polinomial, es decir, P=NP. A pesar de aos de estudio, ningn algoritmo de tiempo polinomial se ha descubierto para ningn problema NP-completo.
Teora de la complejidad computacional Desde el punto de vista terico, un investigador intentando mostrar que la clase P es distinta de la clase NP, pudiera enfocarse en un problema NP-completo. Si algn problema en NP requiere ms que un tiempo polinomial, entonces uno NP-completo tambin. Adems, un investigador intentando demostrar que P=NP, solo necesita encontrar un algoritmo de tiempo polinomial para un problema NP-completo para lograrlo. Desde el punto de vista prctico, el fenmeno de la NP-completitud puede prevenir la prdida de tiempo cuando se busca un algoritmo de tiempo polinomial no existente para resolver un problema determinado. An cuando no se posean los elementos matemticos para demostrar que cierto problema no se puede resolver en tiempo polinomial, creemos que P no es igual a NP, as que demostrar que el problema es NP-completo, es una fuerte evidencia de su no "polinomialidad".
16
Referencias
[1] Richard M. Karp, "Combinatorics, Complexity, and Randomness", 1985 Turing Award Lecture. [2] Garey, Michael R., Johnson David S., (1979), Computers and Intractability: A Guide to the Theory of NP-Completeness, W. H. Freeman, (page 4). [3] Garey, Michael R., Johnson David S., (1979), Computers and Intractability: A Guide to the Theory of NP-Completeness, W. H. Freeman, (page 8). [4] Cormen, Thomas H.; Leiserson, Charles E.; Rivest, Ronald L. & Stein, Clifford, (2010), Introduction to Algorithms, 3ra edicin, MIT Press and McGraw-Hill, (page 1049). [5] Garey, Michael R., Johnson David S., (1979), Computers and Intractability: A Guide to the Theory of NP-Completeness, W. H. Freeman, (page 28). [6] Cormen, Thomas H.; Leiserson, Charles E.; Rivest, Ronald L. & Stein, Clifford, (2010), Introduction to Algorithms, 3ra edicin, MIT Press and McGraw-Hill, (page 1067).
Artculos
Cook, Stephen (1983), An overview of computational complexity, Commun. ACM (ACM) 26 (6): 400408, ISSN 0001-0782 (http:/ / worldcat. org/ issn/ 0001-0782) Fortnow, Lance; Homer, Steven (2002), A Short History of Computational Complexity (http://people.cs. uchicago.edu/~fortnow/papers/history.pdf), Bulletin of the EATCS 80: 95133
Libros de texto
Arora, Sanjeev; Barak, Boaz (2009), Computational Complexity: A Modern Approach (http://www.cs. princeton.edu/theory/complexity/), Cambridge, ISBN 978-0-521-42426-4 Sipser, Michael (2006), Introduction to the Theory of Computation (2da edicin), USA: Thomson Course Technology, ISBN 0-534-95097-3
Teora de la complejidad computacional Garey, Michael R.; Johnson, David S., (1979), Computers and Intractability: A Guide to the Theory of NP-Completeness, W. H. Freeman, ISBN 0-7167-1045-5. Cormen, Thomas H.; Leiserson, Charles E.; Rivest, Ronald L. & Stein, Clifford (2010), Introduction to Algorithms (3ra edicin), Cambridge, MA: MIT Press and McGraw-Hill, ISBN 0-262-03384-4.
17
18
Crecimiento de finciones
Cota superior asinttica
En anlisis de algoritmos una cota superior asinttica es una funcin que sirve de cota superior de otra funcin cuando el argumento tiende a infinito. Usualmente se utiliza la notacin de Landau O(g(x)) (o coloquialmente llamada Notacin O Grande) para referirse a las funciones acotadas superiormente por la funcin g(x). Ms formalmente se define:
Una funcin f(x) pertenece a O(g(x)) cuando existe una constante positiva c tal que a partir de un valor , f(x) no sobrepasa a . Quiere decir que la funcin f es inferior a g a partir de un valor dado salvo por un factor constante. La cota superior asinttica tiene gran importancia en Teora de la complejidad computacional a la hora de definir las clases de complejidad. A pesar de que O(g(x)) est definido como un conjunto, se acostumbra escribir f(x)=O(g(x)) en lugar de f(x)O(g(x)). Muchas veces tambin se habla de una funcin nombrando nicamente su expresin, como en x en lugar de h(x)=x, siempre que est claro cul es el parmetro de la funcin dentro de la expresin. En la grfica se da un ejemplo esquemtico de como se comporta con respecto a f(x) cuando x tiende a infinito. Note adems que dicho conjunto es no vaco pues f(x)=O(g(x)). La cota ajustada asinttica (notacin ) tiene relacin con las cotas asintticas superior e inferior (notacin ):
f(x)=O(g(x)).
Propiedades
Sea i) Si ii) Si iii) iv) Si v) Si vi) Si y entonces , entonces , sean y y , , entonces ,entonces (aqu es igualdad entre conjuntos) ,entonces (aqu es igualdad entre conjuntos) . , , funciones y un real. Entonces los siguientes enunciados son ciertos
19
Ejemplos
La funcin x+10 puede ser acotada superiormente por la funcin 11x. Para demostrarlo basta notar que para todo valor de x1 se cumple x+1011x. Por tanto x+10 = O(x). Sin embargo, x no sirve como cota inferior para x+10, es decir, . Observacin: Este ejemplo muestra que el uso del smbolo "=" esta mal empleado (matemticamente) pues la notacin de Landau (O grande) no es reflexiva. La funcin 200x est acotada superiormente por x. Quiere decir que cuando x tiende a infinito el valor de 200x se puede despreciar con respecto al de x.
O(log log n) orden sublogartmico O(log n) O( O(n) O(n log n) O(nc) ) orden logartmico orden sublineal orden lineal orden lineal logartmico orden potencial
O(cn), n > 1 orden exponencial O(n!) O(nn) orden factorial orden potencial exponencial[citarequerida]
Bibliografa
Introduction to Algorithms, Second Edition by Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein
20
Una funcin f(x) pertenece a (g(x)) cuando existe una constante positiva c tal que a partir de un valor
no supera f(x). Quiere decir que la funcin f es superior a g a partir de un valor dado salvo por un factor constante. La cota inferior asinttica tiene utilidad en Teora de la complejidad computacional a la hora de calcular la complejidad del mejor caso para los algoritmos. A pesar de que (g(x)) est definido como un conjunto, se acostumbra escribir f(x)=(g(x)) en lugar de f(x) (g(x)). Muchas veces tambin se habla de una funcin nombrando nicamente su expresin, como en x en lugar de h(x)=x, siempre que est claro cual es el parmetro de la funcin dentro de la expresin. En la grfica se da un ejemplo esquemtico de como se comporta con respecto a f(x) cuando x tiende a infinito. La cota ajustada asinttica (notacin ) tiene relacin con las cotas superior (notacin O) e inferior asintticas :
f(x)=(g(x)).
Ejemplos
La funcin x puede ser acotada inferiormente por la funcin x. Para demostrarlo basta notar que para todo valor de x1 se cumple xx. Por tanto x = (x) (sin embargo, x no sirve como cota superior para x). La funcin x+200x est acotada inferiormente por x. Quiere decir que cuando x tiende a infinito el valor de 200x se puede despreciar con respecto al de x.
Bibliografa
Introduction to Algorithms, Second Edition by Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein
21
Una funcin f(x) pertenece a (g(x)) cuando existen constantes positivas y tales que a partir de un valor f(x) se encuentra atrapada entre y . Quiere decir que las funciones f y g son iguales a partir de un valor dado salvo por una factor constante. Por tanto tiene sentido tomar a g como un representante de f. A pesar de que (g(x)) est definido como un conjunto, se acostumbra escribir f(x)=(g(x)) en lugar de f(x)(g(x)). Muchas veces tambin se habla de la funcin x en lugar de h(x)=x siempre que est claro cual es el parmetro de la funcin dentro de la expresin. En la grfica se da un ejemplo esquemtico de cmo se comportan y con respecto a f(x) cuando x tiende a infinito.
f(x)=(g(x)).
La cota ajustada asinttica tiene relacin con las cotas superior e inferior asintticas (respectivamente las notaciones O y ):
Ejemplos
La funcin f(x) = x+10 puede ser acotada por la funcin g(x) = x. Para demostrarlo basta notar que para todo valor de x1 se cumple que g(x)f(x)11g(x), es decir x x+10 11x . Por lo tanto x+10 = (x).
Bibliografa
Introduction to Algorithms, Second Edition by Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein
22
Ordenamiento
Algoritmo de ordenamiento
En computacin y matemticas un algoritmo de ordenamiento es un algoritmo que pone elementos de una lista o un vector en una secuencia dada por una relacin de orden, es decir, el resultado de salida ha de ser una permutacin o reordenamiento de la entrada que satisfaga la relacin de orden dada. Las relaciones de orden ms usadas son el orden numrico y el orden lexicogrfico. Ordenamientos eficientes son importantes para optimizar el uso de otros algoritmos (como los de bsqueda y fusin) que requieren listas ordenadas para una ejecucin rpida. Tambin es til para poner datos en forma cannica y para generar resultados legibles por humanos.
Quicksort en accin sobre una lista de nmeros aleatorios. Las lneas horizontales son valores pivote.
Desde los comienzos de la computacin, el problema del ordenamiento ha atrado gran cantidad de investigacin, tal vez debido a la complejidad de resolverlo eficientemente a pesar de su planteamiento simple y familiar. Por ejemplo, BubbleSort fue analizado desde 1956.[1] Aunque muchos puedan considerarlo un problema resuelto, nuevos y tiles algoritmos de ordenamiento se siguen inventado hasta el da de hoy (por ejemplo, el ordenamiento de biblioteca se public por primera vez en el 2004). Los algoritmos de ordenamiento son comunes en las clases introductorias a la computacin, donde la abundancia de algoritmos para el problema proporciona una gentil introduccin a la variedad de conceptos ncleo de los algoritmos, como notacin de O mayscula, algoritmos divide y vencers, estructuras de datos, anlisis de los casos peor, mejor, y promedio, y lmites inferiores.
Clasificacin
Los algoritmos de ordenamiento se pueden clasificar de las siguientes maneras: La ms comn es clasificar segn el lugar donde se realice la ordenacin Algoritmos de ordenamiento interno: en la memoria del ordenador. Algoritmos de ordenamiento externo: en un lugar externo como un disco duro. Por el tiempo que tardan en realizar la ordenacin, dadas entradas ya ordenadas o inversamente ordenadas: Algoritmos de ordenacin natural: Tarda lo mnimo posible cuando la entrada est ordenada. Algoritmos de ordenacin no natural: Tarda lo mnimo posible cuando la entrada est inversamente ordenada. Por estabilidad: un ordenamiento estable mantiene el orden relativo que tenan originalmente los elementos con claves iguales. Por ejemplo, si una lista ordenada por fecha se reordena en orden alfabtico con un algoritmo estable, todos los elementos cuya clave alfabtica sea la misma quedarn en orden de fecha. Otro caso sera cuando no interesan las maysculas y minsculas, pero se quiere que si una clave aBC estaba antes que AbC, en el resultado ambas claves aparezcan juntas y en el orden original: aBC, AbC. Cuando los elementos son
Algoritmo de ordenamiento indistinguibles (porque cada elemento se ordena por la clave completa) la estabilidad no interesa. Los algoritmos de ordenamiento que no son estables se pueden implementar para que s lo sean. Una manera de hacer esto es modificar artificialmente la clave de ordenamiento de modo que la posicin original en la lista participe del ordenamiento en caso de coincidencia. Los algoritmos se distinguen por las siguientes caractersticas: Complejidad computacional (peor caso, caso promedio y mejor caso) en trminos de n, el tamao de la lista o arreglo. Para esto se usa el concepto de orden de una funcin y se usa la notacin O(n). El mejor comportamiento para ordenar (si no se aprovecha la estructura de las claves) es O(n log n). Los algoritmos ms simples son cuadrticos, es decir O(n). Los algoritmos que aprovechan la estructura de las claves de ordenamiento (p. ej. bucket sort) pueden ordenar en O(kn) donde k es el tamao del espacio de claves. Como dicho tamao es conocido a priori, se puede decir que estos algoritmos tienen un desempeo lineal, es decir O(n). Uso de memoria y otros recursos computacionales. Tambin se usa la notacin O(n).
23
Estabilidad
Los algoritmos de ordenamiento estable mantienen un relativo preorden total. Esto significa que un algoritmo es estable solo cuando hay dos registros R y S con la misma clave y con R apareciendo antes que S en la lista original. Cuando elementos iguales (indistinguibles entre s), como nmeros enteros, o ms generalmente, cualquier tipo de dato en donde el elemento entero es la clave, la estabilidad no es un problema. De todas formas, se asume que los siguientes pares de nmeros estn por ser ordenados por su primer componente: (4, 1) (3, 7) (3, 1) (5, 6)
En este caso, dos resultados diferentes son posibles, uno de los cuales mantiene un orden relativo de registros con claves iguales, y una en la que no: (3, 7) (3, 1) (3, 1) (3, 7) (4, 1) (4, 1) (5, 6) (5, 6) (orden mantenido) (orden cambiado)
Los algoritmos de ordenamiento inestable pueden cambiar el orden relativo de registros con claves iguales, pero los algoritmos estables nunca lo hacen. Los algoritmos inestables pueden ser implementados especialmente para ser estables. Una forma de hacerlo es extender artificialmente el cotejamiento de claves, para que las comparaciones entre dos objetos con claves iguales sean decididas usando el orden de las entradas original. Recordar este orden entre dos objetos con claves iguales es una solucin poco prctica, ya que generalmente acarrea tener almacenamiento adicional. Ordenar segn una clave primaria, secundaria, terciara, etc., puede ser realizado utilizando cualquier mtodo de ordenamiento, tomando todas las claves en consideracin (en otras palabras, usando una sola clave compuesta). Si un mtodo de ordenamiento es estable, es posible ordenar mltiples tems, cada vez con una clave distinta. En este caso, las claves necesitan estar aplicadas en orden de aumentar la prioridad. Ejemplo: ordenar pares de nmeros, usando ambos valores (4, 1) (4, 1) (3, 1) (3, 7) (3, 1) (3, 7) (3, 1) (4, 6) (4, 1) (4, 6) (original) (3, 7) (despus de ser ordenado por el segundo valor) (4, 6) (despus de ser ordenado por el primer valor)
Por otro lado: (3, 7) (3, 1) (3, 1) (4, 1) (4, 1) (4, 6) (4, 6) (despus de ser ordenado por el primer valor) (3, 7) (despus de ser ordenando por el segundo valor, el orden por el primer valor es perturbado)
Algoritmo de ordenamiento
24
Ordenamiento de burbuja bidireccional Cocktail sort Ordenamiento por seleccin Ordenamiento por insercin Ordenamiento por casilleros Ordenamiento por cuentas Ordenamiento por mezcla Ordenamiento con rbol binario Selection Sort Insertion sort Bucket sort Counting sort Merge sort Binary tree sort Pigeonhole sort Ordenamiento Radix Radix sort Distribution sort Gnome sort
Several Unique Sort Promedio: O(n u), peor caso: O(n); u=n; u = nmero nico de registros Cuestionables, imprcticos Nombre traducido Nombre original Bogosort Pancake sorting Complejidad O(n n!), peor: no termina O(n), excepto en mquinas de Von Neumann Promedio: O(n!) Peor: No termina Memoria Mtodo
Randomsort
Algoritmo de ordenamiento
25
Referencias
[1] Bubble Sort: An archaeological algorithm analysis (http:/ / www. cs. duke. edu/ ~ola/ papers/ bubble. pdf). Owen Astrachan
Enlaces externos
Explicacin de los distintos mtodos de ordenamiento en Java. (http://blog.zerial.org/ficheros/ Informe_Ordenamiento.pdf) (pdf) Discusin sobre varios algoritmos de ordenacin y sus caractersticas (http://es.tldp.org/Tutoriales/ doc-programacion-algoritmos-ordenacion/alg_orden.pdf) (licencia GFDL) (pdf) Animacin de algoritmos de ordenamiento (http://web.archive.org/web/http://dvegaf.iespana.es/) Animacin de algoritmos de ordenamiento (en ingls) (http://web.archive.org/web/http://vision.bc.edu/ ~dmartin/teaching/sorting/anim-html/all.html) ALT: Algorithm Learning Tool. Herramienta de apoyo a la enseanza de algoritmos que muestra grficamente su funcionamiento. Permite implementar algoritmos propios y realizar una ejecucin dinmica e interactiva (http:// xistral.ei.uvigo.es/MTPAlgoritmos/index.php?action=VisualizarAlgoritmos&tipo=Ordenacion) Cdigos de Ordenamiento en Python (http://tutorial-python.com.ar)
Heapsort
El ordenamiento por montculos (heapsort en ingls) es un algoritmo de ordenamiento no recursivo, no estable, con complejidad computacional Este algoritmo consiste en almacenar todos los elementos del vector a ordenar en un montculo (heap), y luego extraer el nodo que queda como nodo raz del montculo (cima) en sucesivas iteraciones obteniendo el conjunto ordenado. Basa su funcionamiento en una propiedad de los montculos, por la cual, la cima contiene siempre el menor elemento (o el mayor, segn se haya definido el montculo) de Animacin mostrando el funcionamiento del heapsort. todos los almacenados en l. El algoritmo, despus de cada extraccin, recoloca en el nodo raz o cima, la ltima hoja por la derecha del ltimo nivel. Lo cual destruye la propiedad heap del rbol. Pero, a continuacin realiza un proceso de "descenso" del nmero insertado de forma que se elige a cada movimiento el mayor de sus dos hijos, con el que se intercambia. Este intercambio, realizado sucesivamente "hunde" el nodo en el rbol restaurando la propiedad montculo del arbol y dejndo paso a la siguiente extraccin del nodo raz. El algoritmo, en su implementacin habitual, tiene dos fases. Primero una fase de construccin de un montculo a partir del conjunto de elmentos de entrada, y despus, una fase de extraccin sucesiva de la cima del montculo. La implementacin del almacn de datos en el heap, pese a ser conceptualmente un rbol, puede realizarse en un vector de forma fcil. Cada nodo tiene dos hijos y por tanto, un nodo situado en la posicin i del vector, tendr a sus hijos en las posiciones 2 x i, y 2 x i +1 suponiendo que el primer elemento del vector tiene un ndice = 1. Es decir, la cima ocupa la posicin inicial del vector y sus dos hijos la posicin segunda y tercera, y as, sucesivamente. Por tanto, en
Heapsort la fase de ordenacin, el intercambio ocurre entre el primer elemento del vector (la raz o cima del rbol, que es el mayor elemento del mismo) y el ltimo elemento del vector que es la hoja ms a la derecha en el ltimo nivel. El rbol pierde una hoja y por tanto reduce su tamao en un elemento. El vector definitivo y ordenado, empieza a construirse por el final y termina por el principio.
26
Descripcin
He aqu una descripcin en pseudocdigo del algoritmo. Se pueden encontrar descripciones de las operaciones insertar_en_monticulo y extraer_cima_del_monticulo en el artculo sobre montculos. function heapsort(array A[0..n]): montculo M integer i := 124578 for i = 0..n: insertar_en_monticulo(M, A[i]) for i = 0..n: A[i] = extraer_cima_del_monticulo(M) return A
Enlaces externos
Distintas implementaciones del algoritmo en RosettaCode.org [1]
Referencias
[1] http:/ / rosettacode. org/ wiki/ Sorting_algorithms/ Heapsort
Quicksort
27
Quicksort
El ordenamiento rpido (quicksort en ingls) es un algoritmo creado por el cientfico britnico en computacin C. A. R. Hoare basado en la tcnica de divide y vencers, que permite, en promedio, ordenar n elementos en un tiempo proporcional a n log n.
En la primera fase del algoritmo habr n comparaciones. En la segunda fase el algoritmo instanciar dos sublistas de tamao aproximadamente n/2. El nmero total de comparaciones de estas dos sublistas es: 2(n/2) = n. En la tercera fase el algoritmo procesar 4 sublistas ms, por tanto el nmero total de comparaciones en esta fase es 4(n/4) = n. En conclusin, el nmero total de comparaciones que hace el algoritmo es: , donde caso es . , por tanto el tiempo de ejecucin del algoritmo en el mejor
Quicksort
28
Tcnicas de reposicionamiento
Una idea preliminar para ubicar el pivote en su posicin final sera contar la cantidad de elementos menores que l, y colocarlo un lugar ms arriba, moviendo luego todos esos elementos menores que l a su izquierda, para que pueda aplicarse la recursividad. Existe, no obstante, un procedimiento mucho ms efectivo. Se utilizan dos ndices: i, al que llamaremos ndice izquierdo, y j, al que llamaremos ndice derecho. El algoritmo es el siguiente: Recorrer la lista simultneamente con i y j: por la izquierda con i (desde el primer elemento), y por la derecha con j (desde el ltimo elemento). Cuando lista[i] sea mayor que el pivote y lista[j] sea menor, se intercambian los elementos en esas posiciones. Repetir esto hasta que se crucen los ndices. El punto en que se cruzan los ndices es la posicin adecuada para colocar el pivote, porque sabemos que a un lado los elementos son todos menores y al otro son todos mayores (o habran sido intercambiados).
Quicksort
29
Ejemplo
En el siguiente ejemplo se marcan el pivote y los ndices i y j con las letras p, i y j respectivamente. Comenzamos con la lista completa. El elemento pivote ser el 4: 5 - 3 - 7 - 6 - 2 - 1 - 4 p Comparamos con el 5 por la izquierda y el 1 por la derecha. 5 - 3 - 7 - 6 - 2 - 1 - 4 i j p 5 es mayor que 4 y 1 es menor. Intercambiamos: 1 - 3 - 7 - 6 - 2 - 5 - 4 i j p Avanzamos por la izquierda y la derecha: 1 - 3 - 7 - 6 - 2 - 5 - 4 i j p 3 es menor que 4: avanzamos por la izquierda. 2 es menor que 4: nos mantenemos ah. 1 - 3 - 7 - 6 - 2 - 5 - 4 i j p 7 es mayor que 4 y 2 es menor: intercambiamos. 1 - 3 - 2 - 6 - 7 - 5 - 4 i j p Avanzamos por ambos lados: 1 - 3 - 2 - 6 - 7 - 5 - 4 iyj p En este momento termina el ciclo principal, porque los ndices se cruzaron. Ahora intercambiamos lista[i] con lista[sup] (pasos 16-18): 1 - 3 - 2 - 4 - 7 - 5 - 6 p Aplicamos recursivamente a la sublista de la izquierda (ndices 0 - 2). Tenemos lo siguiente: 1 - 3 - 2 1 es menor que 2: avanzamos por la izquierda. 3 es mayor: avanzamos por la derecha. Como se intercambiaron los ndices termina el ciclo. Se intercambia lista[i] con lista[sup]: 1 - 2 - 3 El mismo procedimiento se aplicar a la otra sublista. Al finalizar y unir todas las sublistas queda la lista inicial ordenada en forma ascendente. 1 - 2 - 3 - 4 - 5 - 6 - 7
Quicksort
30
Enlaces externos
Distintas implementaciones del algoritmo en RosettaCode.org [1]
Referencias
[1] http:/ / rosettacode. org/ wiki/ Sorting_algorithms/ Quicksort
31
Estructuras de datos
Estructura de datos
En programacin, una estructura de datos es una forma de organizar un conjunto de datos elementales con el objetivo de facilitar su manipulacin. Un dato elemental es la mnima informacin que se tiene en un sistema. Una estructura de datos define la organizacin e interrelacin de estos y un conjunto de operaciones que se pueden realizar sobre ellos. Las operaciones bsicas son: Alta, adicionar un nuevo valor a la estructura. Baja, borrar un valor de la estructura. Bsqueda, encontrar un determinado valor en la estructura para realizar una operacin con este valor, en forma secuencial o binario (siempre y cuando los datos estn ordenados). Otras operaciones que se pueden realizar son: Ordenamiento, de los elementos pertenecientes a la estructura. Apareo, dadas dos estructuras originar una nueva ordenada y que contenga a las apareadas. Cada estructura ofrece ventajas y desventajas en relacin a la simplicidad y eficiencia para la realizacin de cada operacin. De esta forma, la eleccin de la estructura de datos apropiada para cada problema depende de factores como la frecuencia y el orden en que se realiza cada operacin sobre los datos.
Estructuras de datos
Conjuntos (set) Matriz (matemticas) Matriz (programacin) Lista Lista simple Lista doblemente enlazada Lista circular Listas por saltos (Skip lists)
rboles rboles Binarios rbol binario de bsqueda rbol binario de bsqueda equilibrado rboles rojo-negro rboles AVL rboles biselados (rboles splay) rboles multicamino (Multirrama) rboles B rboles B+ rboles B* Tries Grafos
Estructura de datos Tablas Hash Mapeos Diccionarios Montculos (o heaps) Montculo binario Montculo binmico Montculo de Fibonacci Montculo suave Montculo 2-3
32
Pila (informtica)
Una pila (stack en ingls) es una lista ordenada o estructura de datos en la que el modo de acceso a sus elementos es de tipo LIFO (del ingls Last In First Out, ltimo en entrar, primero en salir) que permite almacenar y recuperar datos. Esta estructura se aplica en multitud de ocasiones en el rea de informtica debido a su simplicidad y ordenacin implcita de la propia estructura. Para el manejo de los datos se cuenta con dos operaciones bsicas: apilar (push), que coloca un objeto en la pila, y su operacin inversa, retirar (o desapilar, pop), que retira el ltimo elemento apilado.
En cada momento slo se tiene acceso a la parte superior de la pila, es decir, al ltimo objeto apilado (denominado TOS, Top of Stack en ingls). La operacin retirar permite la obtencin de este elemento, que es retirado de la pila permitiendo el acceso al siguiente (apilado con anterioridad), que pasa a ser el nuevo TOS. Por analoga con objetos cotidianos, una operacin apilar equivaldra a colocar un plato sobre una pila de platos, y una operacin retirar a retirarlo. Las pilas suelen emplearse en los siguientes contextos: Evaluacin de expresiones en notacin postfija (notacin polaca inversa). Reconocedores sintcticos de lenguajes independientes del contexto Implementacin de recursividad.
Historia
El mtodo de pila para la evaluacin de expresiones fue propuesto en 1955 y dos aos despus patentado por Friedrich L. Bauer, quin recibi en 1988 el premio "IEEE Computer Society Pioneer Award" por su trabajo en el desarrollo de dicha estructura de datos.
Pila (informtica) usuario, todas las dems placas permanecen ocultas. Como se aaden las nuevas placas, cada nueva placa se convierte en la parte superior de la pila, escondidos debajo de cada plato, empujando a la pila de placas. A medida que la placa superior se elimina de la pila, la segunda placa se convierte en la parte superior de la pila. Dos principios importantes son ilustrados por esta metfora: En primer lugar la ltima salida es un principio, la segunda es que el contenido de la pila est oculto. Slo la placa de la parte superior es visible, por lo que para ver lo que hay en la tercera placa, el primer y segundo platos tendrn que ser retirados.
33
Operaciones
Una pila cuenta con 2 operaciones imprescindibles: apilar y desapilar, a las que en las implementaciones modernas de las pilas se suelen aadir ms de uso habitual. Crear: se crea la pila vaca. (constructor) Tamao: regresa el nmero de elementos de la pila. (size) Apilar: se aade un elemento a la pila.(push) Desapilar: se elimina el elemento frontal de la pila.(pop) Cima: devuelve el elemento que esta en la cima de la pila. (top o peek) Vaca: devuelve cierto si la pila est vaca o falso en caso contrario (empty).
Implementacin
Un requisito tpico de almacenamiento de una pila de n elementos es O(n). El requisito tpico de tiempo de O(1) las operaciones tambin son fciles de satisfacer con un array o con listas enlazadas simples. La biblioteca de plantillas de C++ estndar proporciona una "pila" clase templated que se limita a slo apilar/desapilar operaciones. Java contiene una biblioteca de la clase Pila que es una especializacin de Vector. Esto podra ser considerado como un defecto, porque el diseo heredado get () de Vector mtodo LIFO ignora la limitacin de la Pila. Estos son ejemplos sencillos de una pila con las operaciones descritas anteriormente (pero no hay comprobacin de errores). Implementacin en Python class Stack(object): def __init__(self): self.stack_pointer = None def push(self, element): self.stack_pointer = Node(element, self.stack_pointer) def pop(self): e = self.stack_pointer.element self.stack_pointer = self.stack_pointer.next return e def peek(self): return self.stack_pointer.element def __len__(self): i = 0 sp = self.stack_pointer
Pila (informtica) while sp: i += 1 sp = sp.next return i class Node(object): def __init__(self, element=None, next=None): self.element = element self.next = next if __name__ == '__main__': # small use example s = Stack() for i in range(10):s.push(i) for i in range(len(s)):print(s.pop()) Implementacin en Maude La PilaNV es la pila no vaca, que diferenciamos de la pila normal a la hora de tomar en cuenta errores. El elemento X representa el tipo de valor que puede contener la pila: entero, carcter, registro, etc. fmod PILA-GENRICA {X :: TRIV} is sorts Pila{X} PilaNV{X}. subsorts PilaNV{X} < Pila{X}. ***generadores: op crear: -> Pila {X} [ctor]. op apilar : X$Elt Pila{X} -> PilaNV{X} [ctor]. ***constructores op desapilar : Pila{X} -> Pila{X}. ***selectores op cima : PilaNV{X} -> X$Elt. ***variables var P : Pila{X}. var E : X$Elt. ***ecuaciones eq desapilar (crear) = crear. eq desapilar(apilar(E, P)) = P. eq cima(apilar(E, P)) = E. endfm
34
Pila (informtica) Implementacin en Visual Basic Public Class Stack Private p_index As Integer Private list As New ArrayList Public Sub New() p_index = -1 End Sub ReadOnly Property count Get Return list.Count End Get End Property Public Sub push(ByVal value As Object) list.Add(value) p_index += 1 End Sub Public Function pop() As Object Dim obj As Object = list.Item(p_index) list.RemoveAt(p_index) p_index -= 1 Return obj End Function Public Sub clear() list.Clear() p_index = -1 End Sub Public Function peek() As Object Return list.Item(p_index) End Function End Class En C++ #ifndef PILA #define PILA // define la pila
35
Pila (informtica) struct Nodo { T elemento; Nodo* siguiente; // coloca el nodo en la segunda posicion }* ultimo; unsigned int elementos; public: Pila() { elementos = 0; } ~Pila() { while (elementos != 0) pop(); } void push(const T& elem) { Nodo* aux = new Nodo; aux->elemento = elem; aux->siguiente = ultimo; ultimo = aux; ++elementos; } void pop() { Nodo* aux = ultimo; ultimo = ultimo->siguiente; delete aux; --elementos; } T cima() const { return ultimo->elemento; } bool vacia() const { return elementos == 0; } unsigned int altura() const { return elementos; } };
36
#endif
Pila (informtica) Implementacin en Java public class Nodo<tipo> { public tipo dato; private Nodo<tipo> siguiente; public Nodo(tipo Dato) { dato = Dato; siguiente = null; } public void conectar(Nodo<tipo> elSiguiente) { siguiente = elSiguiente; } public Nodo<tipo> getSiguiente() { return siguiente; } } public class Pila<tipo> { Nodo<tipo> cima; public Pila() { cima = null; } public int tamano() { Nodo<tipo> lectorAuxiliar = cima; int contadorDeDatos = 0; while (lectorAuxiliar != null) { contadorDeDatos++; lectorAuxiliar = lectorAuxiliar.getSiguiente(); } return contadorDeDatos; } public void apilar(tipo datoNuevo) { Nodo<tipo> nuevo = new Nodo<tipo>(datoNuevo); nuevo.conectar(cima); cima = nuevo; } public tipo desapilar() { tipo dato = cima.dato; cima = cima.getSiguiente(); return dato; }
37
Pila (informtica) public tipo getCima() { return cima.dato; } public boolean estaVacia() { return cima == null; } public String toString() { Nodo<tipo> lectorAuxiliar = cima; String respuesta = "IN/OUT <->"; while (lectorAuxiliar != null) { respuesta += " [" + lectorAuxiliar.dato.toString() + "] "; lectorAuxiliar = lectorAuxiliar.getSiguiente(); } return respuesta; } }
38
Pilas Hardware
Un uso muy comn de las pilas a nivel de arquitectura hardware es la asignacin de memoria.
Pila (informtica) Por ejemplo, una pila puede comenzar en una posicin de la memoria de mil, y ampliar por debajo de las direcciones, en cuyo caso, los nuevos datos se almacenan en lugares que van por debajo de 1000, y el puntero de pila se decrementa cada vez que un nuevo elemento se agrega. Cuando un tema es eliminado de la pila, el puntero de pila se incrementa. Los punteros de pila pueden apuntar al origen de una pila o de un nmero limitado de direcciones, ya sea por encima o por debajo del origen (dependiendo de la direccin en que crece la pila), sin embargo el puntero de pila no puede cruzar el origen de la pila. En otras palabras, si el origen de la pila est en la direccin 1000 y la pila crece hacia abajo (hacia las direcciones 999, 998, y as sucesivamente), el puntero de pila nunca debe ser incrementado ms all de 1000 (para 1001, 1002, etc.) Si un desapilar operacin en la pila hace que el puntero de pila se deje atrs el origen de la pila, una pila se produce desbordamiento. Si una operacin de apilar hace que el puntero de pila incremente o decremente ms all del mximo de la pila, en una pila se produce desbordamiento. La pila es visualizada ya sea creciente de abajo hacia arriba (como pilas del mundo real), o, con el mximo elemento de la pila en una posicin fija, o creciente, de izquierda a derecha, por lo que el mximo elemento se convierte en el mximo a "la derecha". Esta visualizacin puede ser independiente de la estructura real de la pila en la memoria. Esto significa que rotar a la derecha es mover el primer elemento a la tercera posicin, la segunda a la primera y la tercera a la segunda. Aqu hay dos equivalentes visualizaciones de este proceso: Manzana Pltano Fresa Fresa Pltano Manzana ==rotar a la izquierda==> ==rotar a la derecha==> Pltano Fresa Manzana Manzana Fresa Pltano
39
Una pila es normalmente representada en los ordenadores por un bloque de celdas de memoria, con los "de abajo" en una ubicacin fija, y el puntero de pila de la direccin actual de la "cima" de clulas de la pila. En la parte superior e inferior se utiliza la terminologa con independencia de que la pila crece realmente a la baja de direcciones de memoria o direcciones de memoria hacia mayores. Apilando un elemento en la pila,se ajusta el puntero de pila por el tamao de elementos (ya sea decrementar o incrementar, en funcin de la direccin en que crece la pila en la memoria), que apunta a la prxima celda, y copia el nuevo elemento de la cima en rea de la pila. Dependiendo de nuevo sobre la aplicacin exacta, al final de una operacin de apilar, el puntero de pila puede sealar a la siguiente ubicacin no utilizado en la pila, o tal vez apunte al mximo elemento de la pila. Si la pila apunta al mximo elemento de la pila, el puntero de pila se actualizar antes de que un nuevo elemento se apile, si el puntero que apunta a la prxima ubicacin disponible en la pila, que se actualizar despus de que el mximo elemento se apile en la pila. Desapilando es simplemente la inversa de apilar. El primer elemento de la pila es eliminado y el puntero de pila se actualiza, en el orden opuesto de la utilizada en la operacin de apilar.
Pila (informtica)
40
Soporte de Hardware
Muchas CPUs tienen registros que se pueden utilizar como punteros de pila. Algunos, como el Intel x86, tienen instrucciones especiales que implcitamente el uso de un registro dedicado a la tarea de ser un puntero de pila. Otros, como el DEC PDP-11 y de la familia 68000 de Motorola tienen que hacer frente a los modos de hacer posible la utilizacin de toda una serie de registros como un puntero de pila. La serie Intel 80x87 numrico de coprocessors tiene un conjunto de registros que se puede acceder ya sea como una pila o como una serie de registros numerados. Algunos microcontroladores, por ejemplo algunos PICs, tienen un fondo fijo de pila que no es directamente accesible. Tambin hay una serie de microprocesadores que aplicar una pila directamente en el hardware: Computer vaqueros MuP21 Harris RTX lnea Novix NC4016 Muchas pilas basadas en los microprocesadores se utilizan para aplicar el lenguaje de programacin Forth en el nivel de microcdigo. Pila tambin se utilizaron como base de una serie de mainframes y miniordenadores. Esas mquinas fueron llamados pila de mquinas, el ms famoso es el Burroughs B5000
Soporte de Software
En programas de aplicacin escrito en un lenguaje de alto nivel, una pila puede ser implementada de manera eficiente, ya sea usando vectores o listas enlazadas. En LISP no hay necesidad de aplicar la pila, puesto que las funciones apilar y desapilar estn disponibles para cualquier lista. Adobe PostScript tambin est diseada en torno a una pila que se encuentra directamente visible y manipuladas por el programador. El uso de las pilas est muy presente en el desarrollo de software por ello la importancia de las pilas como tipo abstracto de datos.
41
El resultado final, 15, se encuentra en la parte superior de la pila al final del clculo.
Seguridad
La seguridad a la hora de desarrollar software usando estructuras de datos de tipo pila es un factor a tener en cuenta debido a ciertas vulnerabilidad que un uso incorrecto de stas puede originar en la seguridad de nuestro software o en la seguridad del propio sistema que lo ejecuta. Por ejemplo, algunos lenguajes de programacin usan una misma pila para almacenar los datos para un procedimientos y el link que permite retornar a su invocador. Esto significa que el programa introduce y extrae los datos de la misma pila en la que se encuentra informacin crtica con las direcciones de retorno de las llamadas a procedimiento, supongamos que al introducir datos en la pila lo hacemos en una posicin errnea de manera que introducimos una datos de mayor tamao al soportado por la pila corrompiendo as
Pila (informtica) las llamadas a procedimientos provocariamos un fallo en nuestro programa. sta tcnica [1] usada de forma maliciosa (es similar, pero en otro mbito al buffer overflow) permitira a un atacante modificar el funcionamiento normal de nuestro programa y nuestro sistema, y es al menos una tcnica til si no lo evitamos en lenguajes muy populares como el ejemplo C++.
42
Referencias
[1] http:/ / www. cs. ucla. edu/ ~palsberg/ paper/ sas03. pdf
Cola (informtica)
Usos concretos de la cola
La particularidad de una estructura de datos de cola es el hecho de que slo podemos acceder al primer y al ltimo elemento de la estructura. As mismo, los elementos slo se pueden eliminar por el principio y slo se pueden aadir por el final de la cola.
Ejemplos de colas en la vida real seran: personas comprando en un supermercado, esperando para entrar a ver un partido de bisbol, esperando en el cine para ver una pelcula, una pequea peluquera, etc. La idea esencial es que son todos lneas de espera.
Informacin adicional
En caso de estar vaca, borrar un elemento sera imposible hasta que no se aade un nuevo elemento. A la hora de aadir un elemento podramos darle una mayor importancia a unos elementos que a otros (un cargo VIP) y para ello se crea un tipo de cola especial que es la cola de prioridad. (Ver cola de prioridad).
Cola (informtica)
43
Operaciones Bsicas
Crear: se crea la cola vaca. Encolar (aadir, entrar, insertar): se aade un elemento a la cola. Se aade al final de esta. Desencolar (sacar, salir, eliminar): se elimina el elemento frontal de la cola, es decir, el primer elemento que entr. Frente (consultar, front): se devuelve el elemento frontal de la cola, es decir, el primer elemento que entr.
Implementaciones
Colas en Maude
La ColaNV es la cola no vaca, que diferenciamos de la cola normal a la hora de tomar en cuenta errores. A su vez, el elemento X representa el tipo de valor que puede contener la cola: entero, carcter, registro....
fmod COLA {X :: TRIV} is sorts ColaNV{X} Cola{X} . subsort ColaNV{X} < Cola{X} . *** generadores op crear : -> Cola{X} [ctor] . op encolar : X$Elt Cola{X} -> ColaNV {X} [ctor] . *** constructores op desencolar : Cola{X} -> Cola{X} . *** selectores op frente : ColaNV{X} -> X$Elt . *** variables var C : ColaNV{X} . vars E E2 : X$Elt . *** ecuaciones eq desencolar(crear) = crear . eq desencolar(encolar(E, crear)) = crear . eq desencolar(encolar(E, C)) = encolar(E, desencolar(C)) . eq frente(encolar(E, crear)) = E . eq frente(encolar(E, C)) = frente(C) . endfm
Especificacin de una cola de colas de enteros en Maude: view VInt from TRIV to INT is sort Elt to Int . endv view VColaInt from TRIV to COLA{VInt} is
Cola (informtica)
sort Elt to Cola{VInt} . endv fmod COLA-COLAS-INT is protecting INT . protecting COLA{VColaInt} . *** operaciones propias de la cola de colas de enteros op encolarInt op frenteInt *** variables var CCNV : ColaNV{VColaInt} . var CC var CE var E : Cola{VColaInt} . : Cola{VInt} . : Int . : Int ColaNV{VColaInt} -> ColaNV{VColaInt} . -> Cola{VColaInt} . -> [Int] . : ColaNV{VColaInt} op desencolarInt : Cola{VColaInt}
44
*** ecuaciones eq encolarInt(E, encolar(CE, CC)) = encolar(encolar(E, CE), CC) . eq desencolarInt (encolar(CE, crear)) = encolar(desencolar(CE), crear) . eq desencolarInt (encolar(CE, CCNV)) = encolar(CE, desencolarInt(CCNV)) . eq frenteInt(CCNV) = frente(frente(CCNV)) . endfm
Colas en C++
#ifndef COLA #define COLA // Define la cola template <class T> class Cola{ private: struct Nodo{ T elemento; struct Nodo* siguiente; posicin }* primero; struct Nodo* ultimo; unsigned int elementos; public: Cola(){ elementos = 0; } cout<<" Hola Mundo! "<<endl; cout<<" Hello, World! "<<endl; ~Cola(){
Cola (informtica) while (elementos != 0) pop(); } void push(const T& elem){ Nodo* aux = new Nodo; aux->elemento = elem; if (elementos == 0) primero = aux; else ultimo->siguiente = aux; ultimo = aux; ++elementos; } void pop(){ Nodo* aux = primero; primero = primero->siguiente; delete aux; --elementos; } T consultar() const{ return primero->elemento; } bool vacia() const{ return elementos == 0; } unsigned int size() const{ return elementos; } }; #endif
45
Colas en JAVA
public void inserta(Elemento x) { Nodo Nuevo; Nuevo = new Nodo(x, null); if (NodoCabeza == null) { NodoCabeza = Nuevo; } else { NodoFinal.Siguiente = Nuevo; } NodoFinal = Nuevo; } public Elemento cabeza() throws IllegalArgumentException { if (NodoCabeza == null) { throw new IllegalArgumentException(); } else { return NodoCabeza.Info; } }
Cola (informtica)
46
public Cola() { // Devuelve una Cola vaca NodoCabeza = null; NodoFinal = null; }
Colas en C#
public partial class frmPrincipal { // Variables globales public static string[] Cola; public static int Frente; public static int Final; public static int N; [STAThread] public static void Main(string[] args) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new frmPrincipal()); } public frmPrincipal() { // Constructor
InitializeComponent(); Cola = new string[5]; N = 4; Frente = -1; Final = -1; } void CmdInsercionClick(object sender, System.EventArgs e) { frmInsercion Insercion = new frmInsercion(); Insercion.Show(); } void CmdRecorridoClick(object sender, System.EventArgs e) { frmRecorrido Recorrido = new frmRecorrido(); Recorrido.Show(); } // Arreglo lineal de 5
Cola (informtica) void CmdBusquedaClick(object sender, EventArgs e) { frmBusqueda Busqueda = new frmBusqueda(); Busqueda.Show(); } void CmdEliminacionClick(object sender, EventArgs e) { frmEliminacion Eliminar = new frmEliminacion(); Eliminar.Show(); } } Algoritmo Insertar(Cola, N, Frente, Final, Elemento) void CmdInsertarClick(object sender, System.EventArgs e) { elemento = txtInsercion.Text; // Se verifica que haya espacio en la Cola if (frmPrincipal.Frente == 0 && frmPrincipal.Final == frmPrincipal.N) { MessageBox.Show("La Cola esta llena"); return; } if (frmPrincipal.Frente == frmPrincipal.Final + 1) { MessageBox.Show("La Cola esta llena"); return; } // Si la cola esta vacia se inicializan punteros if (frmPrincipal.Frente == -1) { frmPrincipal.Frente = 0; frmPrincipal.Final = 0; } else if (frmPrincipal.Final == frmPrincipal.N) { frmPrincipal.Final = 0; } else { frmPrincipal.Final = frmPrincipal.Final + 1; } // Se agrega elemento a la Cola frmPrincipal.Cola[frmPrincipal.Final] = elemento; txtInsercion.Text = "";
47
Cola (informtica)
48
} Algoritmo Eliminacin (Cola, Frente, Final, N) void CmdEliminarClick(object sender, EventArgs e) { if (frmPrincipal.Frente == -1) { MessageBox.Show("Cola Vacia"); return; } string elemento = frmPrincipal.Cola[frmPrincipal.Frente]; // si la cola tiene un solo elemento if (frmPrincipal.Frente == frmPrincipal.Final) { frmPrincipal.Frente = -1; frmPrincipal.Final = -1; } else if (frmPrincipal.Frente == frmPrincipal.N) { frmPrincipal.Frente = 0; } else { frmPrincipal.Frente = frmPrincipal.Frente + 1; } lsEliminado.Items.Add(elemento); } Otra forma de programar una cola en Java Por Jorge Herrera C import java.util.*; public class Cola <Tipo>{ private List<Tipo> cola; public Cola(){ cola=new ArrayList<Tipo>(); } public boolean colaVacia(){ return cola.isEmpty(); } public void agregar(Tipo elemento){ cola.add(elemento); } public Tipo sacar(){
Cola (informtica) if(colaVacia())return null; Tipo elemento=cola.get(0); cola.remove(0); return elemento; } }// Fin de la clase Cola A continuacion un ejemplo de una clase manejadora de la clase Cola public class Manejador { public static void main(String[] args) { Cola cola=new <Integer>Cola(); System.out.println(cola.sacar()); cola.agregar(23); cola.agregar(24); cola.agregar(25); while(!cola.colaVacia()){ System.out.println(cola.sacar()); } Cola nombres=new <String>Cola(); nombres.agregar("Jorge"); nombres.agregar("Raquel"); nombres.agregar("Mayra Alejandra"); while(!nombres.colaVacia()){ System.out.println(nombres.sacar()); } } }// Fin de la clase Manejadora
49
Tipos de colas
Colas circulares (anillos): en las que el ltimo elemento y el primero estn unidos. Colas de prioridad: En ellas, los elementos se atienden en el orden indicado por una prioridad asociada a cada uno. Si varios elementos tienen la misma prioridad, se atendern de modo convencional segn la posicin que ocupen. Hay 2 formas de implementacin: 1. Aadir un campo a cada nodo con su prioridad. Resulta conveniente mantener la cola ordenada por orden de prioridad. 2. Crear tantas colas como prioridades haya, y almacenar cada elemento en su cola. Bicolas: son colas en donde los nodos se pueden aadir y quitar por ambos extremos; se les llama DEQUE (Double Ended QUEue). Para representar las bicolas lo podemos hacer con un array circular con Inicio y Fin que apunten a cada uno de los extremos. Hay variantes: Bicolas de entrada restringida: Son aquellas donde la insercin slo se hace por el final, aunque podemos eliminar al inicio al final. Bicolas de salida restringida: Son aquellas donde slo se elimina por el final, aunque se puede insertar al inicio y al final.
50
rboles de bsqueda
rbol (informtica)
En ciencias de la informtica, un rbol es una estructura de datos ampliamente usada que imita la forma de un rbol (un conjunto de nodos conectados). Un nodo es la unidad sobre la que se construye el rbol y puede tener cero o ms nodos hijos conectados a l. Se dice que un nodo es padre de un nodo si existe un enlace desde hasta (en ese caso, tambin decimos que es hijo de ). Slo puede haber un nico nodo sin padres, que llamaremos raz. Un nodo que no tiene hijos se conoce como hoja. Los dems nodos (tienen padre y uno o varios hijos) se les conoce como rama.
Definicin
Formalmente, podemos definir un rbol de la siguiente forma: Caso base: un rbol con slo un nodo (es a la vez raz del rbol y hoja). Un nuevo rbol a partir de un nodo una de las races de los nodo , los nodos y rboles de races con y cada nodos tiene como raz el y el conjunto de nodos hoja est formado por la unin
elementos cada uno, puede construirse estableciendo una relacin padre-hijo entre rboles. El rbol resultante de son los hijos de
de los conjuntos hojas iniciales. A cada uno de los rboles se les denota ahora subrboles de la raz. Una sucesin de nodos del rbol, de forma que entre cada dos nodos consecutivos de la sucesin haya una relacin de parentesco, decimos que es un rbol recorrido. Existen dos recorridos tpicos para listar los nodos de un rbol: en profundidad y en anchura. En el primer caso, se listan los nodos expandiendo el hijo actual de cada nodo hasta llegar a una hoja, donde se vuelve al nodo anterior probando por el siguiente hijo y as sucesivamente. En el segundo, por su parte, antes de listar los nodos de nivel (a distancia aristas de la raz), se deben haber listado todos los de nivel . Otros recorridos tpicos del rbol son preorden, postorden e inorden: El recorrido en preorden, tambin llamado orden previo consiste en recorrer en primer lugar la raz y luego cada uno de los hijos en orden previo. El recorrido en inorden, tambin llamado orden simtrico (aunque este nombre slo cobra significado en los rboles binarios) consiste en recorrer en primer lugar , luego la raz y luego cada uno de los hijos en orden simtrico. El recorrido en postorden, tambin llamado orden posterior consiste en recorrer en primer lugar cada uno de los hijos en orden posterior y por ltimo la raz. Finalmente, puede decirse que esta estructura es una representacin del concepto de rbol en teora de grafos. Un rbol es un grafo conexo y acclico.
rbol (informtica)
51
Tipos de rboles
rboles Binarios rbol de bsqueda binario auto-balanceable rboles AVL rboles Rojo-Negro rbol AA rboles Multicamino rboles B (rboles de bsqueda multicamino autobalanceados) rbol-B+ rbol-B*
Ejemplo de rbol (binario).
Aadir un subrbol (algunas veces llamada injertar). Encontrar la raz de cualquier nodo. Por su parte, la representacin puede realizarse de diferentes formas. Las ms utilizadas son:
Las rotaciones en rboles binarios son operaciones internas comunes utilizadas para mantener el balance perfecto (o casi perfecto) del rbol binario. Un rbol balanceado permite operaciones en tiempo logartmico.
Representar cada nodo como una variable en el heap, con punteros a sus hijos y a su padre. Representar el rbol con un array donde cada elemento es un nodo y las relaciones padre-hijo vienen dadas por la posicin del nodo en el array.
rbol binario
52
rbol binario
En ciencias de la computacin, un rbol binario es una estructura de datos en la cual cada nodo siempre tiene un hijo izquierdo y un hijo derecho. No pueden tener ms de dos hijos (de ah el nombre "binario"). Si algn hijo tiene como referencia a null, es decir que no almacena ningn dato, entonces este es llamado un nodo externo. En el caso contrario el hijo es llamado un nodo interno. Usos comunes de los rboles binarios son los rboles binarios de bsqueda, los montculos binarios y Codificacin de Huffman.
Un rbol binario sencillo de tamao 9, 4 niveles y altura 3 (altura = mximo nivel - 1), con un nodo raz cuyo valor es 2.
Un rbol binario lleno es un rbol en el que cada nodo tiene cero o dos hijos. Un rbol binario perfecto es un rbol binario lleno en el que todas las hojas (vrtices con cero hijos) estn a la misma profundidad (distancia desde la raz, tambin llamada altura). A veces un rbol binario perfecto es denominado rbol binario completo. Otros definen un rbol binario completo como un rbol binario lleno en el que todas las hojas estn a profundidad n o n-1, para alguna n. Un rbol binario es un rbol en el que ningn nodo puede tener ms de dos subrboles. En un rbol binario cada nodo puede tener cero, uno o dos hijos (subrboles). Se conoce el nodo de la izquierda como hijo izquierdo y el nodo de la derecha como hijo derecho.
Implementacin en C
Un rbol binario puede declararse de varias maneras. Algunas de ellas son: Estructura con manejo de memoria dinmica, siendo el puntero que apunta al rbol de tipo tArbol: typedef struct nodo { int clave; struct nodo *izdo, *dcho; }Nodo; Estructura con arreglo indexado: typedef struct tArbol {
rbol binario int clave; tArbol hIzquierdo, hDerecho; } tArbol; tArbol rbol[NUMERO_DE_NODOS]; En el caso de un rbol binario casi-completo (o un rbol completo), puede utilizarse un sencillo arreglo de enteros con tantas posiciones como nodos deba tener el rbol. La informacin de la ubicacin del nodo en el rbol es implcita a cada posicin del arreglo. As, si un nodo est en la posicin i, sus hijos se encuentran en las posiciones 2i+1 y 2i+2, mientras que su padre (si tiene), se encuentra en la posicin truncamiento((i-1)/2) (suponiendo que la raz est en la posicin cero). Este mtodo se beneficia de un almacenamiento ms compacto y una mejor localidad de referencia, particularmente durante un recorrido en preorden. La estructura para este caso sera por tanto: int rbol[NUMERO_DE_NODOS];
53
rbol binario
FIN-MIENTRAS
54
Recorrido en postorden En este caso se trata primero el subrbol izquierdo, despus el derecho y por ltimo el nodo actual. Otra forma para entender el recorrido con este metodo seria seguir el orden: nodo izquierda, nodo derecha, nodo raz. En el rbol de la figura el recorrido en postorden sera: 2, 5, 11, 6, 7, 4, 9, 5 y 2. void postorden(tArbol *a) { if (a != NULL) { postorden(a->hIzquiedo); postorden(a->hDerecho); tratar(a); } } Recorrido en enorden En este caso se trata primero el subrbol izquierdo, despus el nodo actual y por ltimo el subrbol derecho. En un ABB este recorrido dara los valores de clave ordenados de menor a mayor. Otra forma para entender el recorrido con este metodo seria seguir el orden: nodo izquierda,nodo raz,nodo derecha. En el rbol de la figura el recorrido en enorden sera: 2, 7, 5, 6, 11, 2, 5, 4, 9. Esquema de implementacin: void enorden(tArbol *a) { if (a != NULL) { enorden(a->hIzquierdo); tratar(a); enorden(a->hDerecho); } }
rbol binario
55
if (vacio(A)) // si el rbol esta vacio, salimos return; cola_inicializa(&cola_nodos); // obvio, y necesario cola_enqueue(A, &cola_nodos); // se encola la raz while (!vacia(&cola_nodos)) { // mientras la cola no se vacie se realizara el recorrido nodo_actual = cola_dequeue(&cola_nodos) // de la cola saldran los nodos ordenados por nivel printf("%c,", nodo_actual->info); // se "procesa" el nodo donde va el recorrido, en este caso se imprime if (nodo_actual->izq != null) // si existe, ponemos el hijo izquierdo en la cola cola_enqueue(nodo_actual->izq, &cola_nodos); if (nodo_actual->der != null) // si existe, ponemos el hijo derecho en la cola cola_enqueue(nodo_actual->der, &cola_nodos); } // al vaciarse la cola se han visitado todos los nodos del rbol }
rbol binario acuerdo con preorden es , lo cual es una incongruencia, de esa forma sabemos que el otro es la raz.
56
Entonces marcamos la raz en el recorrido inorden: Preorden Inorden Postorden El recorrido inorden, es un recorrido de los rboles binarios en los que se empieza desde el nodo que se encuentra ms a la izquierda de todos, sigue con la raz y termina con los nodos del lado derecho, entonces, como en el recorrido inorden ya encontramos la raz, la parte izquierda representa el subrbol izquierdo y la parte derecha representa el subrbol derecho. En los recorridos tenemos 5 nodos a la izquierda del y a la derecha se encuentran 3 valores, entonces podemos crear los recorridos para el subrbol izquierdo y el subrbol derecho
Subrbol derecho Preorden Inorden Postorden Subrbol derecho Preorden Inorden Postorden
Se sigue repitiendo el proceso hasta encontrar todos los nodos del rbol, en este punto la siguiente raz izquierda es el y la raz derecha el . Cuando se llegan a nodos en los que nicamente cuentan con una rama es necesario saber que rama es la derecha y cul es la izquierda (para algunos rboles con balanceo como los AVL), por ejemplo siguiendo la rama de la derecha partiendo de que el es la raz el recorrido inorden es entonces el siguiente nodo va a la derecha, no hay nodo a la izquierda, despus, los recorridos para el subrbol son: Preorden Inorden Postorden Finalmente el siguiente nodo se coloca a la izquierda del .
Este mtodo es 100% efectivo cuando no existen nodos repetidos, cuando los nodos se repiten la complejidad aumenta para poder descubrir cul es el nodo raz en el recorrido inorden.
rbol binario
57
Los rboles binarios tambin pueden ser almacenados como una estructura de datos implcita en vectores, y si el rbol es un rbol binario completo, este mtodo no desaprovecha el espacio en memoria. Tomaremos como notacin la siguiente: si un nodo tiene un ndice i, sus hijos se encuentran en ndices 2i + 1 y 2i + 2, mientras que sus padres (si los tiene) se encuentra en el ndice (partiendo de que la raz tenga ndice cero). Este mtodo tiene como
ventajas el tener almacenados los datos de forma ms compacta y por tener una forma ms rpida y eficiente de localizar los datos en particular durante un preoden transversal. Sin embargo, desperdicia mucho espacio en memoria.
rbol binario
58
El rbol binario puede ser pensado como el rbol original inclinado hacia los lados, con los bordes negros izquierdos representando el primer hijo y los azules representado los siguientes hermanos. Las hojas del rbol de la izquierda seran escritas en Lisp como: (((N O) I J) C D ((P) (Q)) F (M)) Que se ejecutar en la memoria como el rbol binario de la derecha, sin ningn tipo de letras en aquellos nodos que tienen un hijo izquierdo.
Enlaces externos
rbol binario de bsqueda en PHP [1]
Referencias
[1] http:/ / mmengineer. blogspot. com/ 2007/ 10/ aboles-binarios-de-busqueda-php. html
59
Descripcin
Un rbol binario de bsqueda (ABB) es un rbol binario definido de la siguiente forma: rbol binario la mayora de los rboles binarios son de bsqueda Un rbol binario no vaco, de raz R, es un rbol binario de bsqueda si: En caso de tener subrbol izquierdo, la raz R debe ser mayor que el valor mximo almacenado en el subrbol izquierdo, y que el subrbol izquierdo sea un rbol binario de bsqueda. En caso de tener subrbol derecho, la raz R debe ser menor que el valor mnimo almacenado en el subrbol derecho, y que el subrbol derecho sea un rbol binario de bsqueda. Para una fcil comprensin queda resumido en que es un rbol binario que cumple que el subrbol izquierdo de cualquier nodo (si no est vaco) contiene valores menores que el que contiene dicho nodo, y el subrbol derecho (si no est vaco) contiene valores mayores. Para estas definiciones se considera que hay una relacin de orden establecida entre los elementos de los nodos. Que cierta relacin est definida, o no, depende de cada lenguaje de programacin. De aqu se deduce que puede haber distintos rboles binarios de bsqueda para un mismo conjunto de elementos. La altura h en el peor de los casos siempre el mismo tamao que el nmero de elementos disponibles. Y en el mejor de los casos viene dada por la expresin , donde ceil indica redondeo por exceso. El inters de los rboles binarios de bsqueda (ABB) radica en que su recorrido en inorden proporciona los elementos ordenados de forma ascendente y en que la bsqueda de algn elemento suele ser muy eficiente. Dependiendo de las necesidades del usuario que trate con una estructura de este tipo, se podr permitir la igualdad estricta en alguno, en ninguno o en ambos de los subrboles que penden de la raz. Permitir el uso de la igualdad provoca la aparicin de valores dobles y hace la bsqueda ms compleja. Un rbol binario de bsqueda no deja de ser un caso particular de rbol binario, as usando la siguiente especificacin de rbol binario en maude: fmod ARBOL-BINARIO {X :: TRIV}is sorts ArbolBinNV{X} ArbolBin{X} . subsort ArbolBinNV{X} < ArbolBin{X} . *** generadores
rbol binario de bsqueda op crear : -> ArbolBin{X} [ctor] . op arbolBin : X$Elt ArbolBin{X} ArbolBin{X} -> ArbolBinNV{X} [ctor] . endfm podemos hacer la siguiente definicin para un rbol binario de bsqueda (tambin en maude): fmod ARBOL-BINARIO-BUSQUEDA {X :: ORDEN} is protecting ARBOL-BINARIO{VOrden}{X} . sorts ABB{X} ABBNV{X} . subsort ABBNV{X} < ABB{X} . subsort ABB{X} < ArbolBin{VOrden}{X} . subsort ABBNV{X} < ArbolBinNV{VOrden}{X} . *** generadores op crear : -> ArbolBin{X} [ctor] . op arbolBin : X$Elt ArbolBin{X} ArbolBin{X} -> ArbolBinNV{X} [ctor] . endfm con la siguiente teora de orden: fth ORDEN is protecting BOOL . sort Elt . *** operaciones op _<_ : Elt Elt -> Bool . endfth para que un rbol binario pertenezca al tipo rbol binario de bsqueda debe cumplir la condicin de ordenacin siguiente que ira junto al mdulo ARBOL-BINARIO-BUSQUEDA: var R : X$Elt . vars INV DNV : ABBNV{X} . vars I D : ABB{X} . mb crear : ABB{X} . mb arbolBin(R, crear, crear) : ABBNV{X} . cmb arbolBin(R, INV, crear) : ABBNV{X} if R > max(INV) . cmb arbolBin(R, crear, DNV) : ABBNV{X} if R < min(DNV) . cmb arbolBin(R, INV, DNV) : ABBNV{X} if (R > max(INV)) and (R < min(DNV)) . ops min max : ABBNV{X} -> X$Elt . eq min(arbolBin(R, crear, D)) = R . eq min(arbolBin(R, INV, D)) = min(INV) . eq max(arbolBin(R, I, crear)) = R . eq max(arbolBin(R, I, DNV)) = max(DNV) .
60
Implementacin en Python
class nodo: izq , der, dato = None, None, 0 def __init__(self, dato): # crea un nodo self.izq = None
rbol binario de bsqueda self.der = None self.dato = dato class arbolBinario: def __init__(self): # inicializa la raiz self.raiz = None def agregarNodo(self, dato): # crea un nuevo nodo y lo devuelve return nodo(dato) def insertar(self, raiz, dato): # inserta un dato nuevo en el rbol if raiz == None: # si no hay nodos en el rbol lo agrega return self.agregarNodo(dato) else: # si hay nodos en el rbol lo recorre if dato <= raiz.dato: # si el dato ingresado es menor que el dato guardado va al subrbol izquierdo raiz.izq = self.insertar(raiz.izq, dato) else: # si no, procesa el subrbol derecho raiz.der = self.insertar(raiz.der, dato) return raiz
61
Operaciones
Todas las operaciones realizadas sobre rboles binarios de bsqueda estn basadas en la comparacin de los elementos o clave de los mismos, por lo que es necesaria una subrutina, que puede estar predefinida en el lenguaje de programacin, que los compare y pueda establecer una relacin de orden entre ellos, es decir, que dados dos elementos sea capaz de reconocer cual es mayor y cual menor. Se habla de clave de un elemento porque en la mayora de los casos el contenido de los nodos ser otro tipo de estructura y es necesario que la comparacin se haga sobre algn campo al que se denomina clave.
Bsqueda
La bsqueda consiste acceder a la raz del rbol, si el elemento a localizar coincide con ste la bsqueda ha concluido con xito, si el elemento es menor se busca en el subrbol izquierdo y si es mayor en el derecho. Si se alcanza un nodo hoja y el elemento no ha sido encontrado se supone que no existe en el rbol. Cabe destacar que la bsqueda en este tipo de rboles es muy eficiente, representa una funcin logartmica. El mximo nmero de comparaciones que necesitaramos para saber si un elemento se encuentra en un rbol binario de bsqueda estara entre [log2(N+1)] y N, siendo N el nmero de nodos. La bsqueda de un elemento en un ABB (rbol Binario de Bsqueda) se puede realizar de dos formas, iterativa o recursiva. Ejemplo de versin iterativa en el lenguaje de programacin C, suponiendo que estamos buscando una clave alojada en un nodo donde est el correspondiente "dato" que precisamos encontrar:
rbol binario de bsqueda data Buscar_ABB(abb t,clave k) { abb p; dato e; e=NULL; p=t; if (!estaVacio(p)) { while (!estaVacio(p) && (p->k!=k) ) { if (k < p->k) { p=p->l; } if (p->k < k) { p=p->r; } } if (!estaVacio(p) &&(p->d!=NULL) ) { e=copiaDato(p->d); } } return e; } Vase ahora la versin recursiva en ese mismo lenguaje: int buscar(tArbol *a, int elem) { if (a == NULL) { return 0; } else if (a->clave < elem) { return buscar(a->hDerecho, elem); } else if (a->clave > elem) { return buscar(a->hIzquierdo, elem); } else { return 1; } }
62
rbol binario de bsqueda Otro ejemplo en Python: def buscar(raiz, clave): # busca el valor clave dentro del arbol if raiz == None: print 'No se encuentra' else: # if clave == raiz.dato: print 'El valor ',clave,' se encuentra en el ABB' elif clave < raiz.dato: # lado izquierdo return buscar(raiz.izq, clave) else: # lado derecho return buscar(raiz.der, clave) En Pascal: Function busqueda(T:ABR, y: integer):ABR begin if (T=nil) or (^T.raiz=y) then busqueda:=T; else if (^T.raiz<y) then busqueda:=busqueda(^T.dch,y); else busqueda:=busqueda(^T.izq,y); end; Una especificacin en maude para la operacin de bsqueda quedara de la siguiente forma: op esta? : X$Elt ABB{X} -> Bool . var R R1 R2 : X$Elt . vars I D : ABB{X} . eq esta?(R, crear) = false . eq esta?(R1, arbolBin(R2, I, D)) = if R1 == R2 then true else if R1 < R2 then esta?(R1, I) else esta?(R1, D) fi fi .
63
64
Insercin
La insercin es similar a la bsqueda y se puede dar una solucin tanto iterativa como recursiva. Si tenemos inicialmente como parmetro un rbol vaco se crea un nuevo nodo como nico contenido el elemento a insertar. Si no lo est, se comprueba si el elemento dado es menor que la raz del rbol inicial con lo que se inserta en el subrbol izquierdo y si es mayor se inserta en el subrbol derecho.
Como en el caso de la bsqueda puede haber varias variantes a la hora de implementar la insercin en el TAD (Tipo Abstracto de Datos), y es la decisin a tomar cuando el elemento (o clave del elemento) a insertar ya se encuentra en el rbol, puede que ste sea modificado o que sea ignorada la insercin. Es obvio que esta operacin modifica el ABB perdiendo la versin anterior del mismo. A continuacin se muestran las dos versiones del algoritmo en pseudolenguaje, iterativa y recursiva, respectivamente. PROC InsertarABB(rbol:TABB; dato:TElemento) VARIABLES nuevonodo,pav,pret:TABB clavenueva:Tclave ele:TElemento INICIO nuevonodo <- NUEVO(TNodoABB) nuevonodo^.izq <- NULO nuevonodo^.der <- NULO nuevonodo^.elem <- dato SI ABBVaco (rbol) ENTONCES rbol <- nuevonodo ENOTROCASO clavenueva <- dato.clave pav <- rbol // Puntero Avanzado pret <- NULO // Puntero Retrasado MIENTRAS (pav <- NULO) HACER pret <- pav ele = pav^.elem SI (clavenueva < ele.clave ) ENTONCES pav <- pav^.izq EN OTRO CASO pav <- pav^.dch FINSI
rbol binario de bsqueda FINMIENTRAS ele = pret^.elem SI (clavenueva < ele.clave ) ENTONCES pret^.izq <- nuevonodo EN OTRO CASO pret^.dch <- nuevonodo FINSI FINSI FIN PROC InsertarABB(rbol:TABB; dato:TElemento) VARIABLES ele:TElemento INICIO SI (ABBVaco(rbol)) ENTONCES rbol <- NUEVO(TNodoABB) rbol^.izq <- NULO rbol^.der <- NULO rbol^.elem <- dato EN OTRO CASO ele = InfoABB(rbol) SI (dato.clave < ele.clave) ENTONCES InsertarABB(rbol^.izq, dato) EN OTRO CASO InsertarABB(rbol^.dch, dato) FINSI FINSI FIN Se ha podido apreciar la simplicidad que ofrece la versin recursiva, este algoritmo es la traduccin en C. El rbol es pasado por referencia para que los nuevos enlaces a los subrboles mantengan la coherencia. void insertar(tArbol **a, int elem) { if (*a == NULL) { *a = (tArbol *) malloc(sizeof(tArbol)); (*a)->clave = elem; (*a)->hIzquierdo = NULL; (*a)->hDerecho = NULL; } else if ((*a)->clave < elem) insertar(&(*a)->hDerecho, elem); else if ((*a)->clave > elem) insertar(&(*a)->hIzquierdo, elem); } En Python el mecanismo de insercin se define, por ejemplo, dentro de la clase que defina el ABB (ver ms arriba). Otro ejemplo en Pascal:
65
rbol binario de bsqueda Procedure Insercion(var T:ABR, y:integer) var ultimo:ABR; actual:ABR; nuevo:ABR; begin ultimo:=nil; actual:=T; while (actual<>nil) do begin ultimo:=actual; if (actual^.raiz<y) then actual:=actual^.dch else actual:=actual^.izq; end; new(nuevo); ^nuevo.raiz:=y; ^nuevo.izq:=nil; ^nuevo.dch:=nil; if ultimo=nil then T:=nuevo else if ultimo^.raiz<y then ultimo^.dch:=nuevo else ultimo^.izq:=nuevo; end; Vase tambin un ejemplo de algoritmo recursivo de insercin en un ABB en el lenguaje de programacin Maude:
op insertar : X$Elt ABB{X} -> ABBNV{X} . var R R1 R2 : X$Elt . vars I D : ABB{X} . eq insertar(R, crear) = arbolBin(R, crear, crear) . eq insertar(R1, arbolBin(R2, I, D)) = if R1 < R2 then arbolBin(R2, insertar(R1, I), D) else arbolBin(R2, I, insertar(R1, D)) fi .
66
La operacin de insercin requiere, en el peor de los casos, un tiempo proporcional a la altura del rbol.
67
Borrado
La operacin de borrado no es tan sencilla como las de bsqueda e insercin. Existen varios casos a tener en consideracin: Borrar un nodo sin hijos o nodo hoja: simplemente se borra y se establece a nulo el apuntador de su padre.
Nodo a eliminar 74
Borrar un nodo con un subrbol hijo: se borra el nodo y se asigna su subrbol hijo como subrbol de su padre.
Nodo a eliminar 70
Borrar un nodo con dos subrboles hijo: la solucin est en reemplazar el valor del nodo por el de su predecesor o por el de su sucesor en inorden y posteriormente borrar este nodo. Su predecesor en inorden ser el nodo ms a la derecha de su subrbol izquierdo (mayor nodo del subarbol izquierdo), y su sucesor el nodo ms a la izquierda de su subrbol derecho (menor nodo del subarbol derecho). En la siguiente figura se muestra cmo existe la posibilidad de realizar cualquiera de ambos reemplazos:
Nodo a eliminar 59
El siguiente algoritmo en C realiza el borrado en un ABB. El procedimiento reemplazar busca la mayor clave del subrbol izquierdo y la asigna al nodo a eliminar. void reemplazar(tArbol **a, tArbol **aux); /*Prototipo de la funcion ''reemplazar''*/ void borrar(tArbol **a, int elem) { tArbol *aux; if (*a == NULL) return; if ((*a)->clave < elem) borrar(&(*a)->hDerecho, elem); else if ((*a)->clave > elem) borrar(&(*a)->hIzquierdo, elem);
rbol binario de bsqueda else if ((*a)->clave == elem) { aux = *a; if ((*a)->hIzquierdo == NULL) *a = (*a)->hDerecho; else if ((*a)->hDerecho == NULL) *a = (*a)->hIzquierdo; else reemplazar(&(*a)->hIzquierdo, &aux); free(aux); } } void reemplazar(tArbol **a, tArbol **aux) { if ((*a)->hDerecho == NULL) { (*aux)->clave = (*a)->clave; *aux = *a; *a = (*a)->hIzquierdo; } else reemplazar(&(*a)->hDerecho, aux); } Otro ejemplo en Pascal. Procedure Borrar(var T:ABR, x:ABR) var aBorrar:ABR; anterior:ABR; actual:ABR; hijo:ABR; begin if (^x.izq=nil) or (^x.dch=nil) then aBorrar:=x; else aBorrar:=sucesor(T,x); actual:=T; anterior:=nil; while (actual<>aBorrar) do begin anterior:=actual; if (^actual.raiz<^aBorrar.raiz) then actual:=^actual.dch; else actual:=^actual.izq;
68
rbol binario de bsqueda end; if (^actual.izq=nil) then hijo:=^actual.dch; else hijo:=^actual.izq; if (anterior=nil) then T:=hijo; else if (^anterior.raiz<^actual.raiz) then ^anterior.dch:=hijo; else ^anterior.izq:=hijo; if (aBorrar<>x) then ^x.raiz:=^aBorrar.raiz; free(aBorrar); end; Vase tambin un ejemplo de algoritmo recursivo de borrado en un ABB en el lenguaje de programacin Maude, considerando los generadores crear y arbolBin. Esta especificacin hace uso de la componente clave a partir de la cual se ordena el rbol.
op eliminar : X$Elt ABB{X} -> ABB{X} . varS R M : X$Elt . vars I D : ABB{X} . vars INV DNV : ABBNV{X} . ops max min : ArbolBin{X} -> X$Elt . eq min(arbolBin(R, crear, D)) = R . eq max(arbolBin(R, I, crear)) = R . eq min(arbolBin(R, INV, D)) = min(INV) . eq max(arbolBin(R, I, DNV )) = max(DNV) . eq eliminar(M, crear) = crear . ceq eliminar(M, arbolBin(R, crear, D)) = D if M == clave(R) . ceq eliminar(M, arbolBin(R, I, crear)) = I if M == clave(R) . ceq eliminar(M, arbolBin(R, INV, DNV)) = arbolBin(max(INV), eliminar(clave(max(INV)), INV), DNV) if M == clave(R) . ceq eliminar(M, arbolBin(R, I, D)) = arbolBin(R, eliminar(M, I), D) if M < clave(R) . ceq eliminar(M, arbolBin(R, I, D)) = arbolBin(R, I, eliminar(M, D)) if clave(R) < M .
69
Otras Operaciones
Otra operacin sera por ejemplo comprobar que un rbol binario es un rbol binario de bsqueda. Su implementacin en maude es la siguiente: op esABB? : ABB{X} -> Bool . var R : X$Elt . vars I D : ABB{X} . eq esABB?(crear) = true . eq esABB?(arbolbBin(R, I, D)) = (Max(I) < R) and (Min(D) > R) and (esABB?(I)) and (esABB?(D)) .
70
Recorridos
Se puede hacer un recorrido de un rbol en profundidad o en anchura. Los recorridos en anchura son por niveles, se realiza horizontalmente desde la raz a todos los hijos antes de pasar a la descendencia de alguno de los hijos. El coste de recorrer el ABB es O(n), ya que se necesitan visitar todos los vrtices. El recorrido en profundidad lleva al camino desde la raz hacia el descendiente ms lejano del primer hijo y luego contina con el siguiente hijo. Como recorridos en profundidad tenemos inorden, preorden y postorden. Una propiedad de los ABB es que al hacer un recorrido en profundidad inorden obtenemos los elementos ordenados de forma ascendente. Resultado de hacer el recorrido en: Inorden = [6, 9, 13, 14, 15, 17, 20, 26, 64, 72]. Preorden = [15, 9, 6, 14, 13, 20, 17, 64, 26, 72]. Postorden =[6, 13, 14, 9, 17, 26, 72, 64, 20, 15]. Recorridos en Visual Basic .Net
Ejemplo rbol binario de bsqueda
'funcin de recorrido en PREORDEN Public Function preorden() As String cadenasalida = "" rePreorden(raz) Return cadenasalida End Function Private Sub rePreorden(ByVal padre As Nodo) If IsNothing(padre) Then Return End If cadenasalida = cadenasalida & "-" & padre.dato rePreorden(padre.ant) rePreorden(padre.sig) End Sub 'funcin de recorrido en POSTORDEN Public Function postorden() As String cadenasalida = "" reposorden(raz) Return cadenasalida End Function Private Sub repostorden(ByVal padre As Nodo) If IsNothing(padre) Then Return End If repostorden(padre.ant) repostorden(padre.sig) cadenasalida = cadenasalida & "-" & padre.dato
rbol binario de bsqueda End Sub 'funcin de recorrido en ENORDEN Public Function inorden() As String cadenasalida = "" reinorden(raz) Return cadenasalida End Function Private Sub reinorden(ByVal padre As Nodo) If IsNothing(padre) Then Return End If reinorden(padre.ant) cadenasalida = cadenasalida & "-" & padre.dato reinorden(padre.sig) End Sub Recorridos en C con funciones recursivas struct Nodo{ char nombre[30]; struct Nodo *izq; struct Nodo *der; }; typedef struct Nodo Nodo; typedef Nodo *Arbol; void preOrden(Arbol abb){ if(abb) { printf("%s\n", abb->nombre); preOrden(abb->izq); preOrden(abb->der); } } void postOrden(Arbol abb){ if(abb) { postOrden(abb->izq); postOrden(abb->der); printf("%s\n", abb->nombre); } } void inOrden(Arbol abb){ if(abb) {
71
72
Comparacin de rendimiento
D. A. Heger(2004) realiza una comparacin entre los diferentes tipos de rboles binarios de bsqueda para encontrar que tipo nos dara el mejor rendimiento para cada caso. Los montculos se encuentran como el tipo de rbol binario de bsqueda que mejor resultado promedio da, mientras que los rboles rojo-negro los que menor rendimiento medio nos aporta.
rbol binario de bsqueda rboles alfabticos son rboles Huffman con una restriccin de orden adicional, o lo que es lo mismo, rboles de bsqueda con modificacin tal que todos los elementos son almacenados en las hojas.
73
74
Comparada con otras estructuras de arrays asociadas, las tablas hash son ms tiles cuando se almacenan grandes cantidades de informacin. Las tablas hash almacenan la informacin en posiciones pseudo-aleatorias, as que el acceso ordenado a su contenido es bastante lento. Otras estructuras como rboles binarios auto-balanceables tienen un tiempo promedio de bsqueda mayor (tiempo de bsqueda O(log n)), pero la informacin est ordenada en todo momento.
Tabla hash
75
Funcionamiento
Las operaciones bsicas implementadas en las tablas hash son: insercin(llave, valor) bsqueda(llave) que devuelve valor La mayora de las implementaciones tambin incluyen borrar(llave). Tambin se pueden ofrecer funciones como iteracin en la tabla, crecimiento y vaciado. Algunas tablas hash permiten almacenar mltiples valores bajo la misma clave. Para usar una tabla hash se necesita: Una estructura de acceso directo (normalmente un array). Una estructura de datos con una clave Una funcin resumen (hash) cuyo dominio sea el espacio de claves y su imagen (o rango) los nmeros naturales.
Insercin
1. Para almacenar un elemento en la tabla hash se ha de convertir su clave a un nmero. Esto se consigue aplicando la funcin resumen (hash) a la clave del elemento. 2. El resultado de la funcin resumen ha de mapearse al espacio de direcciones del vector que se emplea como soporte, lo cual se consigue con la funcin mdulo. Tras este paso se obtiene un ndice vlido para la tabla. 3. El elemento se almacena en la posicin de la tabla obtenido en el paso anterior. 1. Si en la posicin de la tabla ya haba otro elemento, se ha producido una colisin. Este problema se puede solucionar asociando una lista a cada posicin de la tabla, aplicando otra funcin o buscando el siguiente elemento libre. Estas posibilidades han de considerarse a la hora de recuperar los datos.
Bsqueda
1. Para recuperar los datos, es necesario nicamente conocer la clave del elemento, a la cual se le aplica la funcin resumen. 2. El valor obtenido se mapea al espacio de direcciones de la tabla. 3. Si el elemento existente en la posicin indicada en el paso anterior tiene la misma clave que la empleada en la bsqueda, entonces es el deseado. Si la clave es distinta, se ha de buscar el elemento segn la tcnica empleada para resolver el problema de las colisiones al almacenar el elemento.
Tabla hash 2. Este valor es reducido a un ndice vlido en el vector encontrando su mdulo con respecto al tamao del array. El tamao del vector de las tablas hash es con frecuencia un nmero primo. Esto se hace con el objetivo de evitar la tendencia de que los hash de enteros grandes tengan divisores comunes con el tamao de la tabla hash, lo que provocara colisiones tras el clculo del mdulo. Sin embargo, el uso de una tabla de tamao primo no es un sustituto a una buena funcin hash. Un problema bastante comn que ocurre con las funciones hash es el aglomeramiento. El aglomeramiento ocurre cuando la estructura de la funcin hash provoca que llaves usadas comnmente tiendan a caer muy cerca unas de otras o incluso consecutivamente en la tabla hash. Esto puede degradar el rendimiento de manera significativa, cuando la tabla se llena usando ciertas estrategias de resolucin de colisiones, como el sondeo lineal. Cuando se depura el manejo de las colisiones en una tabla hash, suele ser til usar una funcin hash que devuelva siempre un valor constante, como 1, que cause colisin en cada insercin. Funciones Hash ms usadas: 1. Hash de Divisin: Dado un diccionario D, se fija un nmero m >= |D| (m mayor o igual al tamao del diccionario) y que sea primo no cercano a potencia de 2 o de 10. Siendo k la clave a buscar y h(k) la funcin hash, se tiene h(k)=k%m (Resto de la divisin k/m). 2. Hash de Multiplicacin Si por alguna razn, se necesita una tabla hash con tantos elementos o punteros como una potencia de 2 o de 10, ser mejor usar una funcin hash de multiplicacin, independiente del tamao de la tabla. Se escoge un tamao de tabla m >= |D| (m mayor o igual al tamao del diccionario) y un cierto nmero irracional (normalmente se usa 1+5^(1/2)/2 o 1-5^(1/2)/2). De este modo se define h(k)= Suelo(m*Parte fraccionaria(k*))
76
Resolucin de colisiones
Si dos llaves generan un hash apuntando al mismo ndice, los registros correspondientes no pueden ser almacenados en la misma posicin. En estos casos, cuando una casilla ya est ocupada, debemos encontrar otra ubicacin donde almacenar el nuevo registro, y hacerlo de tal manera que podamos encontrarlo cuando se requiera. Para dar una idea de la importancia de una buena estrategia de resolucin de colisiones, considerese el siguiente resultado, derivado de la paradoja de las fechas de nacimiento. Aun cuando supongamos que el resultado de nuestra funcin hash genera ndices aleatorios distribuidos uniformemente en todo el vector, e incluso para vectores de 1 milln de entradas, hay un 95% de posibilidades de que al menos una colisin ocurra antes de alcanzar los 2.500 registros. Hay varias tcnicas de resolucin de colisiones, pero las ms populares son encadenamiento y direccionamiento abierto.
Tabla hash
77
Tabla hash
78
sondeo
ms
El sondeo lineal ofrece el mejor rendimiento del cach, pero es ms sensible al aglomeramiento, en tanto que el doble hasheo tiene pobre rendimiento en el cach pero elimina el problema de aglomeramiento. El sondeo cuadrtico se sita en medio. El doble hasheo tambin puede requerir ms clculos que las otras formas de sondeo. Una influencia crtica en el rendimiento de una tabla hash de direccionamiento abierto es el porcentaje de casillas usadas en el array. Conforme el array se acerca al 100% de su capacidad, el nmero de saltos requeridos por el sondeo puede aumentar considerablemente. Una vez que se llena la tabla, los algoritmos de sondeo pueden incluso caer en un crculo sin fin. Incluso utilizando buenas funciones hash, el lmite aceptable de capacidad es normalmente 80%. Con funciones hash pobremente diseadas el rendimiento puede degradarse incluso con poca informacin, al provocar aglomeramiento significativo. No se sabe a ciencia cierta qu provoca que las funciones hash generen aglomeramiento, y es muy fcil escribir una funcin hash que, sin querer, provoque un nivel muy elevado de aglomeramiento.
Tabla hash Desaprovechamiento de la memoria. Si se reserva espacio para todos los posibles elementos, se consume ms memoria de la necesaria; se suele resolver reservando espacio nicamente para punteros a los elementos.
79
Implementacin en pseudocdigo
El pseudocdigo que sigue es una implementacin de una tabla hash de direccionamiento abierto con sondeo lineal para resolucin de colisiones y progresin sencilla, una solucin comn que funciona correctamente si la funcin hash es apropiada. registro par { llave, valor } var vector de pares casilla[0..numcasillas-1] function buscacasilla(llave) { i := hash(llave) mdulo de numcasillas loop { if casilla[i] esta libre or casilla[i].llave = llave return i i := (i + 1) mdulo de numcasillas } } function busqueda(llave) i := buscacasilla(llave) if casilla[i] est ocupada // llave est en la tabla return casilla[i].valor else // llave no est en la tabla return no encontrada function asignar(llave, valor) { i := buscacasilla(llave) if casilla[i] est ocupada casilla[i].valor := valor else { if tabla casi llena { hacer tabla ms grande (nota 1) i := buscacasilla(llave) } casilla[i].llave := llave casilla[i].valor := valor } }
Tabla hash
80
Implementacin en Java
En este mtodo no se requiere que los elementos estn ordenados. El mtodo consiste en asignar el ndice a cada elemento mediante una transformacin del elemento, esto se hace mediante una funcin de conversin llamada funcin hash. Hay diferentes funciones para transformar el elemento y el nmero obtenido es el ndice del elemento. La principal forma de transformar el elemento es asignarlo directamente, es decir al 0 le corresponde el ndice 0, al 1 el 1, y as sucesivamente pero cuando los elementos son muy grandes se desperdicia mucho espacio ya que necesitamos arreglo grandes para almacenarlos y estos quedan con muchos espacios libres, para utilizar mejor el espacio se utilizan funciones ms complejas. La funcin de hash ideal debera ser biyectiva, esto es, que a cada elemento le corresponda un ndice, y que a cada ndice le corresponda un elemento, pero no siempre es fcil encontrar esa funcin, e incluso a veces es intil, ya que puedes no saber el nmero de elementos a almacenar. La funcin de hash depende de cada problema y de cada finalidad, y se pueden utilizar con nmeros o cadenas, pero las ms utilizadas son:
Restas Sucesivas
Esta funcin se emplea con claves numricas entre las que existen huecos de tamao conocido, obtenindose direcciones consecutivas. Un ejemplo seran los alumnos de ingeniera en sistemas que entraron en el ao 2005 sus nmeros de control son consecutivos y est definido el nmero de alumnos. 05210800 -05210800 0 05210801 -05210800 1 05210802 -05210800 2 05210899 -05210800 99
Aritmtica Modular
El ndice de un nmero es resto de la divisin de ese nmero entre un nmero N prefijado, preferentemente primo. Los nmeros se guardarn en las direcciones de memoria de 0 a N-1. Este mtodo tiene el problema de que dos o ms elementos pueden producir el mismo residuo y un ndice puede ser sealado por varios elementos. A este fenmeno se le llama colisin. Si el nmero N es el 7, los nmeros siguientes quedan transformados en: 1679 6 4567 3 8471 1 0435 1 5033 0 Mientras ms grande sea nmero de elementos es mejor escoger un nmero primo mayor para seccionar el arreglo en ms partes. El nmero elegido da el nmero de partes en que se secciona el arreglo, y las cada seccin est compuesta por todos los elementos que arrojen el mismo residuo, y mientras ms pequeas sean las secciones la bsqueda se agilizara ms que es lo que nos interesa.
Tabla hash
81
Truncamiento
Consiste en ignorar parte del nmero y utilizar los elementos restantes como ndice. Tambin se produce colisin. Por ejemplo, si un nmero de 7 cifras se debe ordenar en un arreglo de elementos, se pueden tomar el segundo, el cuarto y el sexto para formar un nuevo nmero: 5700931 703 3498610 481 0056241 064 9134720 142 5174829 142
Plegamiento
Consiste en dividir el nmero en diferentes partes, y operar con ellas (normalmente con suma o multiplicacin). Tambin se produce colisin. Por ejemplo, si dividimos el nmero de 7 cifras en 2, 2 y 3 cifras y se suman, dar otro nmero de tres cifras (y si no, se toman las tres ltimas cifras): 5700931 > 57 + 00 + 931 = 988 3498610 34 + 98 + 610 = 742 0056241 00 + 56 + 241 = 297 9134720 91 + 34 + 720 = 845 5174929 51 + 74 + 929 = 1054 Nota: Estas solo son sugerencias y que con cada problema se pude implementar una nueva funcin hash que incluso tu puedes inventar o formular.
Tratamiento de Colisiones
Hay diferentes maneras de solucionarlas pero lo ms efectivo es en vez de crear un arreglo de nmero, crear un arreglo de punteros, donde cada puntero seala el principio de una lista enlazada. As, cada elemento que llega a un determinado ndice se pone en el ltimo lugar de la lista de ese ndice. El tiempo de bsqueda se reduce considerablemente, y no hace falta poner restricciones al tamao del arreglo, ya que se pueden aadir nodos dinmicamente a la lista.
Tabla hash
82
Prueba Lineal
Consiste en que una vez detectada la colisin se debe recorrer el arreglo secuencialmente a partir del punto de colisin, buscando al elemento. El proceso de bsqueda concluye cuando el elemento es hallado, o bien cuando se encuentra una posicin vaca. Se trata al arreglo como a una estructura circular: el siguiente elemento despus del ltimo es el primero. La funcin de rehashing es, por tanto, de la forma: R(H(X)) = (H(X) + 1) % m (siendo m el tamao del arreglo) Ejemplo: Si la posicin 397 ya estaba ocupada, el registro con clave 0596397 es colocado en la posicin 398, la cual se encuentra disponible. Una vez que el registro ha sido insertado en esta posicin, otro registro que genere la posicin 397 o la 398 es insertado en la posicin siguiente disponible. public class Principal { public static void main(String[] args) { try { int i, n, resp; int m = Integer.parseInt(javax.swing.JOptionPane.showInputDialog("Ingrese el tamao de la tabla")); Hash[] h = new Hash[m]; for (i = 0; i < m; i++) { h[i] = new Hash(); h[i].estado = 0; } do { resp = Integer.parseInt(javax.swing.JOptionPane.showInputDialog("Men Principal nn" + "Insertar (1)nBuscar (2)nEliminar (3)nSalir (4)")); switch (resp) { case 1: n = Integer.parseInt(javax.swing.JOptionPane.showInputDialog("Ingrese el nmero a ser insertado en la tabla:")); Hash.insertaHash(h, m, n); break; case 2: n = Integer.parseInt(javax.swing.JOptionPane.showInputDialog("Ingrese el nmero a ser buscado en la tabla:")); i = Hash.buscaHash(h, m, n); if (i == -1) { javax.swing.JOptionPane.showMessageDialog(null, "Nmero no encontrado"); } else { javax.swing.JOptionPane.showMessageDialog(null, "Nmero encontrado"); } break;
Tabla hash case 3: n = Integer.parseInt(javax.swing.JOptionPane.showInputDialog("Ingrese el nmero a ser eliminado de la tabla:")); i = Hash.eliminaHash(h, m, n); if (i == -1) { javax.swing.JOptionPane.showMessageDialog(null, "Nmero no encontrado"); } else { javax.swing.JOptionPane.showMessageDialog(null, "Nmero eliminado con xito"); } break; case 4: System.exit(0); default: } } while (resp != 4); } catch (NumberFormatException nfe) { javax.swing.JOptionPane.showMessageDialog(null, "Est Saliendo del Programa"); } catch (OutOfMemoryError ome) { javax.swing.JOptionPane.showMessageDialog(null, "No Hay Espacio"); } } } public class Hash { int dato; int estado; //0 = Vaco, 1 = Eliminado, 2 = Ocupado static int funcion(int n, int m) { return ((n + 1) % m); } static void insertaHash(Hash[] h, int m, int n) { boolean i = false; int j = funcion(n, m); do { if (h[j].estado == 0 || h[j].estado == 1) { h[j].dato = n; h[j].estado = 2; i = true; } else {
83
Tabla hash j++; } } while (j < m && !i); if (i) { javax.swing.JOptionPane.showMessageDialog(null, "Elemento insertado con xito!"); } else { javax.swing.JOptionPane.showMessageDialog(null, "Tabla llena!"); } } static int buscaHash(Hash[] h, int m, int n) { int j = funcion(n, m); while (j < m) { if (h[j].estado == 0) { return -1; } else if (h[j].dato == n) { if (h[j].estado == 1) { return -1; } else { return j; } } else { j++; } } return -1; } static int eliminaHash(Hash[] h, int m, int n) { int i = buscaHash(h, m, n); if (i == -1) { return -1; } else { h[i].estado = 1; return 1; } } }
84
Tabla hash
85
Hash Dinmico
Las tablas hash se presentaron como una alternativa hacia las estructuras tipo rbol ya que permitan el almacenamiento de grandes volmenes de informacin y algoritmos eficientes para la administracin sobre estas estructuras (insercin, eliminacin y bsqueda). Sin embargo, presentan 2 grandes problemas: 1. No existen funciones hash perfectas que permitan asegurar que por cada transformacin de un elemento habr una nica correspondencia en la clave que contiene este elemento. 2. Son estructuras estticas que no pueden crecer ya que necesitan un tamao fijo para el funcionamiento de la estructura. Para solucionar el segundo problema se implementa la utilizacin de mtodos totales y mtodos parciales. Convirtiendo la tabla hash en una estructura dinmica capaz de almacenar un flujo de informacin y no una cantidad fija de datos.
Mtodos Totales
Mtodo de las expansiones totales El mtodo de las expansiones totales consiste en realizar una duplicacin del tamao del arreglo establecido para realizar la tabla hash, esta expansin se ejecuta cuando se supera la densidad de ocupacin . As si se tiene una tabla hash de tamao N, al realizar la expansin total se obtendr una tabla hash de 2N, al realizar una segunda expansin se obtendr una tabla hash de 4N, al realizar una tercera expansin se obtendr una tabla hash de 8N y en general el tamao de la tabla para una i-sima expansin se define como aparece a continuacin:
Dnde: N: Tamao de la Tabla. i: Nmero de expansiones que se quieren realizar. T: Nuevo tamao de la Tabla. La densidad de ocupacin se define como el cociente entre el nmero de registros ocupados y el nmero de registros disponibles; as se tiene que:
Dnde: ro: Registros Ocupados. rd: Registros Disponibles. o: Densidad de Ocupacin. Cada vez que se pretende insertar un elemento es necesario calcular la densidad de ocupacin, si se supera esta densidad se procede a implementar la expansin. Al realizar cada de una de las expansiones es necesario volver a implementar la funcin hash para cada uno de los registros almacenados en la tabla y volver a insertarlos de nuevo en la tabla. Mtodo de las reducciones totales Este mtodo surge como una consecuencia del mtodo de expansiones totales presentado anteriormente. En este mtodo la densidad de ocupacin disminuye de tal manera que acepta una reduccin del tamao de la tabla hash a la mitad. As si se tiene una tabla hash de N, la primera reduccin dar como resultado la N/2, la segunda reduccin dar como resultado N/4, la tercera reduccin dar N/8 y la i-sima reduccin dar como resultado:
Dnde: N: Tamao de la Tabla. i: Nmero de expansiones que se quieren realizar. T: Nuevo tamao de la Tabla. Para realizar una reduccin la densidad de ocupacin se debe disminuir a un valor menor al rango establecido y los registros se deben eliminar de tal manera que los registros resultantes se puedan ingresar en una tabla hash que posea
Tabla hash la mitad del tamao de la tabla original. Cada vez que se implementa una reduccin es necesario volver a utilizar la funcin hash con cada uno de los registros almacenados.
86
Mtodos Parciales
Mtodo de las expansiones parciales El mtodo de las expansiones parciales consiste en incrementar en un 50% el tamao del arreglo establecido para realizar la tabla hash, esta expansin se ejecuta cuando se supera la densidad de ocupacin. As si se tiene una tabla hash de tamao N, al realizar la expansin parcial se obtendr una tabla hash de 1.5 N, al realizar una segunda expansin se obtendr una tabla hash de 2.25 N, al realizar una tercera expansin se obtendr una tabla hash de 3.375 N y en general el tamao de la tabla para una i-sima expansin se define como: T = ( (1.5) ^ i * N ) Dnde: N: Tamao de la Tabla. i: Nmero de expansiones que se quieren realizar. T: Nuevo tamao de la Tabla. Cada vez que se pretende insertar un elemento es necesario calcular la densidad de ocupacin, si se supera esta densidad se procede a implementar la expansin. Al realizar cada de una de las expansiones es necesario volver a implementar la funcin hash para cada uno de los registros almacenados en la tabla hash y volver a insertarlos de nuevo en la tabla. Mtodo de las reducciones parciales Este mtodo surge como una consecuencia del mtodo de expansiones parciales presentado en la seccin 2.1 de este documento. En este mtodo la densidad de ocupacin disminuye de tal manera que acepta una reduccin del tamao de la tabla hash al 50%. As si se tiene una tabla hash de N, la primera reduccin dar como resultado la 0.5 N, la segunda reduccin dar como resultado 0.25 N, la tercera reduccin dar 0.125 N y la i-sima reduccin dar como resultado: T = ((0.5)^i*N) Dnde: N: Tamao de la Tabla. i: Nmero de reducciones que se quieren realizar. T: Nuevo tamao de la Tabla. Para realizar una reduccin la densidad de ocupacin debe disminuir a un valor menor al rango establecido y los registros se deben eliminar de tal manera que los registros resultantes se puedan ingresar en una tabla hash que posea la mitad del tamao de la tabla original. Cada vez que se implementa una reduccin es necesario volver a utilizar la funcin hash con cada uno de los registros almacenados.
Nota
[1] La reconstruccin de la tabla requiere la creacin de un array ms grande y el uso posterior de la funcin asignar para insertar todos los elementos del viejo array en el nuevo array ms grande. Es comn aumentar el tamao del array exponencialmente, por ejemplo duplicando el tamao del array.
Enlaces externos
Artculos e implementaciones
Artculo donde se explica la implementacin en C y un anlisis de costo-beneficio de una tabla hash (http:// urtevolution.com.ar/blog/?p=1). [Categora:Estructura de datos]]
Funcin hash
87
Funcin hash
A las funciones hash (adopcin ms o menos directa del trmino ingls hash function) tambin se les llama funciones picadillo, funciones resumen o funciones de digest (adopcin ms o menos directa del trmino ingls equivalente digest function)[1][2][3]Una funcin hash H es una funcin computable mediante un algoritmo, H: U M x h(x),
Una funcin de hash en funcionamiento.
que tiene como entrada un conjunto de elementos, que suelen ser cadenas, y los convierte (mapea) en un rango de salida finito, normalmente cadenas de longitud fija. Es decir, la funcin acta como una proyeccin del conjunto U sobre el conjunto M. Observar que M puede ser un conjunto definido de enteros. En este caso podemos considerar que la longitud es fija si el conjunto es un rango de nmeros de enteros ya que podemos considerar que la longitud fija es la del nmero con mayor nmero de cifras. Todos los nmeros se pueden convertir al nmero especificado de cifras simplemente anteponiendo ceros. Normalmente el conjunto U tiene un nmero elevado de elementos y M es un conjunto de cadenas con un nmero ms o menos pequeo de smbolos. Por esto se dice que estas funciones resumen datos del conjunto dominio. La idea bsica de un valor hash es que sirva como una representacin compacta de la cadena de entrada. Por esta razn decimos que estas funciones resumen datos del conjunto dominio.
Terminologa asociada
Al conjunto U se le llama dominio de la funcin hash. A un elemento de U se le llama preimagen o dependiendo del contexto clave o mensaje. Al conjunto M se le llama imagen de la funcin hash. A un elemento de M se le llama valor hash, cdigo hash o simplemente hash. Se dice que se produce una colisin cuando dos entradas distintas de la funcin de hash producen la misma salida. De la definicin de funcin hash podemos decir que U, el dominio de la funcin, puede tener infinitos elementos. Sin embargo M, el rango de la funcin, tiene un nmero finito de elementos debido a que el tamao de sus cadenas es fijo. Por tanto la posibilidad de existencia de colisiones es intrnseca a la definicin de funcin hash. Una buena funcin de hash es una que tiene pocas colisiones en el conjunto esperado de entrada. Es decir, se desea que la probabilidad de colisin sea muy baja.
Funcin hash
88
Parmetros adicionales
La definicin formal dada, a veces se generaliza para poder aprovechar las funciones hash en otros mbitos. Para ello a la funcin hash se le aaden nuevos parmetros de forma que el valor hash no es slo funcin del contenido en s, sino adems de otros nuevos factores. Para hallar valores hash de ficheros a veces se usan, adems del contenido en s, diversos parmetros como el nombre del archivo, su longitud, hora de creacin, etc. Otras veces se aaden parmetros que permiten configurar el comportamiento de la funcin. Por ejemplo, la funcin hash puede recibir como parmetro una funcin de generacin de valores pseudoaleatorios que es usada dentro del algoritmo de la funcin hash. Otros ejemplos de parmetros son el uso de valores sal, el uso de claves secretas, el uso de parmetros que especifican el rango de la funcin (funciones hash de rango variable), el uso de parmetros que especifican el nivel de seguridad que se quiere en el valor hash de salida (funciones hash dinmicas),....
Propiedades
La calidad de una funcin hash viene definida con base en la satisfaccin de ciertas propiedades deseables en el contexto en el que se va a usar.
Bajo costo
Calcular el valor hash necesita poco costo (computacional, de memoria,...).
Compresin
Una funcin hash comprime datos si puede mapear un dominio con datos de longitud muy grande a datos con longitud ms pequea
Uniforme
Se dice que una funcin hash es uniforme cuando para una clave elegida aleatoriamente es igualmente probable tener un valor hash determinado, independientemente de cualquier otro elemento. Para una funcin hash H uniforme del tipo H:{0,1}m{0,1}n, es decir: Las cadenas estn construidas sobre un alfabeto de 2 smbolos (Alfabeto binario) El dominio es el conjunto de las cadenas de longitud m El rango es el conjunto de las cadenas de longitud n podemos decir que a cada resumen le corresponde 2m-n mensajes y que la probabilidad de que dos mensajes den como resultado la misma salida es 2-n Para algoritmos de bsqueda, si todas las entradas son igualmente probables, se busca esta propiedad para minimizar el nmero de colisiones ya que cuantas ms colisiones haya, ser mayor el tiempo de ejecucin de las bsquedas.
Funcin hash
89
De rango variable
En algunas funciones hash el rango de valores hash puede ser diferente a lo largo del tiempo. Ejemplo: Funciones hash usadas para tablas hash que necesitan expandirse. En estos caso a la funcin hash se le debe pasar un parmetro que le permita saber en qu rango se mueve la ejecucin para hallar el valor hash.
Determinista
Una funcin hash se dice que es determinista cuando dada una cadena de entrada siempre devuelve el mismo valor hash. Es decir, el valor hash es el resultado de aplicar un algoritmo que opera slo sobre la cadena de entrada. Ejemplos de funciones hash no-deterministas son aquellas funciones hash que dependen de parmetros externos, tales como generadores de nmeros pseudoaleatorios o la fecha. Tampoco son deterministas aquellas funciones hash que dependen de la direccin de memoria en la que est almacenada la cadena de entrada. Esa direccin es accidental y no se considera un cambio de la cadena entrada en s. De hecho puede cambiar dinmicamente durante la propia ejecucin del algoritmo de la funcin hash.
Se dice que una funcin hash tiene resistencia a la primera preimagen o simplemente que tiene resistencia a preimagen (del ingls preimage-resistant) si dado un valor hash y, es computacionalmente intratable encontrar un x, tal que h(x)=y. Resistencia a la segunda preimagen
[5]
Se dice que una funcin hash tiene resistencia a la segunda preimagen (en ingls second preimage-resistant) si dado un mensaje x, es computacionalmente intratable encontrar un x', , tal que h(x)=h(x'). Resistencia a colisiones (CRHF)
[6]
Se dice que una funcin hash tiene resistencia a colisiones o que es resistente a colisiones o CRHF (del ingls Collision Resistant Hash Function) si encontrar un par con tal que es computacionalmente intratable. Es decir, es difcil encontrar dos entradas que tengan el mismo valor hash. Como encontrar una segunda preimagen no puede ser ms fcil que encontrar una colisin, entonces la resistencia a colisiones incluye la propiedad de resitencia a la segunda preimagen.[7][8] Por otro lado se puede decir que la mayora de las funciones hash CRHFs son resistentes a preimagen.[9] La resistencia a colisisiones implica resistencia
Funcin hash a preimagen para funciones hash con salida aleatoria uniforme.[10] En algunos trabajos a estas funciones se les llama funciones hash de un slo sentido fuertes (del ingls strong one way hash function) para resaltar que es fuerte debido a que hay libre eleccin de los dos valores x e y. Funcin hash de un solo sentido (OWHF)
[11]
90
Una funcin hash se dice que es una funcin hash de un solo sentido o que es OWHF (del ingls One-Way Hash Function) si tiene las propiedades de resistencia a preimagen y de resistencia a segunda preimagen. Es decir, es difcil encontrar una entrada cuya hash sea un valor hash preespecificado. Observar que es diferente a la definicin general que se hace de funciones de un solo sentido:
[12]
Una funcin se dice que es una funcin de un solo sentido o que es OWF si para cada x del dominio de la funcin, es fcil computar f(x), pero para todo y del rango de f, es computacionalmente intratable encontrar cualquier x tal que y=f(x). La diferencia entre OWHF y OWF es que OWF no requiere que sea funcin hash ni que sea resistente a segunda preimagen. En algunos trabajos a estas funciones se les llama funciones hash de un slo sentido dbiles (del ingls strong one way hash function) para resaltar que es dbil en contraste con CRHF (que es fuerte) debido a que al cumplir la propiedad de resistencia a segunda preimagen no hay libre eleccin en la seleccin del valor x, y por tanto del valor h(x), en el que se tiene que producir la colisin. Resistencia a la casi colisin
[13]
H es resistente a la casi colisin (en ingls near-colission resistance) si es difcil encontrar dos mensajes con para las cuales sus imgenes y difieran solamente en unos pocos bits.
[14]
Por ejemplo podemos tener una funcin resistente a colisiones de 256 bits que no es resistente a la casi colisin porque se pueden encontrar casi-colisiones para los 224 bits de ms a la izquierda. Resistencia a las preimgenes parciales
[15]
Una funcin hash tiene resistencia a preimgenes parciales (en ingls Partial-preimage resistance) si es difcil encontrar una parte de la preimagen de un valor hash incluso conociendo el resto de la preimagen. Es decir, se debe recurrir a la fuerza bruta: si se desconocen t bits de la preimagen, se deben realizar en promedio 2n-t operaciones de hash encontrarlo. A una funcin hash resistente a preimgenes parciales tambin se le dice que es localmente de un slo sentido (del ingls local one-wayness).
Funcin hash cambio en el mensaje original idealmente hace que cada uno de cualquier bit del valor hash resultante cambie con probabilidad 0.5. Cuando esto sucede (o casi) se dice que se produce un efecto avalancha En funciones hash usadas para bsqueda normalmente se buscan funciones tan continuas como sea posible; de forma que entradas que difieran un poco deberan tener valores hash similares o iguales. Sin embargo la continuidad no es deseable para funciones hash usadas para sumas de verificacin o funciones criptogrficas por evidentes razones.
91
se dice que tiene resistencia a la computacin de nuevos valores hash no puede ser
computado para un nuevo dato x con para cualquier i, sin que K sea conocida. Observar que la propiedad anterior implica que no debera ser posible calcular K a partir de un rango de pares conocidos . A esta propiedad se la llama propiedad de no recuperacin de clave (en ingls key non-recovery). El estudio de este tipo de propiedades son muy tiles en el campo de la criptografa para los llamados 'cdigos de autenticacin de mensajes'
Concepto
Sea , el dominio de la funcin, sea el rango de la funcin. Sea el conjunto de todas las posibles claves (tericamente es infinito aunque en la prctica es finito), Una familia de funciones hash (notacin equivalente es un conjunto infinito de funciones hash de la forma , donde cada funcin de la familia es indexada por una clave que
cumple las siguientes propiedades: es accesible, es decir hay un algoritmo probabilstico de tiempo polinomial, que sobre una entrada devuelve una instancia es muestreable, es decir, hay un algoritmo probabilstico de tiempo polinomial, que selecciona uniformemente elementos de entrada . computa . es computable en tiempo polinomial, es decir, hay un algoritmo de tiempo polinomial (en l) que sobre una
Ejemplo: SHA-1 es una sola instancia de funcin hash, no una familia. Sin embargo SHA-1 puede ser modificado para construir una familia finita de funciones. M. Bellare y P. Rogaway[18] modificaron SHA-1 de tal forma que la claves especifica las constantes usadas en la cuarta ronda de las funciones. En este caso el tamao de la clave es de 128 bits y por tanto , y .
Funcin hash Observar que en la definicin de una funcin hash el dominio se puede formalizar como , sin embargo en una . Esto es
92
funcin hash definida como instancia de un elemento de una familia de funciones hash el dominio es
debido a que para que se cumplan las propiedades de seguridad es necesario que el dominio sea muestreado uniformemente en tiempo polinomial. Una familia de funciones puede siempre ser definida con aquel tamao apropiado para acomodar cualquier mensaje que sea necesario.
Se dice que una familia de funciones hash es una (t,)-familia hash resistente a colisiones
con n,l y k enteros positivos y n>=l, que satisfacen la siguiente condicin: Sea buscador de colisiones de cadenas que para un entrada K en el espacio de claves usa tiempo salida , un par tal que . Observar que la probabilidad es tomada sobre las elecciones aleatorias de . Mirando esta definicin se ve que son interesantes aquellas familias que tienen un t/ suficientemente grande. Estrictamente hablando hablamos de familias CRHF pero por simplicidad se suele hablar simplemente de CRHF. . Para cada ,
La definicin no se mete en cmo se eligen las funciones hash de la familia. Este punto es crucial.[21] En realidad, en cualquier aplicacin de funciones hash resistentes a colisiones, alguna parte P tienen que elegir una funcin de la familia de forma aleatoria para producir la descripcin de la funcin. Es importante distinguir entre dos casos: La eleccin aleatoria se puede hacer pblica (o 'public-coin'). La eleccin aleatoria puede ser revelada como parte de la descripcin de la funcin. La eleccin aleatoria se tiene que mantener secreta (o 'secret-coin'). La revelacin la eleccin aleatoria realizada puede que permita encontrar colisiones. Por tanto P tiene que mantener secreta la eleccin despus de producir la descripcin de la funcin. Evidentemente una familia CRHF elegible de forma pblica (public-coin) tambin puede trabajar si uno elige o mantiene la eleccin de forma privada (secret-coin).
probabilidad de que dos entradas distintas m,n tengan el mismo valor hash asociado, estando la funcin hash elegida aleatoriamente entre los miembros de . De la definicin se percibe que son interesantes aquellas familias que tienen un valor pequeo de indicando que el adversario no puede encontrar un par de entradas que producen el mismo valor hash, para una funcin hash elegida aleatoriamente de entre los elementos la familia.
Funcin hash
93
si no existe ningn adversario que en tiempo menor que t pueda ganar el siguiente juego con probabilidad mayor o igual que : El adversario escoge un valor x del Rango, entonces recibe una clave K del espacio de claves escogida de forma aleatoria. El juego se gana si encuentra un x' tal que hK(x)= hK(x'). El adversario est compuesto por dos algoritmos . slo tiene como parmetro de entrada el conjunto de la familia de funciones hash. Produce como salida x y
State. x es el valor hash objetivo y State es alguna informacin extra que puede ayudar a A2 a encontrar la colisin. tiene como parmetros de entrada K,x y State y produce como salida x' por tanto . siendo un par con tal que hK(x)= hK(x') Observar que, al igual que en la definicin de (t,)-CRHF la probabilidad es tomada sobre las elecciones aleatorias de . La gran diferencia es que aqu la entrada x se fija primero. Mirando esta definicin se ve que son interesantes aquellas familias que tienen un t/ suficientemente grande.
Muchas funciones hash se construyen mediante el proceso iterativo siguiente hasta conseguir el valor hash de la entrada X, h(X): El nmero de bits de la entrada X (en principio de longitud arbitraria) tiene que ser mltiplo de la longitud de bloque. Para conseguirlo se tiene una regla de padding que alarga la entrada a una longitud aceptable. Normalmente esta regla consiste en aadir al final de la entrada unos smbolos adicionales a los que se llama relleno o padding. Se divide la entrada en bloques de longitud fija. Obteniendo un conjunto de bloques x1,...,xt. Se realiza un proceso iterativo de la siguiente forma: H0=IV Hi=f(xi,Hi-1), i=1,2,...,t y h(X)=g(Ht). Al valor IV se le llama valor inicial y se representa por esas siglas por el trmino ingls Initial Value. A la funcin f se la llama funcin de ronda o funcin de compresin. A la funcin g se la llama transformacin de salida. Lo que hace la funcin g es derivar a partir de Ht tantos bits como se quieran en la salida de la funcin. Frecuentemente
Funcin hash g es la funcin identidad o un truncamiento de Ht. En este tipo de descripcin de funciones hash hay dos elecciones importantes que afectarn a las propiedades que tendr la funcin: La eleccin de la regla de padding. Si lo que se quiere es evitar colisiones es recomendable que la regla de padding no permita que existan dos mensajes que sean rellenados a el mismo mensaje. La eleccin de valor inicial (IV). Debera ser definido como parte de la descripcin de la funcin hash. A las funciones que se construyen mediante el anterior sistema se dice que son son funciones hash iterativas. A esta forma de construccin recursiva se la conoce tambin como de Merkle-Damgrd debido a que fue usado por primera vea por R. Merkle y I. Damgrd independientemente en 1989.
94
Aplicaciones
Las funciones hash son usadas en mltiples campos. Ejemplos: Herramienta bsica para la construccin de utilidades ms complejas: Construccin de estructuras de datos: Su uso en distintas estructuras de datos hacen ms eficientes las bsquedas. Ej. tablas hash. Construccin de esquemas de compromiso. Los esquemas de compromiso permiten que una entidad elija una valor entre un conjunto finito de posibilidades de tal forma que no pueda cambiarla. Esa entidad no tiene que revelar su eleccin hasta si acaso el momento final (la eleccin puede permanecer oculta). Construccin de algoritmos de cifrado/descifrado. Por ejemplo se usa en la construccin de cifradores de flujo y de cifradores de bloque. Construccin de algoritmos generadores de nmeros pseudoaleatorios. Construccin de cadenas pseudoaleatorias. Por ejemplo el llamado modelo de orculo aleatorio se basa en considerar que funciones hash con ciertas propiedades se comportan como funciones que escogen cadenas al azar, se usa para el estudio de la seguridad los esquemas criptogrficos. Construccin de algoritmos de testeo de pertenencia o no a un conjunto.- Se han usado funciones hash para la construccin de acumuladores criptogrficos y filtros de Bloom. Estas tecnologas permiten establecer mecanismos que permiten pronunciarse, a veces con cierto grado de error, sobre la pertenencia o no a cierto conjunto. Construccin de mtodos de generacin de sellos de tiempo confiables. Herramienta para proteger la integridad En la firma digital Como dato que se firma:En los algoritmos de firma convencionales normalmente en lugar de firmar todo el contenido se suele ser firmar slo el valor hash del mismo. Algunas de las motivaciones para hacer esto son:[32] Cuando se usa para firmar algoritmos de firma por bloques donde los mensajes son ms largos que el bloque, no es seguro firmar mensajes bloque a bloque ya que un enemigo podra borrar bloques del mensaje firmado o insertar bloques de su eleccin en el mensaje antes de que sea firmado. Al usar una funcin hash hacemos una transformacin que hace a la firma dependiente de todas las partes del mensaje. Normalmente los valores hash son mucho ms cortos que los datos originales de entrada. Se puede mejorar mucho la velocidad de firma firmando el valor hash en lugar de firmar el dato original. Si los mensajes a firmar pueden tener cierta estructura algebraica y el algoritmo de firma se comporta de forma que el sistema resultante puede ser vulnerable a criptoanlisis con ataques de texto escogido, podemos usar funciones hash para destruir esta estructura algebraica.
Funcin hash Como parte del algoritmo de firma: Se han desarrollado algoritmos de firma que usan funciones hash en el propio algoritmo de firma como una herramienta interna del mismo. Ejemplo de este tipo algoritmos son el esquema de firma de Merkle. Suma de verificacin (del ingls checksum): Cuando queremos almacenar o transmitir informacin, para protegernos frente a errores fortuitos en el almacenamiento o transmisin, es til acompaar a los datos de valores hash obtenidos a partir de ellos aplicando funciones hash con ciertas propiedades de forma que puedan ser usados para verificar hasta cierto punto el propio dato. A el valor hash se le llama Suma de verificacin. Prueba de la integridad de contenidos.- Por ejemplo cuando se distribuye un contenido por la red, y se quiere estar seguro de que lo que le llega al receptor es lo que se est emitiendo, se proporciona un valor hash del contenido de forma que ese valor tiene que obtenerse al aplicar la funcin hash sobre el contenido distribuido asegurando as la integridad. A esto se le suele llamar checksum criptogrfico debido a que es un checksum que requiere el uso de funciones hash criptogrficas para que sea difcil generar otros ficheros falso que tengan el mismo valor hash. Otro ejemplo de uso esta tecnologa para verificar la integridad es calcular y guardar el valor hash de archivos para poder verificar posteriormente que nadie (Ej un virus) los ha modificado. Si en lugar de verificar la integridad de un solo contenido lo que se quiere es verificar la integridad de un conjunto de elementos, se pueden usar algoritmos basados en funciones hash como los rboles de Merkle que se basan en aplicar reiteradamente las funciones hash sobre los elementos del conjunto y sobre los valores hash resultantes. Herramientas vinculadas a la autenticacin y control de acceso Autenticacin de entidades: Por ejemplo es frecuente el uso para este propsito de funciones hash deterministas con clave secreta que tienen ciertas propiedades (Cdigos de autenticacin de mensajes). En estos esquemas tanto el servicio de autenticacin, o verificador, como la entidad que se quiere autenticar mantienen en secreto la clave de la funcin hash. El esquema funciona de la siguiente forma: El que se quiere autenticar genera un mensaje y calcula su valor hash. Estos dos datos se mandan al verificador. El verificador comprueba que el valor hash se corresponde con el mensaje enviado y de esta forma verifica que la entidad tiene la clave secreta y por otra parte puede asegurar que el mensaje es ntegro (no ha sido modificado desde que se calcul el valor hash). Observar que el esquema no tiene la propiedad del no-repudio por parte del que se quiere autenticar ya que el verificador, al disponer de la clave secreta, puede generar tambin los valores hash. Proteccin de claves: Para comprobar la correccin de una clave no es necesario tener la clave almacenada, lo que puede ser aprovechado para que alguien no autorizado acceda a ella, sino almacenar el valor hash resultante de aplicar una funcin hash determinista. De esta forma para verificar si una clave es correcta basta con aplicar la funcin hash y verificar si el resultado coincide con el que tenemos almacenado. Derivacin de claves: Por ejemplo en algunas aplicaciones usan funciones hash para derivar una clave de sesin a partir de un nmero de transaccin y una clave maestra. Otro ejemplo de aplicacin sera el uso de funciones hash para conseguir sistemas de autenticacin con claves de un solo uso o OTP (del ingls One Time Password). En este tipo de sistemas la clave es vlida para un solo uso. Estos sistemas se basan en tener un semilla inicial y luego ir generando claves (mediante un algoritmo que puede usar funciones hash) que pueden tener un solo uso y as evitar ataques de REPLAY. Herramienta para la identificacin y la rpida comparacin de datos: Se pueden usar funciones hash para proporcionar una identificacin de objetos o situaciones. Una buena funcin hash para este propsito debera ser rpida y asegurarse de que dos objetos o situaciones que se considerar iguales den lugar al mismo valor hash. Observar que dos objetos o situaciones pueden ser considerados iguales sin ser idnticos. Por ejemplo podemos considerar iguales a dos ficheros que son distintos bit a bit porque realmente son la digitalizacin de la misma pelcula. Es labor del diseo de la funcin hash capturar la esencia del criterio de igualdad. Por otra parte la evaluacin de la funcin hash debera ser poco costosa para facilitar la rpida comparacin de elementos candidatos a ser iguales y de esta forma poder implementar algoritmos de bsqueda rpidos.
95
Funcin hash Huellas digitales.- El uso de funciones hash aplicados a cadenas permiten obtener valores hash que pueden usarse detectar fcilmente la aparicin de esos datos en distintos sitios. Pueden ser usados para distintos usos como bsqueda de virus, autenticacin con datos biomtricos, deteccin de copias,...La idea puede usarse ms all de textos y ser aplicado a cualquier tipo de contenido multimedia:[33][34] Las funciones hash especficamente diseadas para este propsito obtienen valores hash que permiten detectar caractersticas intrnsecas del contenido multimedia, de forma que se pueda identificar si dos archivos diferentes se corresponden con el mismo contenido multimedia. Como aplicacin prctica de este tipo de algoritmo tenemos los programas que se ejecutan en dispositivos mviles y que son capaces de adivinar el ttulo de la cancin que est sonando en la habitacin solamente capturando el sonido y comparndolo con estos valores hash. Este tipo de algoritmos tambin se puede utilizar para proteccin de contenidos multimedia ya que permite validar automticamente si cierto fichero multimedia est protegido o no por derechos de autor. Identificacin de contenidos: En algunas aplicaciones se usa el valor hash de un contenido multimedia para identificar ese contenido independientemente de su nombre o ubicacin. Esto es ampliamente usado en redes Peer-to-peer que intercambian de archivos, tales como Kazaa, Ares Galaxy, Overnet, BitTorrent. Identificar un registro en una base de datos y permitir con ello un acceso ms rpido a los registros (incluso ms rpido que teniendo ndices). Algortmos de bsqueda de subcadenas: Los algoritmos de bsqueda de subcadenas tratan el problema de buscar subcadenas, a la que llaman patrn, dentro de otra cadena a la que llaman texto. Hay algoritmos de este tipo que usan funciones hash en su implementacin. Ejemplo: algoritmo Karp-Rabin. Deteccin de virus: Para detectar los virus muchos antivirus definen funciones hash que capturan la esencia del virus y que permiten distinguirlos de otros programas o virus. Es lo que se llama firma del virus. Estas firmas son usadas por los antivirus para poder detectarlos. Muchas de las aplicaciones de las funciones hash son relativas al campo de la criptografa ( Cifradores, acumuladores criptogrficos, firma digital, protocolos criptogrficos de autenticacin,...). La Criptografa es una rama de las matemticas que proporciona herramientas para conseguir seguridad en los sistemas de informacin. Las funciones hash interesantes en el rea de la criptografa se caracterizan por cumplir una serie de propiedades que permiten a las utilidades criptogrficas que las utilizan ser resistente frente ataques que intentan vulnerar la seguridad del sistema. A las funciones hash que cumplen estas propiedades se las llama funciones hash criptogrficas.
96
Referencias
[1] [2] [3] [4] [5] [6] [7] [8] H. Tiwari, K. Asawa "Cryptographic Hash Function: An Elevated View", European Journal of Scientific Research, 2010 A. J. Menezes et all, " Handbook of Applied Cryptography (http:/ / www. cacr. math. uwaterloo. ca/ hac/ )", CRC Press 2011 D. Henrici,"Concepts, Protocols, And Architectures". Lectures Notes in Electrical Engineering. Springer-Verlag 2008. A. J. Menezes et all, " Handbook of Applied Cryptography (http:/ / www. cacr. math. uwaterloo. ca/ hac/ )", CRC Press 2011 A. J. Menezes et all, " Handbook of Applied Cryptography (http:/ / www. cacr. math. uwaterloo. ca/ hac/ )", CRC Press 2011 A. J. Menezes et all, " Handbook of Applied Cryptography (http:/ / www. cacr. math. uwaterloo. ca/ hac/ )", CRC Press 2011 Bart Preneel,"The State of Cryptographic Hash functions. I. B. Damgard, "Collision free hash functions and public key signatures schemes". Advances in Cryptology- Crypto'89. LNCS 304 pages 203-216. Springer 1987 [9] A. J. Menezes et all, " Handbook of Applied Cryptography (http:/ / www. cacr. math. uwaterloo. ca/ hac/ )", CRC Press 2011 [10] Kazumaro Aoki, Yu Sasaki, "Meet in the midle preimage attacks against reduced SHA-0 and SHA-1" [11] H. Tiwari et all, "Cryptographic Hash Function:An elevated View", European Jorunal of Scientific Research, Vol 43 pp.452-465. 2010 [12] A. J. Menezes et all, " Handbook of Applied Cryptography (http:/ / www. cacr. math. uwaterloo. ca/ hac/ )", CRC Press 2011 [13] W. R. Speirs,"Dynamic cryptographic hash functions", Thesis. Purdue University School.2007 [14] Peter Stavroulakis et all,"Handbook of Information and Communication Security", Spring 2010 [15] Dirk Henric,"RFID security and privacy: concepts, protocols, and architectures", Springer 2008 [16] Gnter Schfer,"Security in fixed and wireless networks: an introduction to securing data communications". Willey 2003 [17] William Speirs, " Dynamic cryptographic hash functions (https:/ / www. cerias. purdue. edu/ assets/ pdf/ bibtex_archive/ 2007-20. pdf)" [18] Mihir Bellare and Phillip Rogaway. " Introduction to modern cryptography. Chapter 5 (http:/ / www-cse. ucsd. edu/ users/ mihir/ cse207/ w-hash. pdf).September 2005. [19] Chum-Yuan Hsiao et all, "Finding Collision on a Public Road, or Do Secure Hash Functions Need Secret Coins?"
Funcin hash
[20] "Signature Scheme in Multi-User Setting", The Institute of Electronics, Information and Communication Engineers, 2006 [21] Chun-Yuan Hsiao et all, "Finding Collisions on a Public Road, or Do Secure Hash Functions Need Secret Coins [22] Mridul Nandi," A Generic Method to Extend Message Space of a Strong Pseudorandom Permutation (http:/ / www. scielo. org. mx/ pdf/ cys/ v12n3/ v12n3a4. pdf)" [23] A. R. Caldebank et all, "Improved Range Summable Random Variable Construction Algorithms", Proceedings of the 16 Annual ACM-SIAM Symposium on Discrete Algorithms [24] Ted Krovetz,"Message Authentication on 64-Bit Architectures", Selected Areas in Cryptography, LNCS 4356, Springer.2006. [25] Ilya Mironov,"Collision-Resistant No More: Hash-and-Sign Paradigm Revisited", Public Key Cryptography PKC 2006, LNCS 3958. Springer 2006 [26] D. Hong et all, "Higher Order Universal One-Way Hash Functions",Center for Information Security Technologies, Korea University, Seoul,Korea. [27] Henk C. A. Van Tilborg,"Encyclopedia of Cryptography and Security" Second Edition. pg 1349. Springer 2011 [28] D. Simon, "Finding collisions on a one-way street:Can secure hash functions be based on general assumptions?, EUROCRYPT 98 pp 334-345, 1998 [29] H. Tiwari,"Cryptographic Hash Function: An Elevated View", European journal of Scientific Research, Vol 43 pp.452-465.2010 [30] Bart Preneel,"Cryptographic Primitives for Information Authentication-State of the Art", Katholieke Universiteit Leuven, COSIC'97 LNCS 1528 1998 [31] Chris Mitchell,"Developments in Security Mechanism Standards", "Internet and Intranet Security Management: Risks and Solutions", editado por L. Janczewski,Idea Group Publishing.2000 [32] Ivan Bjerre Damgrd, " Collision free hash functions and public key signature schemes (https:/ / hkn. eecs. berkeley. edu/ ~chris/ temp/ damgard. pdf)",Advances in Cryptology - EUROCRYPT'87, Lncs 304 PP 203-216. Springer-Verlag Berlin Heidelberg 1988 [33] P. Cano et all. A Review of Audio Fingerprinting (http:/ / www. music. mcgill. ca/ ~ich/ classes/ mumt611_08/ fingerprinting/ cano05review. pdf) Journal of VLSI Signal Processing 41, 271284, 2005 [34] Loubna Bouarfa. Research Assignment on Video Fingerprinting (http:/ / ict. ewi. tudelft. nl/ pub/ ben/ Research Assignment Loubna Bouarfa - Video fingerprinting. pdf) Faculty of Electrical Engineering, Mathematics and Computer Science Delft University of Technology
97
Enlaces externos
Funciones hash para bsqueda en tablas hash (http://burtleburtle.net/bob/hash/evahash.html) (en ingls). Generador de Hashes (http://www.sinfocol.org/herramientas/hashes.php) Generador Online de Hashes (CRCs, MD2, MD4, MD5, SHA1, Tiger, Snefru, RipeMD, Whirlpool, Haval, entre otros) Aproximadamente 123 algoritmos, y 200 modos (Hex, Base64) http://www.schneier.com/threefish.html
98
99
Licencia
100
Licencia
Creative Commons Attribution-Share Alike 3.0 //creativecommons.org/licenses/by-sa/3.0/