FORMATO 2 (Anexo No.3) FORMULARIO DE LA DESCRIPCIÓN DE LA TESIS DOCTORAL O DEL TRABAJO DE GRADO TÍTULO COMPLETO DE LA TESIS DOCTORAL O TRABAJO DE GRADO: APLICACIONES DE LA TEORIA DE GRAFOS EN LA INFORMÁTICA AUTOR O AUTORES Apellidos Completos PIEDRA HERNANDEZ PATERNOSTRO MOVILLA Nombres Completos VIVIANA SOFIA CARLOS ANDRES DIRECTOR (ES) TESIS DOCTORAL O DEL TRABAJO DE GRADO Apellidos Completos Nombres Completos NIETO CLAVIJO GUSTAVO ADOLFO TRABAJO PARA OPTAR AL TÍTULO DE: TESIS DE GRADO FACULTAD: CIENCIAS BASICAS PROGRAMA: Carrera _X_ Licenciatura ___ Especialización ____ Maestría ____ Doctorado ____ NOMBRE DEL PROGRAMA: INFORMATICA MATEMATICA NOMBRES Y APELLIDOS DEL DIRECTOR DEL PROGRAMA: PATRICIA ARACELY HERNANDEZ ROMERO CIUDAD: BOGOTA AÑO DE PRESENTACIÓN DEL TRABAJO DE GRADO: 2009 NÚMERO DE PÁGINAS 86 TIPO DE ILUSTRACIONES: - Tablas y gráficos SOFTWARE requerido y/o especializado para la lectura del documento__NINGUNO________ DESCRIPTORES O PALABRAS CLAVES EN ESPAÑOL E INGLÉS: Son los términos que definen los temas que identifican el contenido. ESPAÑOL Arista no dirigida Arista dirigida Aristas múltiples Bucle Grafo no dirigido Grafo simple Grafo dirigido Multigrafo dirigido Adyacente Incidente Grafo bipartito Hoja Grafo regular Subgrafo INGLÉS Edge not addressed Directed edge Multiple edges Loop Graph not addressed Simple graph Directed graph Multigraph directed Adjacent Incident Bipartite graph Sheet Regular graph Subgraph RESUMEN DEL CONTENIDO EN ESPAÑOL E INGLÉS: ESPAÑOL El principal objetivo es conformar un proyecto que muestre algunas de las aplicaciones de la teoría de grafos en las redes de comunicaciones, manejo de información y secuencia de programas. También mostrar ejemplos y aplicaciones de la teoría de grafos en el diseño y estructura de redes de comunicaciones, establecer situaciones donde se muestra la importancia de los grafos dirigíos en la ejecución de programas y diseñar estructuras de bases de datos mostrando la utilidad de los grafos a través de ejemplos ilustrados. La finalidad de nuestro trabajo es proveer de un texto en donde se encuentren algunas de las mas grandes e importantes aplicaciones informáticas, teoría y terminología básica de la teoría de grafos, a los estudiantes de informática matemática e ingeniería de Sistemas de los primeros semestres, los cuales empiezan a estudiar la teoría de grafos y a comprender que ésta puede ser de gran ayuda para la ciencia de la computación, por ende así para sus carreras respectivas. INGLES The main objective is to build a project that shows some of the applications of graph theory in communication networks, information management and sequencing programs. We also show examples and applications of graph theory in the design and structure of communication networks, establish situations, showing the importance of the graph directed in program implementation and design of database structures showing the usefulness of a graph illustrated through examples. The purpose of our work is to provide a text where some of the biggest and important applications, theory and basic terminology of graph theory, students of mathematics and computer engineering of the first semester, the are beginning to study the theory of graphs and understand that it can be very helpful for computer science, and hence for their respective careers. APLICACIONES DE LA TEORIA DE GRAFOS EN LA INFORMÁTICA VIVIANA SOFIA PIEDRA HERNANDEZ CARLOS ANDRES PATERNOSTRO MOVILLA 1 TRABAJO DE GRADO INFORMATICA MATEMATICA PONTIFICIA UNIVERSIDAD JAVERIANA FACULTAD DE CIENCIAS CARRERA DE INFORMATICA MATEMATICA Bogotá, D. C. 10 de julio de 2009 2 DEDICATORIA Este trabajo esta dedicado a quienes nos apoyaron económica, física, emocional y mentalmente a lograr dar cada paso en nuestro camino profesional. A nuestros padres, familias y maestros. 3 RESUMEN El principal objetivo es conformar un proyecto que muestre algunas de las aplicaciones de la teoría de grafos en las redes de comunicaciones, manejo de información y secuencia de programas. También mostrar ejemplos y aplicaciones de la teoría de grafos en el diseño y estructura de redes de comunicaciones, establecer situaciones donde se muestra la importancia de los grafos dirigíos en la ejecución de programas y diseñar estructuras de bases de datos mostrando la utilidad de loa grafos a través de ejemplos ilustrados. La finalidad de nuestro trabajo es proveer de un texto en donde se encuentren algunas de las mas grandes e importantes aplicaciones informáticas, teoría y terminología básica de la teoría de grafos, a los estudiantes de informática matemática e ingeniería de Sistemas de los primeros semestres, los cuales empiezan a estudiar la teoría de grafos y a comprender que ésta puede ser de gran ayuda para la ciencia de la computación, por ende así para sus carreras respectivas. 4 AGRADECIMIENTOS Gracias a José Luis Piedra, Reinaldo Paternostro, Carmen Hernández y Vilma Movilla, nuestros padres y principales colaboradores en nuestra educación. A Gustavo Nieto quien con su inteligencia y paciencia nos ayudo a crear este trabajo. A Alejandro Forero. 10 de julio de 2009 5 INDICE 1 INTRODUCCIÓN .................................................................................................................... 7 2 MARCO TEÓRICO Y REVISIÓN DE LITERATURA ......................................................... 8 3 FORMULACION DEL PROBLEMA Y JUSTIFICACION .................................................. 9 4 OBJETIVOS ........................................................................................................................... 10 5 HISTORIA DE LA TEORIA DE GRAFOS .......................................................................... 11 7 TÉRMINOS CLAVE .............................................................................................................. 19 8 DEFINICIONES ..................................................................................................................... 20 9 MODELOS CON GRAFOS ................................................................................................... 29 10 APLICACIONES INFORMÁTICAS USANDO LA TEORÍA DE GRAFOS ..................... 33 11 GRAFOS BIPARTITOS ......................................................................................................... 36 12 GRAFOS ISOMORFOS ......................................................................................................... 37 13 CONEXIÓN ............................................................................................................................ 39 13.1 13.2 13.3 13.4 CAMINOS ....................................................................................................................... 39 CONEXIÓN EN GRAFOS NO DIRIGIDOS .................................................................... 41 CONEXIÓN EN GRAFOS DIRIGIDOS ........................................................................... 43 APLICACIONES INFORMATICAS PARA LA CONEXIÓN ENTRE GRAFOS ............ 45 14 CAMINOS EULERIANOS Y HAMILTONIANOS .............................................................. 47 15 ALGORITMO DE DIJKSTRA .............................................................................................. 51 16 ÁRBOLES ............................................................................................................................... 52 17 INTRODUCCION A LOS ÁRBOLES................................................................................... 54 18 ARBOL BINARIO .................................................................................................................. 56 19 ALGORITMOS DE RECORRIDOS ..................................................................................... 57 19.1 19.2 19.3 20 IN-ORDEN ...................................................................................................................... 57 PREORDEN ..................................................................................................................... 58 POSTORDEN .................................................................................................................. 58 ÁRBOLES DE DECISIÓN ..................................................................................................... 61 20.2 20.3 20.4 APLICACIONES DE ÁRBOLES BINARIOS .................................................................. 64 APLICACIONES INFORMATICAS DE ÁRBOLES DE DECISION ............................... 70 ÁRBOLES DE JUEGOS .................................................................................................. 72 21 ARBOL RECUBRIDOR ........................................................................................................ 78 22 ALGORITMO DE KRUSKAL .............................................................................................. 79 23 ALGORITMO DE PRIM ....................................................................................................... 83 24 BIBLIOGRAFIA..................................................................................................................... 91 6 1 INTRODUCCIÓN La teoría de grafos también llamada teoría de las gráficas, es una disciplina que es importante tanto para las matemáticas como para la teoría de la computación. En esta última disciplina todo es manejado a través de los grafos que son estructuras discretas que constan de puntos y de líneas que se conectan entre sí. Es importante saber que existen diferentes tipos de grafos, que se distinguen entre si por el tipo y el número de líneas que pueden conectarse a través de pares de puntos. Para este caso serán representados algunos de los diferentes problemas informáticos que pueden ser resueltos a través de la teoría de grafos, dichos problemas pueden ser como calcular el número de combinaciones diferentes de vuelo entre dos ciudades de una red aérea, el problema del viajante, que trata de resolver cual es la manera en que una persona debería viajar para conocer diferentes ciudades sin volver a pasar por la misma ciudad, como utilizar grafos predecibles para la creación de sistemas operativos, diseño de bases de datos entre otras aplicaciones. Es importante también saber de los diferentes algoritmos ya existentes y que son de gran importancia para poder resolver las diferentes aplicaciones informáticas, dichos algoritmos son el de Dijkstra, Prim, Kruskal, y Kuratwoski etc. El propósito principal de la investigacion es mostrar algunas de las aplicaciones que contienen la teoría de grafos y cómo se pueden resolver, con la ayuda de las matemáticas muchos manejos computacionales. Algunos de los temas relacionados con dichas aplicaciones son: Las estructuras de datos, el diseño de circuitos planos y la solución de variados problemas en campos tan particulares como la teoría de juegos, en las redes telefónicas, eléctricas, Bases de datos y de comunicaciones en general. 7 2 MARCO TEÓRICO Y REVISIÓN DE LITERATURA Actualmente la teoría de grafos es esencial para el manejo de circuitos y la creación del diseño de programas, en el sigo XVIII Leonhard Euler introdujo las primeras ideas de esta disciplina. El problema de los puentes de Konigsberg, resuelto por Leonhard Euler, en 1736, fue el comienzo de la teoría de grafos, ya que es considerado el primer resultado de esta disciplina. Existieron otros pensadores que influyeron en su desarrollo, como Gustav Kirchhoff con las leyes de los circuitos para calcular el voltaje y la corriente en los circuitos eléctricos. Son éstos ejemplos esenciales para el desarrollo de la teoría de grafos. Podemos encontrar bibliografía variada y rica en conocimiento como J. Gross, J. Yellen: "Graph Theory and its Applications" . CRC Press, 1999 y también encontramos K. H. Rosen: "Exploring Discrete Mathematics with Maple". McGrawHill, 1997, que nos presentan conceptos y aplicaciones matemáticas importantes. Después de estudiar la bibliografía nos dimos cuenta que hacía falta en la bibliografía un texto donde se encontraran en un sólo lugar algunas de las aplicaciones más importantes en la informática en el tema de la teoría de grafos. De ahí es de donde surge nuestro objetivo final de este proyecto. 8 3 3.1 FORMULACION DEL PROBLEMA Y JUSTIFICACION Formulación del problema El problema básicamente se centra en la falta de información sobre algunas aplicaciones informáticas desde un tema tan amplio como es la teoría de grafos. Lo que se pretende solucionar es contar rápidamente con un manual, en el cual se puedan encontrar algunas de las más importantes aplicaciones informáticas en el ámbito de dicha disciplina. 3.2 Justificación de la investigación La finalidad de nuestro trabajo es proveer de un texto en donde se encuentren algunas de las más grandes e importantes aplicaciones informáticas, teoría y terminología básica de la teoría de grafos, a los estudiantes de informática matemática e ingeniería de Sistemas, los cuales apenas empiezan a estudiar la teoría de grafos y a comprender que ésta puede ser de gran ayuda para la ciencia de la computación ya que a través de ella se logran muchas de las aplicación mostradas alrededor de toda su carrera. 9 4 OBJETIVOS 4.1 Objetivo General: Conformar un proyecto que muestre algunas de las aplicaciones de la teoría de grafos en las redes de comunicaciones, manejo de información y secuencia de programas. 4.2 Objetivos Específicos: - Mostrar ejemplos y aplicaciones de la teoría de grafos en el diseño y estructura de redes de comunicaciones. - Establecer situaciones donde se muestra la importancia de los grafos dirigidos en la ejecución de programas - Diseñar estructuras de bases de datos mostrando la utilidad de los grafos a través de ejemplos ilustrados. 10 5 HISTORIA DE LA TEORIA DE GRAFOS La teoría de grafos es una disciplina que hoy en día presenta un desarrollo vertiginoso debido a su importancia en el diseño de programas, circuitos etc. Sus ideas básicas las introdujo el matemático suizo Leonhard Euler en el siglo XVIII. Los grafos desde sus inicios se han empleado para resolver problemas de diversas áreas. Dicha disciplina se puede utilizar, por ejemplo, para determinar si se puede o no implementar un circuito sobre una placa de una sola capa; también a través de ella se pueden diferenciar dos compuestos químicos que tengan la misma fórmula molecular, pero distinta estructura. Como es también de gran importancia para nuestra área, Informática, ya que a través de los grafos se pueden estudiar las estructuras de redes en Internet, redes neuronales, análisis de los diferentes algoritmos ya existentes, manejo de las estructuras de datos, la creación de los diferentes sistemas operativos manejados hoy en día, entre otras aplicaciones. Esta disciplina fue creada por el respetado matemático Leonhard Euler nacido el 15 de abril de 1707 en Brasilea, Suiza, y fallecido el 18 de septiembre de 1783 en San Petersburgo. Quien es considerado como el principal matemático del siglo XVIII y como uno de los más grandes de todos los tiempos. Euler Vivió en Rusia y Alemania la mayor parte de su vida y realizó múltiples aportes a la matemática, siendo uno de los más importantes la teoría de grafos, en 1736 con el trabajo de los puentes de Konigsberg que fue considerado el primer resultado de dicha disciplina. Dicho problema consistía en que existen dos islas en el Rio Pregel en tierras de Konigsberg, y que existen 7 puentes que se cruzan entre dichas islas, por lo cual Euler se pregunto ¿Es posible dar un paseo empezando por cualquiera de las cuatro 11 partes de tierra firme, cruzando cada puente una sola vez y volviendo al punto de partida? = FIGURA 1. PUENTE DE KONIGSBERG Y SU REPRESENTACIÓN EN GRAFOS Euler enfocó dicho problema representando cada parte de tierra por un punto y cada puente, por una línea. Al final de esto se llega a la misma pregunta ¿Se podrá recorrer todas las líneas del dibujo terminando en el mismo punto de partida sin repetir las líneas? Euler demostró que no era posible puesto que el número de líneas que inciden en cada punto no es par, (condición necesaria para entrar y salir de un mismo punto). Así nació la teoría de grafos. También existieron otros trabajos que influyeron en su desarrollo, como el de Gustav Kirchhoff, quien publicó sus leyes de los circuitos para calcular el voltaje y la corriente en los circuitos eléctricos; en éste se estudiaron los grafos conexos de medida mínima, es decir, sin ciclos (árboles) con el objetivo de desarrollar un método efectivo para el análisis de redes eléctricas entendido dicho análisis como el cálculo de la intensidad y la diferencia de potencial de cada elemento de la red (resistencia, bobina, condensador, fuente de tensión, etc.). En realidad conocidas las características físicas de un elemento (resistencia, inductancia o capacidad, según corresponda) las 12 dos variables Jk(t) y Vk(t) están relacionadas por una ley física (Ohm, etc.). Además, por el hecho de estar interconectados deben cumplir los postulados conocidos como leyes de Kirchhoff : La suma algebraica de las intensidades (corrientes) asociadas a los arcos incidentes a un vértice dado ha de ser 0 (CP). (No se acumula intensidad en ningún nodo). La suma algebraica de los voltajes asociados a los arcos de cualquier ciclo ha de ser 0 (VP). (La diferencia de potencial ha de ser 0). El término “suma algebraica" tiene el significado siguiente: (CP): se suma [resta] si corresponde a un arco adyacente desde [hacia] el vértice en cuestión; (VP): se asigna una orientación arbitraria al ciclo y, según esta, se suma [resta] un voltaje si la orientación del arco asociado coincide [difiere] con la del ciclo. Modelización: Imponiendo dichos postulados a cada uno de los nodos y ciclos del grafo que modela la red eléctrica se obtiene un sistema de ecuaciones lineales a solucionar. El trabajo de Kirchhoff consistió en determinar un sistema equivalente y reducido de dichas ecuaciones. Tal reducción se obtiene considerando únicamente las ecuaciones asociadas a un sistema fundamental de ciclos y cortes asociados a un árbol generador del grafo subyacente que, en total, da lugar a un sistema de tantas ecuaciones lineales como elementos eléctricos. Dado un árbol generador T de un grafo G de orden n, un ciclo fundamental asociado a T se obtiene añadiendo a T una arista de G no perteneciente a T. De este modo pueden obtenerse m - (n - 1) ciclos distintos, donde m es la medida de G. Por otro lado, un corte fundamental está formado por el conjunto de arcos que unen pares de vértices situados en las dos componentes conexas que resultan de suprimir en el árbol generador una de sus aristas. Así, en total, hay n - 1 conjuntos de corte fundamentales. 13 EL PROBLEMA DE LOS CUATRO COLORES En 1852 Francis Guthrie escribió una carta a su hermano Frederick, discípulo de Augustus de Morgan, preguntándole si sería posible demostrar matemáticamente que son suficientes cuatro tintas para colorear cualquier mapa de forma que países con frontera común tengan asignados colores distintos. Al hablar de “países vecinos", Guthrie debió pensar en países adyacentes a lo largo de una línea fronteriza común ya que si se permitiesen fronteras reducidas a un punto, como ocurre con los distintos trozos en los que se divide un pastel, serían necesarios tantos colores como países. Por otro lado, por “país" debieron entender una “región conexa" ya que si no fuera así habría mapas pentacromáticos. Augustus de Morgan probó que no es posible que cinco países estén situados de modo que cada país tenga frontera común con cada uno de los otros cuatro. Ahora bien, en general, del hecho que en un determinado mapa se observe que no puede haber k países adyacentes dos a dos no puede deducirse que pueda pintarse con k colores. En 1878 Arthur Cayley, incapaz de probar o refutar la conjetura de los cuatro colores, presentó el problema a la London Mathematical Society. Antes de transcurrir un año, Alfred Kempe (abogado y miembro de la sociedad) publicó un artículo en el que hablaba de haber demostrado la conjetura de los cuatro colores. Aunque la demostración de Kempe resultó ser incompleta ésta contenía la mayor parte de las ideas fundamentales que posteriormente serían utilizadas por Appel y Haken. Noción de mapa normal: es aquélla donde ningún país engloba otros países y donde, además, nunca hay más de tres países que tengan un punto común. 14 Kempe demostró que era suficiente probar la conjetura de los cuatro colores para los mapas normales ya que si hubiera un mapa que precisara de cinco colores, entonces también habría un mapa pentacromático normal. También se percató que era suficiente trabajar con mapas normales minimales, en el sentido que contienen el mínimo número de países. Así, pues, el esquema de la demostración de Kempe consistía en suponer la existencia de un mapa pentacromático normal y minimal y concluir de ella una contradicción. Kempe demostró primero que todo mapa normal debe tener un país con cinco, o menor número, de países vecinos (en términos de grafos, a cada mapa normal se le puede asociar un grafo plano (grafo dual) cuyas caras serán triángulos y, como grafo plano, debe tener al menos un vértice de grado menor o igual que cinco). De aquí dedujo que el conjunto de configuraciones (un país tiene dos vecinos, tres vecinos, cuatro vecinos o cinco vecinos) es “inevitable" en cuanto todo mapa normal debe contener alguna de ellas. Entonces su objetivo era probar que cada una de estas configuraciones era también “reducible" en el sentido que si un mapa pentacromático minimal contenía una de ellas, entonces habría un mapa pentacromático con menor número de países, lo cual es absurdo. Su demostración es incompleta ya que la prueba que presenta para el caso de la configuración de un país con cinco vecinos es incorrecta. (De alguna manera puede decirse que la demostración de Appel y Hakel corrige esta deficiencia analizando, mediante un programa informático, unas 1500 configuraciones). En 1890, once años después de publicarse la demostración de Kempe, John Heawood señaló que el razonamiento dado por Kempe para justificar la imposibilidad de mapas pentacromáticos minimales en los cuales hubiese un país con cinco vecinos era insuficiente y, además, su arreglo parecía harto difícil. Heawood se planteó el problema de la coloración de un mapa en otras superficies (además del plano y la esfera) y obtuvo cotas superiores para el número mínimo de colores necesarios. Sin embargo sus razonamientos no podían aplicarse en el caso del plano. Heinrich Heesch (1936) parece haber sido el primer matemático que con 15 posterioridad a Kempe haya afirmado públicamente que la conjetura de los cuatro colores podría demostrarse encontrando un conjunto de configuraciones inevitables y reducibles. Heesch utilizó un método muy conveniente para la representación de configuraciones. Esta representación se conoce hoy como el grafo dual del mapa original. Dicho grafo (plano) se obtiene considerando como vértices las capitales de los distintos países y como aristas las trazas que unen las capitales correspondientes a países vecinos y que cortan la frontera común. Así, asociado a un mapa normal tenemos un grafo plano cuyas caras son triángulos. Por otro lado, con el objetivo de hallar configuraciones inevitables, Heesch introdujo un método que puede asimilarse al desplazamiento de cargas eléctricas de una malla. Kenneth Appel y Wolfgang Haken, de la universidad de Illinois, en enero de 1976 comenzaron la construcción de un conjunto inevitable de configuraciones reducibles utilizando un nuevo proceso de descarga. En junio de 1976, después de 1200 horas de funcionamiento de tres ordenadores distintos, terminaron la construcción. Los revisores de su trabajo, presentado en el Illinois Journal of Mathematics, “comprobaron" los cómputos de irreductibilidad mediante un programa independiente. Según, Appel y Haken, su demostración sugiere que existe un límite por que se puede conseguir con métodos puramente teóricos, incluso en el campo de las matemáticas y pone de relieve que en el pasado se había subestimado el uso de métodos computacionales en las demostraciones matemáticas. FIGURA 2. EJEMPLO GRAFICO DEL PROBLEMA DE LOS CUATRO COLORES 16 Estos trabajos desarrollados por dichos matemáticos fueron de gran importancia ya que dieron inicio a lo que miraremos en todo el transcurso del trabajo que lo llamaremos teoría de grafos y aplicaciones informáticas. 6 REPRESENTACIÓN DE GRAFOS EN PROGRAMAS. Hay tres maneras de representar un grafo en un programa: mediante matrices, mediante listas y mediante matrices dispersas. Representación mediante matrices: La forma más fácil de guardar la información de los nodos es mediante la utilización de un vector que indexe los nodos, de manera que los arcos entre los nodos se pueden ver como relaciones entre los índices. Esta relación entre índices se puede guardar en una matriz, que llamaremos de adyacencia. Ejemplo de matriz de adyacencia: A C B FIGURA 3. Representación de un grafo dirigido. Para la representación de la matriz se utilizara la siguiente condición: 0 el vértice i está conectado con el vértice j. aij= -1 el vértice i no está conectado con el vértice j. 17 A B C A -1 0 0 B -1 -1 0 C -1 -1 -1 TABLA 1. Representación de la FIGURA 3 a través de una matriz de adyacencia. Representación mediante listas: En las listas de adyacencia lo que haremos será guardar por cada nodo, además de la información que pueda contener el propio nodo, una lista dinámica con los nodos a los que se puede acceder desde él. La información de los nodos se puede guardar en un vector, al igual que antes, o en otra lista dinámica. A B C FIGURA 4. Representación de la FIGURA 3 mediante listas. Representación mediante matrices dispersas: Una matriz dispersa es una matriz de grandes dimensiones (la cual puede aceptar muchos elementos), dichas matrices son de gran importancia en la teoría de grafos, ya que si tenemos que representar un área de red amplia, existirán muchos elementos, la cual utilizando una lista de adyacencia o una matriz normal pueda que no se guarden todos sus elementos por esto se crearon dichas matrices para no tener estos problemas en cuanto al manejo de información. 18 7 TÉRMINOS CLAVE Arista no dirigida: una arista asociada al conjunto {u, v}, donde u y v son vértices. Arista dirigida: una arista asociada al par ordenado (u, v), donde u y v son vértices. Aristas múltiples: aristas distintas conectando a los mismos vértices. Bucle: una arista que conecta a un vértice consigo mismo. Grafo no dirigido: un conjunto de vértices junto con un conjunto de aristas no dirigidas que conectan a estos vértices entre si. Grafo simple: un grafo no dirigido sin bucles ni aristas múltiples. Grafo dirigido: un conjunto de vértices junto con un conjunto de aristas dirigidas que conectan a estos vértices entre si. Multigrafo dirigido: un grafo con aristas dirigidas que puede tener aristas dirigidas múltiples. Adyacente: dos vértices son adyacentes si hay una arista entre ellos. Incidente: una arista es incidente con un vértice, si el vértice es un extremo de la arista. δ(v) (grado del vértice v de un grafo no dirigido): el número de aristas incidentes con v. δ+(v) (grado de salida del vértice v de un grafo dirigido): el número de aristas que tienen a v como vértice inicial. δ-(v) (grado de entrada del vértice v de un grafo dirigido): el número de aristas que tienen a v como vértice final. Grafo bipartito: un grafo cuyo conjunto de vértices esta dividido en dos subconjuntos V1 y V2 tales que cada arista del grafo conecta un vértice de V1 con un vértice de V2. Vértice aislado: un vértice de grado cero. Hoja: un vértice de grado uno. Grafo regular: un grafo en el que todos los vértices tienen el mismo grado. 19 Subgrafo de un grafo G = {V, E}: un grafo (W, F) tal que W es subconjunto de V y F es subconjunto de E. 8 DEFINICIONES DEFINICIÓN1: Vértice Un vértice es la unidad fundamental de la que están formados los grafos. Los vértices son tratados como un objeto indivisible y sin propiedades, aunque puedan tener una estructura adicional dependiendo de la aplicación por la cual se usa el grafo; por ejemplo, una red semántica es un grafo en donde los vértices representan conceptos o clases de objetos. tiene EMPRESA Tiene EMPLEADOS pertenecen DEPARTAMENTOS FIGURA 5. Representación de una red semántica. DEFINICIÓN 2: Grafo Un grafo simple G= {V, E} consta de V, un conjunto no vacío de vértices, y de E, un conjunto de pares no ordenados de elementos distintos de V. A estos pares se les llama arista. A continuación podemos dar una representación de lo que es un grafo: 20 V1 arista V2 V3 V4 FIGURA 6.Representación de un grafo no dirigido de 2 vértices y una arista DEFINICIÓN 3: Subgrafo Un subgrafo de un grafo G es un grafo cuyos conjuntos de vértices y aristas son subconjuntos de los de G. Se dice que un grafo G contiene a otro grafo H si algún subgrafo de G es H o es isomorfo a H (dependiendo de las necesidades de la situación) El subgrafo inducido de G es un subgrafo G' de G tal que contiene todas las aristas adyacentes al subconjunto de vértices de G. DEFINICIÓN 4: Aristas dirigidas y no dirigidas Las aristas son las uniones entre vértices. En algunos casos es necesario asignar un sentido a las aristas, por ejemplo, si se quiere representar la red de las calles de una ciudad con sus direcciones únicas. El conjunto de aristas será ahora un subconjunto de todos los posibles pares ordenados de vértices, con (a, b) ≠ (b, a). Los grafos que contienen aristas dirigidas se denominan grafos orientados, como el siguiente: A contiene a B FIGURA 7. Grafo dirigido. A B FIGURA 8. Grafo no dirigido. 21 Las aristas no orientadas se consideran bidireccionales para efectos prácticos (equivale a decir que existen dos aristas orientadas entre los nodos, cada una en un sentido). a d c b e FIGURA 9. Representación de grafo dirigido. En la FIGURA 9 V = {a, b, c, d, e} y A = {(a, c), (d, a), (d, e), (a, e), (b, e), (d, b)}. Se considera la característica de "grado" (positivo o negativo) de un vértice v (y se indica como (v)), como la cantidad de aristas que llegan o salen de él; para el caso de grafos no orientados, el grado de un vértice es simplemente la cantidad de aristas incidentes a este vértice. Por ejemplo, el grado positivo (salidas) de d es 3, mientras que el grado negativo (llegadas) de d es 0. DEFINICIÓN 5: Multigrafo Un multigrafo G= {V, E} consta de un conjunto V de vértices, un conjunto de E aristas y una función f de E en {{u, v} |u, v € V, u≠v}. Se dice que las aristas e₁ y e₂ son aristas múltiples o paralelas su f(e₁)= f (e₂). 22 V4 V3 V1 V2 FIGURA 10. Representación de un multigrafo no dirigido de 4 vértices y 5 aristas Como podemos ver en el anterior grafo V1,V2, V3, Y V4 tienen más de una arista que conectan un mismo vértice a eso se le denomina un multigrafo. Cuando hay mucho tráfico de información en diferentes servidores, es importante tener varias líneas telefónicas simples esto se hace para que el flujo de información que se este mandando quepa en varias líneas telefónicas (modelo multigrafo), ya que si se esta mandando mucha información en los diferentes servidores y se toma una sola línea telefónica (grafo simple), pueda que esa línea no tenga la capacidad suficiente para mandar toda la información necesaria en consecuencia traerá perdida de información y por lo cual hay una inestabilidad en las redes ya que no esta mandando toda la información necesaria. Como podemos ver en el anterior grafo si tomamos que los servidores son los vértices y las líneas telefónicas son las aristas y se esta enviando un flujo de información grande en V1 a V2, como podemos ver, V1 y V2 están utilizando dos aristas o sea dos líneas telefónicas por lo que se esta enviado un flujo de información grande, pero si podemos ver en V2 a V4 o V2 a V3 se esta enviando un flujo de información pequeño por lo que nada más es necesario utilizar una sola arista en el cual representa una sola línea telefónica. Por lo tanto una forma de manejar redes entre servidores para el manejo de mucha información es utilizando un modelo de multigrafos. 23 DEFINICION 7: Pseudografo Un pseudografo G= {V, E} consta de un conjunto V de vértices, un conjunto E de aristas y una función f de E en {{u, v}| u, v € V}. Una arista e es un bucle, o lazo, si f(e) = {u, u} = {u} para algún u € V. V1 V2 V4 V3 FIGURA 11.Representación de un pseudografo de 4 vértices, 5 aristas y 3 bucles Como podemos ver en la FIGURA11, V1, V3 Y V4 tienen aristas conectadas consigo mismo. Ese tipo de conexiones se llama bucles, por lo tanto aquellos grafos que tengan bucles en sus vértices son denominados pseudografos. Una aplicación que puede ser manejada con este tipo de grafo puede ser también las redes entre servidores. Ya que pudimos arreglar el problema cuando uno quiere enviar un flujo de información grande poniendo más líneas telefónicas y en la cual es representado con un multigrafo, pero que pasaría con la información que no pudo ser enviada o que se perdió en el momento del envio; para eso tocaría volver a reenviar la información y utilizar un modelo de multigrafo no será la mejor forma, ¿ pues cómo vamos a saber nosotros que un servidor va a volver a reenviar dicha información?; la mejor forma de estar seguro de que dicha información va ser enviada es utilizando bucles en cada servidor para que cuando se pierda una información lo que haga dicho bucle es reenviar dicha información que se perdió y así podemos controlar el manejo de información sin pérdida y eso lo vamos a poder hacer a través del pseudografo. 24 Vemos que en la FIGURA 11, V1, V3, V4 tienen bucles; dichos bucles están puestos en los vértices para saber que si hay una pérdida de información, a ellos les toque volver a retransmitir dicha información. DEFINICIÓN 8: Grafo Dirigido Un grafo dirigido (V, E) consta de un conjunto V de vértices y de un conjunto E de aristas, que son pares ordenados de elementos de V. V2 V1 Arista con dirección FIGURA 12. Representación de un grafo dirigido compuesto de 2 vértices y una arista Utilizando la misma aplicación de comunicación entre servidores, usando un diseño de grafo dirigido podemos ver que el servidor 1 (V1), puede enviarle un flujo de información al servidor 2 (v2), pero el servidor 2 no puede enviarle un flujo de información al servidor 1, porque como podemos ilustrar la arista es dirigida por lo que la línea telefónica es manejada unidireccionalmente (SIMPLEX). Las aplicaciones que se pueden manejar utilizando grafos dirigidos pueden servir de mucha ayuda para la comunicación entre servidores, esto se da porque en las comunicaciones es fundamental utilizar la transmisión de medio SIMPLEX y HALFDUPLEX que es intentar comunicar servidores de manera unidireccional y la mejor forma de hacerlo es utilizando un diseño de grafos dirigidos. 25 DEFINICIÓN 9: Multigrafo Dirigido Un multigrafo dirigido G= (V, E) consta de un conjunto V de vértices, un conjunto E de aristas y una función f de En E= {(u, v) | u, v€ V}. Se dice que la aristas e₁ y e₂ son aristas múltiples si f (e₁)= f (e₂). V2 V1 e3 e5 e4 e6 e1 e2 V5 V4 e7 e8 V3 FIGURA13. Representación de un multígrafo dirigido El anterior diseño de multigrafo puede ser aplicativo también en redes entre servidores cuando se quiere enviar un flujo de información grande de manera unidireccional, como ilustramos anteriormente V1, V2, y V5 necesitan enviar gran cantidad de flujo de información de manera unidireccional hacia los servidores V3, V2, y V1 para eso la mejor forma de hacer dicho diseño es utilizando un multigrafo dirigido. DEFINICIÓN 10: Pseudografo dirigido Un pseudografo dirigido es un grafo G= {V, E} donde V≠Ѳ y E es subconjunto VxV es un conjunto de pares ordenados y etiquetados de elementos de V. Es decir, un pseudografo dirigido es un grafo dirigido que acepte bucles en E. 26 V1 V3 V2 FIGURA 14. Representacion de un pseudografo dirigido NOTA: Es importante que para hacer un buen diseño en teoría de grafos para aplicaciones informáticas se necesita que las terminologías explicadas anteriormente estén bien entendidas para eso se mostrara una tabla resumida con las terminologías ya explicadas, con el fin de tener un mejor entendimiento en la hora de querer hacer diseños para manejos aplicativos a través de los grafos. TERMINOLOGIA EN TEORIA DE GRAFOS Tipos Aristas ¿Se admite aristas múltiples? ¿Se admiten bucles? Grafo simple No dirigido No No Multigrafo No dirigido Si No Pseudografo No dirigido Si Si Grafo dirigido Dirigido No Si Multigrafo dirigido Dirigido Si No Dirigido Si Si Pseudografo dirigido TABLA 2. TERMINOLOGIA EN TEORIA DE GRAFOS 27 DEFINICIÓN 11: Se dice que dos vértices u y v de un grafo no dirigido G son adyacentes (o vecinos) en G si {u, v} es una arista de G. Si e = {u, v}, se dice que la arista e es incidente con los vértices u y v. también se dice que la arista e conecta a u y v. se dice que los vértices u y v son extremos de la arista e. DEFINICIÓN 12: El grado de un vértice de un grafo no dirigido es el número de aristas incidentes con él, exceptuando los bucles, cada uno de los cuales contribuye con dos unidades al grado del vértice. El grado de un vértice se denota por δ(v). DEFINICIÓN 13: Si (u, v) es una arista del grafo dirigido G, se dice que u es adyacente a v y que v es adyacente desde u. Al vértice u se le llama vértice inicial de (u, v) y a v se le llama vértice final o Terminal de (u, v). Los vértices iníciales y Terminales de un bucle coinciden. DEFINICIÓN 14: En un grafo dirigido, el grado de entrada de un vértice v, denotado por δ‾(v), es el numero de aristas que tiene a como vértice final. El grado de salida de un vértice v, denotado por δ+(v), es el numero de aristas que tiene a como vértice inicial. DEFINICIÓN 15: La unión de dos grafos simple G1 = (V1, E1 ) y G2= (V2, E2 ) es el grafo simple cuyo conjunto de vértices es V1 U V2 y cuyo conjunto de aristas es E1 U E2 . La unión de G1 y G2 se denota por G1 U G2. Ejemplo en el grafo de la FIGURA 14. δ‾(V1)=2 δ+(V1) =2 28 9 MODELOS CON GRAFOS Los grafos se emplean en una gran variedad de modelos en diferentes áreas, en nuestro caso mostraremos algunos modelos empleados en el área computacional: Grafos de llamadas Los grafos se pueden utilizar para representar las llamadas telefónicas hechas en una red, por ejemplo en una red telefónica de larga distancia. En particular, puede usarse un multigrafo dirigido para representar llamadas: cada vértice representa un número de teléfono y cada arista representa una llamada. La arista que representa una llamada sale del número del teléfono desde el que se hace la llamada y llega al número de que lo recibe. En la siguiente FIGURA que ilustraremos, se muestra un pequeño grafo de llamadas telefónicas que representa siete números de teléfono. Este grafo muestra, por ejemplo, que se han hecho cinco llamadas telefónicas desde el 732-555-1234 al 732-555-4444 a ninguno de los otros seis números, salvo al 732-555-0011. Cuando solo nos importa si ha habido o no alguna llamada entre dos números, empleamos un grafo no dirigido tal que una arista conecta dos números de teléfono si se ha hecho alguna llamada en dichos números. Esta versión del grafo de llamadas la mostraremos a continuación. 29 732-555-4444 732-555-1001 732-555-1234 732-555-0069 732-555-0011 732-555-9876 732-555-6666 FIGURA 15. Representación grafo de llamadas Grafo de la Red La red de Internet se puede representar mediante un grafo dirigido en el que cada pagina Web esta representada por un vértice y en el que una arista comienza en la pagina a y termina en la pagina b si hay un enlace en la pagina a que conduce a la pagina b. Como cada segundo se crean paginas Web nuevas y otras desaparecen, hay más de mil millones de vértices y decenas de miles de millones de aristas. Hay muchas personas estudiando las propiedades del grafo de la red para entender mejor la naturaleza de la red de Internet. Grafos de precedencia y procesamiento concurrente Los programas informáticos, más que todo para los Sistemas Operativos, pueden ejecutarse más rápidamente si ciertas sentencias se ejecutan simultáneamente. Es 30 importante no ejecutar sentencias que requieran el resultado de sentencias no ejecutadas. La dependencia de sentencias con respecto a sentencias previas se puede representar por medio de un grafo dirigido. Cada sentencia se representa por un vértice, y hay una arista de un vértice a un segundo si la sentencia representada por el segundo vértice no puede ejecutarse hasta la sentencia representada por el primero se ha ejecutado. A este tipo de grafo se le llama grafo de precedencia. Por ejemplo, el grafo nos dice que la sentencia S₅ no se puede ejecutar hasta que se ejecute S₁, S₂, y S₄. S6 S5 S3 S4 S1 S2 FIGURA16. Representación de un Grafo de procedencia S1 a:= 0 S2 b:= 1 S3 c:= a+1 (necesita que s1 se ejecute para que s3 se ejecute) S4 d:= b+a (necesita que s1 y s2 se ejecute para que s4 se ejecute) S5 e:= d+1 (necesita que s4 se ejecute para que s5 se ejecute) S6 f:= d+c (necesita que s4 y s3 se ejecuten para que s6 se ejecute) Como pudimos ver anteriormente estos grafos son de gran ayuda para aplicaciones que tengan que ver con el manejo de los sistemas operativos en las computadoras ya 31 que pueden servir de mucho para el diseño de ejecución de programas para dicho sistema. Diseño de bases de datos Los grafos también pueden ser de gran ayuda para el diseño de bases de datos en las empresas; por ejemplo, una organización necesita saber información acerca de sus empleados, de sus departamentos, y de los trabajos que hace cada empleado en los departamentos. Para estos seria bueno hacer un diseño de una base de datos para que así la empresa tenga una facilitación en saber acerca de todo lo que necesita, pero para eso es necesario hacer el diseño de las bases de datos y una forma de poder representarlos es a través de un grafo. Para hacer un breve diseño en grafos de una base de datos conocer que información acerca de sus empleados, departamentos y de los trabajos que hace cada empleado en su departamento, sería conveniente representar los vértices como la información que hay para los empleados, departamentos, y trabajos, y las aristas como la relación que hay para cada una de ellas a continuación ilustraremos el diseño a través de un multigrafo no dirigido. 32 Empleados Trabajos Empresa Departamentos FIGURA 17. Representación de un multigrafo no dirigido para una organización. Anteriormente ilustramos que a través de los grafos se pueden representar el diseño de una base de datos para una empresa, como podemos ver existen vértices que los llamamos empleados, trabajos, departamentos, y Empresa, los enlaces muestran la comunicación que es impredecible para que la empresa tenga la capacidad de conocer la información que más le interese. 10 APLICACIONES INFORMÁTICAS USANDO LA TEORÍA DE GRAFOS Un sistema de adquisición de datos supervisa continuamente un cierto proceso físico, para registrar su comportamiento, informar cambios significativos y enviar comandos a un controlador de proceso. Desde la perspectiva del programador, el sistema debe: Recoger un paquete de datos desde los sensores y colocarlo en una memoria del computador 33 Una vez se tienen los datos, archivarlos en disco y efectuar un cálculo para identificar el estado de funcionamiento. Una vez calculado el estado, informar si se han detectado cambios significativos y enviar comandos al controlador Para aprovechar el paralelismo, el sistema se divide en cinco procesos, los cuales efectúan las siguientes actividades: R (recoger), G (guardar), C (calcular), I (imprimir) y E (enviar). Si se necesitara recoger dos veces un paquete de datos desde un mismo sensor, construir un grafo de precedencia, y mostrar el orden en que los procesos tienen que ser ejecutados. R1 R2 G2 G1 I1 I2 C2 C1 E1 E2 FIGURA 18. Representación de un grafo de precedencia. R1 a:= 0* (Inician recogiendo un paquete de datos desde los sensores) 34 G1 b:= a+1 (Guardan los datos que fueron recogidos) C1 c:= a+1 (Calculan los datos que fueron recogidos) I1 d:= a+c (Después de calcular el paquete de datos. Imprime lo que lleva hasta el momento) E1 e:= a+c (Enviar lo que se calculo del primer paquete de datos recogido, ya que toca volver a recoger otro paquete de datos desde el sensor y no se puede perder lo que se lleva hasta el momento) R2 a1:= b+c (después de que haya calculado y guardado el paquete de datos anterior, se puede volver a recoger el siguiente paquete de datos) G2 b1:= a1+1 (vuelve otra vez a guardar lo que recoge de los sensores de datos) C2 c1:= a1+1 (vuelve otra vez a calcular de lo que recogió hasta el principio) I2 d1:= a1+c1 (ahora se imprime el total de lo que recogió) E2 e1:= a1+c1 (vuelve a enviar el total que calculo, esto lo hace si le toca volver a recoger en el sensor de datos). (*) esta es la forma en que se representa un grafo de precedencia. Las anteriores secuencias son manejadas en los sistemas operativos cuando se quieren hacer varias impresiones en WORD simultáneamente. 35 11 GRAFOS BIPARTITOS DEFINICIÓN: Se dice que un grafo simple G es bipartito si su conjunto de vértices V se puede dividir en dos conjuntos distintos V1 y V2 tales que cada arista del grafo conecta un vértice de V1 con un vértice de V2 (de manera que no haya ninguna arista que conecte entre si dos vértices de V1 ni tampoco dos vértices de V2). 11.1 APLICACIONES INFORMÁTICAS Podemos encontrar aplicaciones informáticas con grafos bipartitos en la comparación de archivos de computador, utilizando el problema de la Longest Common Subsequence (LCS), en español Subsecuencia Común Más Larga , en el cual dadas dos palabras X e Y sobre un alfabeto finito cualquiera, lo que pretende es encontrar cuál es el largo máximo que puede tener una palabra que sea subsecuencia de X e Y simultáneamente. Por ejemplo, si consideramos X=matemáticas e Y=astronomía, una LCS (y en este caso la única) es atmia. El largo de una LCS se usa comúnmente como criterio de comparación de palabras, pues está relacionada con la cantidad de "pasos" necesarios para ir de una palabra a la otra mediante operaciones de inserción, eliminación y reemplazo de caracteres. Vamos a visualizar un poco más el ejemplo. Todo par de palabras puede representarse convenientemente como un grafo bipartito donde los arcos unen a los caracteres coincidentes de ambas palabras. X=matemáticas e Y=astronomía, el grafo que los representa sería: 36 FIGURA 19. Representación de grafo bipartito. Un matching en un grafo arbitrario (no necesariamente bipartito) es cualquier conjunto de arcos que no comparten extremos; un PM es un matching en donde los arcos no se cruzan ni comparten extremos. Así, calcular la LCS entre dos palabras no es más que calcular el matching planar de costo máximo del grafo bipartito asociado a dichas palabras, donde todos los arcos tienen costo igual a 1. Más aún, aprovechando la generalidad que otorga ver el problema LCS como uno de matching, se nos ocurren ideas nuevas que dan mayor alcance al concepto de comparación de palabras: podemos, por ejemplo, agregar más arcos al grafo asociado a dos palabras cuando los caracteres tengan cierta similitud o cuando compartan algún atributo, y asociarle un costo menor al que tienen los arcos que unen caracteres iguales. 12 GRAFOS ISOMORFOS DEFINICION Dados G=(V,E) y G´=(V´,E´), se denomina isomorfismo de G a G´ a la aplicación biyectiva f tal que para a, b ε V, {a,b}ε E se cumple {f(a),f(b)} ε E´. Es decir, la aplicación que relaciona biyectivamente pares de vértices de E con pares de vértices de E´, de modo que los vértices conectados por aristas siguen estándolo. 37 INTRODUCCIÓN Hay muchas maneras en las que los caminos y circuitos pueden ayudarnos a determinar si dos grafos son o no isomorfos. Por ejemplo, la existencia de un circuito simple de una longitud concreta es un invariante útil que se puede emplear a la hora de mostrar que dos grafos no son isomorfos. Además, podemos hacer uso de los caminos a la hora de construir posibles isomorfismos. Como ya hemos dicho, un invariante bajo isomorfismo es útil para grafos simples es la existencia de un circuito simple de longitud k, siendo k un entero positivo mayor que 2. En este ejemplo, G y G´ se denominan isomorfos, y son matemáticamente iguales, solo varia la apariencia, o sea, que se mantienen las adyacencias, estructura, caminos y ciclos. a c 1 2 b 3 d G 4 FIGURA 20. Ejemplo de grafos isomorfos. 38 G‟ 13 CONEXIÓN INTRODUCCION Hay muchos problemas que se pueden representar por medio de caminos que se forman al ir recorriendo las aristas de un grafo. Por ejemplo, el problema de determinar si se puede enviar o no un mensaje entre dos ordenadores usando enlaces intermedios puede estudiarse utilizando un modelo de grafos. Los problemas de planificar de forma eficiente las rutas de distribución de correo, de recogida de basuras, los diagnósticos en redes de ordenadores y muchos otros pueden resolverse utilizando modelos que involucran caminos definidos sobre grafos. 13.1 CAMINOS De manera informal, un camino es una secuencia de aristas que comienza en un vértice del grafo y recorre ciertas aristas del grafo siempre conectando pares de vértices adyacentes. En la definición 1 se da una definición formal de los caminos, así como cierta terminología relacionada con ellos. DEFINICION 1 Sea n un entero no negativo y sea G un grafo no dirigido. Un camino de longitud n de u a v en G es una secuencia de n aristas a₁ a₂,…, an de G tal que f(a₁)= {x₀, x₁}, f(a₂)= {x₁, x₂},…, f(an){xn-1, xn}, donde x0 = u y xn = v. (Ya que el enumerar estos vértices determina el camino de forma única). El camino es un circuito si comienza y termina en el mismo vértice, esto es, si u=x0=xn=v, y tiene longitud mayor a cero. Se dice que el camino circuito pasa por los 39 vértices x0, x₁ x₂,…, xn o también que recorre las aristas a₁ a₂,…, an. Un camino o circuito es simple si no contiene la misma arista más de una vez. Cuando no es necesario distinguir entre aristas múltiples, denotaremos el camino a₁ a₂,…, an, donde f(a₁) = {xi-1, xi} para i= 1, 2, …, n. Por su secuencia de vértices x₀, x₁, xn. Esta notación identifica un camino mediante los vértices por los que pasa, puede haber más de un camino que pase por esa secuencia de vértices. Nótese que un camino de longitud cero consiste en un único vértice. EJEMPLO En el grafo simple que mostraremos en la siguiente FIGURA a, d, c, f, e es un camino simple de longitud 4, ya que {a, d}, {d, c}, {c, f} y {f, e} son aristas. Sin embargo, d, e, c, a no es un camino, ya que {e, c}, no es una arista. Nótese que b, c, f, e, b es un circuito de longitud 4, ya que {b, c}, {c, f}, {f, e} y {e, b} son aristas, y este camino comienza y termina en b. El camino a, b, e, d, a, b, que tiene longitud, no es simple, ya que contiene dos veces la arista {a, b}. a b c d e f FIGURA 21. Representación de un grafo simple 40 DEFINICION 2 Sean n un entero no negativo y G un multigrafo dirigido. Un camino de longitud n de u a v en G es una secuencia de aristas a₁, a₂,…, an de G talque f (a₁)= (x₀, x₁), f (a₂)=(x₁, x₂),…, f(an)= (xn-1, xn), donde x₀= u y xn= v. Si no hay aristas múltiples en el grafo dirigido, denotamos este camino por su secuencia de vértices x₀, x₁,…, xn. Un camino de longitud mayor que cero que comienza y termina en el mismo vértice es un circuito. Se dice que un camino o circuito es simple sino contiene la misma arista más de una vez. Nótese que el vértice final de una arista de un camino es el vértice inicial de la siguiente arista del camino. Cuando no es necesario distinguir entre aristas múltiples, denotaremos el camino a₁, a₂,…, an, donde f(ai)= (xi-1, xi) para i= 1, 2, …, n por su secuencia de vértices x₀, x₁, …, xn. Esta notación identifica un camino mediante los vértices por los que pasa. Puede haber más de un camino que pase por esa secuencia de vértices. Los caminos representan información útil en muchos modelos de grafos. 13.2 CONEXIÓN EN GRAFOS NO DIRIGIDOS ¿Cuándo tiene una red informática la propiedad de que dos ordenadores cualesquiera pueden compartir información si pueden enviarse mensajes a través de uno o más ordenadores intermedios? Si se utiliza un grafo para representar esta red informática, con los vértices representando ordenadores y las aristas representando enlaces de comunicación, la pregunta se convierte en la siguiente: ¿Bajo que condiciones existe siempre un camino entre dos vértices cualesquiera del grafo? 41 DEFINICION 3 Se dice que un grafo no dirigido es conexo si hay un camino entre cada par de vértices distintos del grafo. Se quiere diseñar una red informática, en la cual existen cinco servidores que quieren enviar información para todos ellos, pero se busca que no pueda existir perdida de información para ningún servidor que este enviando datos. FIGURA 22. Representación de un grafo conexo FIGURA 23. Representación de un grafo no conexo En las FIGURAS ilustradas anteriormente, se quiere mostrar que si existen 5 servidores que quieren enviarse un flujo de información para una red informática, si es tomada la primera FIGURA en la cual se representa un grafo conexo, todos los servidores pueden enviar dicha información a los otros servidores, pero si se toma la segunda FIGURA en donde se representa un grafo no conexo, no es posible representar una red informática para enviar información entre servidores, ya que para los servidores 4 y 5 seria imposible enviar información hacia los servidores 1, 2 y 3 por lo que no hay aristas o conexiones que conecten a los servidores 4 y 5, en tal 42 caso no es posible representar dicho grafo como una red informática ya que la gracia es que haya siempre conexión para todos los servidores. Por lo tanto para manejos de redes informáticas para hacer diseños en grafos seria bueno representarlo a través de los grafos conexos. Un modelo que puede ser utilizado para grafos conexos puede ser: COMPONENTES CONEXAS DEL GRAFO DE LLAMADAS: Dos vértices están en la misma componente conexa de un grafo de llamadas telefónicas si hay una secuencia de llamadas telefónicas que comience en x y termine en y. En cierta ocasión se analizó el grafo de llamadas de las llamadas telefónicas realizadas a lo largo de un día concreto en la red de AT&T en estados unidos con el siguiente resultado: El grafo tenia 53.767.087 vértices, más de 170 millones de aristas y más de 3.7 millones de componentes conexas. La mayor parte de estas componentes eran pequeñas: aproximadamente tres cuartas partes de ellas representaban pares de números de teléfono que solo se habían llamado entre sí. El grafo tenía una componente conexa gigantesca con 44.989.297 vértices, que comprendía más de 80% del total. Además, cada vértice de esta componente podía conectarse con cualquier otro vértice por medio de un camino de no más de 20 llamadas. 13.3 CONEXIÓN EN GRAFOS DIRIGIDOS Hay dos nociones en grafos dirigidos, dependiendo de si se considera o no la dirección de las aristas 43 DEFINICION 4 Se dice que un grafo dirigido es fuertemente conexo si hay un camino de a a b y un camino de b a a para cualesquiera dos vértices a y b del grafo. DEFINICION 5 Se dice que un grafo es dirigido es débilmente conexo si hay un camino entre cada dos vértices del grafo no dirigido subyacente. LAS COMPONENTES FUERTEMENTE CONEXAS DEL GRAFO DE RED: El grafo de red que introdujimos anteriormente en donde se estaba representado la pagina Web por medio de vértices y los enlaces por medio de aristas dirigidas. Una instantánea de la red produjo en 1999 un grafo con más de 200 millones de vértices y más de 1500 millones de aristas. El grafo no dirigido subyacente a este grafo no es conexo y tiene una componente no conexa que incluye aproximadamente al 90% de los vértices del grafo. El subgrafo del grafo dirigido original que corresponde a esta componente conexa del grafo no dirigido subyacente (esto es, el subgrafo con los mismos vértices y con todas las aristas dirigidas que conectan entre sí a los vértices) tiene una sola componente fuertemente conexa muy grande y muchas otras pequeñas. A la primera se le llama componente fuertemente conexa gigantesca (también conocida GSCC, gigant strongly connected component) del grafo dirigido. Puede llegarse a una página Web de esta componente siguiendo enlaces que comiencen en cualquier otra página de la misma componente. La GSCC del grafo de la red que se encontró en este estudio tenía más de 53 millones de vértices. Los restantes vértices de la componente conexa grande del grafo no dirigido corresponden a tres tipos distintos de página Web: páginas a las que se llega desde una página de la GSCC, pero desde las que no se puede regresar a dicha página; se llega desde una página de la GSCC siguiendo una serie de enlaces, pero a las que no se puede llegar siguiendo enlaces a partir de ninguna página de la GSCC ni tampoco se puede llegar a ninguna página de la GSCC partiendo de ellas. En el estudio se estimo que cada uno de estos 44 tres conjuntos tenía aproximadamente 44 millones de vértices (es bastante sorprendente que estos tres conjuntos sean de tamaños tan parecidos). 13.4 APLICACIONES INFORMATICAS PARA LA CONEXIÓN ENTRE GRAFOS El manejo de caminos entre grafos puede ser fundamental para muchas aplicaciones informáticas, una de ellas puede ser la seguridad para las bases de datos de una empresa, por ejemplo, si una empresa quiere darle funciones a diferentes departamentos para el manejo de inserción, eliminación y actualización de los diferentes empleados que trabajan para cada departamento, una forma de hacerlo es haciendo un diseño utilizando grafos, a continuación se ilustrara un grafo que funcione para lo que se pide. E= Empresa DS= Departamento de sistemas DC= Departamento de contaduría DG= Departamento para la gerencia ES= Empleados para el departamento de sistemas EC= Empleados para el departamento de contabilidad EG= Empleados que hacen parte con la gerencia de la empresa DS ES E DC EC EG DG 45 FIGURA 24. Representación de las funciones y departamentos de una empresa en un grafo. En el anterior grafo lo que se quiere ilustrar, es que es fundamental manejar bien los caminos entre grafos, porque como podemos ver existe una empresa que puede actualizar, insertar, eliminar sus departamentos, dichos departamentos solo pueden insertar, actualizar, eliminar aquellos empleados que trabajen para este, por eso es que en el diseño de este grafo se especifican los caminos que pueden existir, existen caminos dirigidos entre E-DS, E-DC, y E-DG, con esto estamos especificando que la empresa puede hacer con sus departamentos ya sea eliminar, actualizar o insertar otro departamento. Para cada departamento que tiene dicha empresa existen caminos entre DS-DE, DC-EC, y DG-EG, con esto cada departamento puede eliminar, insertar o actualizar aquellos empleados que trabajen para dicho departamento, esto es importante ya que cada departamento tiene un poder solo sobre los empleados que le corresponden. REDES DE COMUNICACIONES MOVILES Podemos encontrar muchos tipos de aplicaciones de la teoría de grafos en el ámbito de las redes de comunicaciones móviles, como por ejemplo bases de datos electrónicas, desde las vías telefónicas hasta registros de e-mails. Un ejemplo específico son los patrones de comunicación de millones de usuarios de teléfonos móviles, los grafos permiten estudiar simultáneamente la estructura local y la global de una sociedad en toda la red de comunicación, en las cuales se observan acoplamientos entre la interacción fuertes y una red de la estructura local. La FIGURA 24 intenta ilustrar la estructura de las redes de comunicaciones móviles en torno a un individuo elegido al azar. Cada enlace representa la comunicación mutua entre los usuarios de la red de comunicación, y todos los nodos que se muestran son la distancia inferior a seis desde usuario seleccionado, marcado por un círculo en el centro. 46 FIGURA 25. Representación de la estructura de las redes de comunicaciones móviles en torno a un individuo elegido al azar. 14 CAMINOS EULERIANOS Y HAMILTONIANOS INTRODUCCION Al principio nos habíamos preguntado ¿Si era posible movernos por las aristas de un grafo comenzando de un vértice y volviendo a él después de haber pasado por cada arista del grafo exactamente una vez?, Análogamente ahora nos preguntamos ¿Será qué podemos desplazarnos por las aristas de un grafo comenzando en un vértice y volviendo a él después de haber visitado cada vértice del grafo exactamente una vez? Aunque estas preguntas parecen similares, la primera de ellas, que pregunta si el grafo contiene lo que se llama un circuito euleriano , puede resolverse fácilmente para cualquier grafo, mientras que la segunda cuestión, la de si el grafo contiene o no lo que se llama un circuito hamiltoneano, es bastante difícil de resolver. En esta sección analizaremos ambas preguntas y estudiaremos las dificultades que se presentan a la hora de resolverlas. 47 La FIGURA 26 muestra un diagrama del problema del Camino Hamiltoniano. El objetivo es encontrar un camino que vaya del inicio hasta el final pasando por todos los demás puntos una sola vez. Este problema es difícil para computadoras convencionales (lógica serial) porque deben de intentar cada camino posible uno por uno. Es como tener una pila de llaves y tratar de ver cuál es la que entra en una cerradura. Las computadoras convencionales son muy buenas para las matemáticas, pero malas para problemas de tipo "llave en la cerradura". Para esto se requiere de otro tipo de computadoras; esta fue la primera implementación de una computadora basada en ADN, y el título quiere decir que un problema que requiere buscar varias posibles soluciones (un problema combinatorio) fue resuelto con moléculas (ADN). Aún con su respectiva complejidad, las operaciones biológicas y matemáticas tienen algunas similitudes: La muy compleja estructura de un ser viviente es el resultado de aplicar operaciones simples a la información inicial codificada en una secuencia de ADN (genes). Todos los problemas matemáticos complejos se pueden reducir a operaciones simples como la suma y la resta. Por las mismas razones por las que el ADN fue supuestamente seleccionado para los organismos vivientes como material genético, el ser estable y predecible en reacciones, las cadenas de ADN también pueden ser usadas para codificar información para sistemas matemáticos. Las computadoras basadas en ADN pueden tratar todas las llaves al mismo tiempo (masivamente paralelo) y por lo tanto son muy buenas para problemas de llave-enla-cerradura, pero mucho más lentas para problemas matemáticos simples como la multiplicación. El problema del Camino Hamiltoniano fue escogido porque todos los 48 problemas llave-en-la-cerradura pueden ser resueltos como problemas de Camino Hamiltoniano. FIGURA 26. Representación de un camino de Hamilton. El siguiente algoritmo resuelve el problema del Camino Hamiltoniano, sin importar el tipo de computadora usada: Generar caminos aleatorios a través del grafo. Quedarse solo con los caminos que empiezan en la ciudad inicio (a) y terminan en la ciudad fin (G). Como el grafo tiene 7 ciudades, quedarse solo con los caminos que tengan 7 ciudades. Quedarse solo con los caminos que entran a todas las ciudades por lo menos una vez. Cualquier camino que quede es una solución. En síntesis, programar con ADN implica respetar algunos pasos: Crear una secuencia de ADN única para cada ciudad (de A hasta G). Para cada camino, por ejemplo, de A a B, Crear una pieza de ADN que concuerde con la última mitad de A y la primera mitad de B: Aquí el bloque rojo representa a la ciudad A, mientras que el bloque naranja 49 representa a la ciudad B. El bloque mitad rojo mitad naranja que conecta a los otros dos bloques, representa el camino de A a B. En un tubo de ensayo, todas las diferentes piezas de ADN se conectarán unas con otras al azar, formando caminos a través del grafo. Por peso, las secuencias de ADN que tuvieran 7 "ciudades" de largo fueron separadas del resto. Una malla fue usada, la cual permite que pasen rápidamente pedazos pequeños de ADN, mientras que los segmentos más largos son frenados. El procedimiento usado en realidad permite aislar las piezas que son precisamente de 7 ciudades de largo. La clave para resolver el problema fue usar ADN para llevar a cabo los cinco pasos del algoritmo. Estos bloques interconectados, pueden ser usados para modelar el ADN. Para asegurar que las secuencias que quedan pasan por todas las ciudades, fueron usadas piezas "pegajosas" de ADN unidas a magnetos para separar el ADN. Los magnetos fueron usados para asegurar que el ADN deseado permanezca en el tubo de ensayo, mientras que el ADN no requerido es removido. Primero, los magnetos se quedaban con todo el ADN que pasa por la ciudad A en el tubo de ensayo, luego por B, luego C, y D, y así sucesivamente. Al final, el ADN que permanece en el tubo fue aquél que pasa por todas las ciudades. Todo lo que falta es secuenciar el ADN, revelando el camino de A a B a C a D a E a F a G. Al ADN tiende naturalmente a formar largas hélices dobles: Las dos hélices son unidas por "bases", que serán representadas por bloques de colores. Cada base se une solamente a otra base específica. En el ejemplo, cada bloque de color únicamente se unirá con el mismo color. Por ejemplo, si solo se tuvieran bloques rojos, pudieran formar una cadena larga como esta. Cualquier otro color no se unirá con el rojo. 50 15 ALGORITMO DE DIJKSTRA El algoritmo de dijkstra también conocido como ruta más corta; a partir de un vértice determinado se obtienen todas las rutas más cortas hacia todos los demás vértices. Los pasos a seguir para el algoritmo son: 1) Conocer el vértice de origen y el vértice de destino. 2) Marcar el vértice de origen y conocer a sus vecinos 3) Mirar los costos de las rutas hacia sus vecinos 4) Marcar el vecino de la ruta más corta 5) El vecino marcado se convierte en el nuevo vértice de origen 6) Hace paso 2 y 3 7) Comparar todas las rutas que hay de sus vecinos y no vecinos no marcados que ya tengan costo asociado. 8) Obtener el vértice de costo mínimo asociado y marcarlo 9) Volver a el paso 2 EJEMPLO Los resultados son obtenidos a partir del software ALGORITMOS VORACES. 51 FIGURA 27. Ejemplo de solución del Algoritmo de Dijkstra Vértice 1 2 3 4 5 6 7 Ruta - 1,2 1,3 1,4 1,3,5 1,3,6 1,3,5,7 Costo 0 9 7 8 10 12 18 TABLA 3. Tabla solución con rutas de Dijkstra, ejemplo de FIGURA 26. PSEUDOCODIGO DIJKSTRA (Grafo G, nodo_fuente s) // inicializamos todos los nodos del grafo. La distancia de cada nodo es infinita // y los padres son NULL for u ∈ V[G] do distancia[u] = INFINITO padre[u] = NULL distancia[s] = 0 //encolamos el nodo_fuente s Encolar (cola, grafo) mientras cola no es vacía do // OJO: Se extrae el nodo que tiene distancia mínima y se conserva la condición // de Cola de prioridad u = extraer_minimo(cola) for v ∈ adyacencia[u] do if distancia[v] > distancia[u] + peso (u, v) do distancia[v] = distancia[u] + peso (u, v) padre[v] = u 16 ÁRBOLES Intuitivamente, podemos visualizar árboles como una forma de organizar información de forma jerárquica, con un único punto de entrada y una serie de caminos que van abriéndose en cada punto hacia sus sucesores. 52 Los árboles comenzaron a emplearse en 1857, cuando el matemático ingles Arthur Cayley los utilizo para contar cierto tipo de componentes químicos. Desde ese momento, los árboles se han empleado para resolver problemas de gran variedad en diferentes disciplinas como lo son en la informática, biología, medicina etc. FIGURA 28: Arthur Cayley Estas estructuras de datos son particularmente importantes en la informática, Ya que son usados para la creación de muchos algoritmosLos árboles se usan para crear algoritmos eficientes que localizan elementos en una lista, también se pueden utilizar en algoritmos como el código de huffman, que construyen códigos compresores eficientes, ahorrando costes en la transmisión de datos y en su posterior almacenamiento (mas adelante se explicara con mas detalle el código de huffman), también dichos árboles son de gran ayuda para la creación de juegos como son el ajedrez, triqui entre otros que en si puede ayudar para crear buenas estrategias ganadoras. 53 En sí los árboles son estructuras de datos que están teniendo gran importancia en la actualidad como en futuras generaciones, ya que gracias a dichas estructuras se pueden construir algoritmos que tienen gran capacidad computacional. 17 INTRODUCCION A LOS ÁRBOLES Desde un punto de vista formal (teoría de conjuntos), un árbol con raíz se puede considerar como una estructura constituida por un conjunto, N, cuyos elementos se denominan vértices, y una relación de orden parcial transitiva, —, definida sobre N, y caracterizada por la existencia de un elemento mínimo (anterior a todos los demás) único, la raíz y también un predecesor único para cada vértice p distinto de la raíz, es decir, un vértice, q. También existen los arboles sin raíz, en cuales la raíz no esta definida, en éste caso la raíz puede ser cualquiera de los nodos. Y desde el punto de vista informal, un árbol es un grafo sin circuitos. Los ascendientes de un vértice se definen como el conjunto formado por su predecesor único y los ascendientes de éste, cuando estos existan. Los descendientes de un vértice se definen como el conjunto formado por todos aquellos nodos que lo tienen en su conjunto de ascendientes. Esta estructura se puede considerar una estructura recursiva teniendo en cuenta que cada vértice del árbol, junto con todos sus descendientes, y manteniendo la ordenación original, constituye también un árbol o subárbol del árbol principal, característica esta que permite definiciones simples de árbol, más apropiadas desde el punto de vista de la teoría de tipos abstractos de datos, y, ajustadas, cada una de ellas, al uso que se vaya a hacer de la noción de árbol. 54 Un árbol impone una estructura jerárquica sobre una colección de objetos. Es claro decir que la utilización de árboles se presentan tanto dentro como fuera del área de computación (índices de libros, árboles genealógicos, etc.); en Informática constituyen una de las estructuras más utilizadas, con aplicaciones que van desde los árboles sintácticos utilizados para la representación y/o interpretación de términos de un lenguaje o expresiones aritméticas, pasando por los árboles de activación de procedimientos recursivos, hasta la representación de datos que se desea mantener ordenados con un tiempo de acceso relativamente bajo. En general, se usarán árboles siempre que se quiera representar información jerarquizada, cuando esta converja en un solo punto. Raíz FIGURA 29: Representación de un árbol. 55 18 ARBOL BINARIO Un árbol binario es el que cumple que el subárbol izquierdo de cualquier nodo (si no está vacío) contiene valores menores que el que contiene dicho nodo, y el subárbol derecho (si no está vacío) contiene valores mayores. Usos comunes de los árboles binarios son los árboles binarios de búsqueda, los montículos binarios y codificación de huffman. También seria importante definir que los Árboles Binarios según la teoría de grafos vienen siendo grafos conexos, a cíclicos y no dirigidos tal que el grado de cada vértice no es mayor a 3. De esta forma solo existe un camino entre un par de vértices. FIGURA 30: Representación de un árbol binario Es bueno tener las siguientes condiciones para tener bien definido un árbol binario en la teoría de grafos. Estas serían: - Un árbol binario es un árbol con raíz en el que cada vértice tiene como máximo dos hojas. - Un árbol binario lleno es un árbol en el que cada vértice tiene cero como mínimo o dos hijos como máximo. - Un árbol binario perfecto es un árbol binario lleno en el que todas las hojas están a la misma profundidad. - Un árbol binario perfecto es denominado árbol binario completo. 56 En conclusión lo que podemos decir acerca de los Árboles Binarios es que son árboles en los que ninguno de sus vértices puede tener más de dos sub-árboles. En un árbol binario cada vértice puede tener cero, uno o dos hijos. Se conoce el vértice izquierdo como hijo izquierdo y el vértice derecho como hijo derecho. 19 ALGORITMOS DE RECORRIDOS Los procesamientos para el recorrido sistemático de los vértices de un árbol ordenado con raíz se llaman algoritmos de recorrido de un árbol. Describiremos tres de estos algoritmos, los que se utilizan con mayor frecuencia, llamados recorridos en preorden, recorrido en in-orden y recorrido en post-orden que serán explicados mas adelante. Cada uno de estos algoritmos se puede definir de manera recursiva. 19.1 IN-ORDEN DEFINICION Sea T un árbol ordenado con raíz r. Si T consta de solo r, entonces r es el recorrido en in-orden de T. En otro caso, supongamos que T1, T2, …., Tn son los sub-arboles de r listados de izquierda a derecha en T. El recorrido en inorden comienza recorriendo T1 en in-orden y continua visitando r, a continuación recorre T2 en in-orden, después T3 en in-orden y asi sucesivamente hasta recorrer Tn en in-orden. Pasos para recorrer en un árbol de profundidad en in-orden: o Recorrer el sub-árbol izquierdo en in-orden. o Examinar la raíz. 57 o Recorrer el sub-árbol derecho en in-orden. En el caso de árboles generales o de orden N, se visita primero el árbol más a la izquierda, a continuación la raíz, y por último el resto de sub-árboles en secuencia. 19.2 PREORDEN DEFINICION Sea T un árbol ordenado con raíz r. Si T consta solo de r, entonces r es el recorrido pre-orden de T. En otro caso, supongamos T1, T2,….., Tn son los sub-árboles de r listados de izquierda a derecha en T. El recorrido en preorden comienza visitando r, continua recorriendo T1 en pre-orden, luego T2 en pre-orden y así sucesivamente hacia recorrer hasta recorrer Tn en preorden. Pasos para recorrer en un árbol de profundidad en pre-orden: o Examinar la raíz. o Recorrer el sub-árbol izquierdo en pre-orden. o recorrer el sub-árbol derecho en pre-orden. 19.3 POSTORDEN DEFINICION Sea T un árbol ordenado en raíz r. Si T consta solo de r, entonces r es el recorrido en post-orden de T. En otro caso, supongamos que T1, T2, …, Tn son los sub-arboles de r listados de izquierda a derecha en T. El recorrido en post-orden y así sucesivamente hasta recorrer Tn en post-orden y finaliza visitando r. Pasos para recorrer en un árbol de profundidad en pre-orden: 58 o Recorrer el sub-árbol izquierdo en post-orden. o Recorrer el sub-árbol derecho en post-orden. o Examinar la raíz. A continuación se muestra un ejemplo de los diferentes recorridos en profundidad de un Árbol Binario. A B D C F E J G H I FIGURA 31: Representación de un Árbol Binario. In-orden: GDBHEIACJKF Pre-orden: ABDGEHICFJK Post-orden: GDHIEBKJFCA 59 K J * / + 1 / 3 - 4 7 * * 23 5 8 3 5 FIGURA 32: Representación de una expresión aritmética como un Árbol. Los árboles binarios se emplean a menudo para la representación de expresiones aritméticas, dado que una operación con dos operandos la podemos representar como un árbol cuya raíz sea el operador, y sus sub-árboles sean los operandos. Por ejemplo, la operación: (3-(4*5- 3)*8+7/5)*1/23-j, equivaldría, rellenando paréntesis, a: {[(3-{[(4*5)- 3]*8}) + (7/5)]*(1/23)}-j, y su árbol sería el de la FIGURA 25. 60 Están además la notación polaca en la que los operadores siempre preceden a los operandos sobre los que actúan, y que tiene la ventaja de no necesitar paréntesis y la polaca inversa en la que los operadores van después de los operandos sobre los que actúan, la ventaja mas grande es que los cálculos se realizan secuencialmente según se van introduciendo operadores, en vez de tener que esperar a escribir la expresión al completo. Debido a esto, se cometen menos errores al procesar cálculos complejos: Polaca: -/*+ /-*-* 4 5 3 8 3 7 5 1 23 j Polaca inversa: {[(3 {[(4 5*) 3-] 8*}-) (7 5/)+] (1 23/)*} j- 20 ÁRBOLES DE DECISIÓN Un árbol de decisión es un modelo de predicción utilizado en el ámbito de la inteligencia artificial. Dada una base de datos se construyen estos diagramas de construcciones lógicas, muy similares a los sistemas de predicción basados en reglas, que sirven para representar y categorizar una serie de condiciones que suceden de forma sucesiva, para la resolución de un problema. Un árbol de decisión tiene unas entradas las cuales pueden ser un objeto o una situación descrita por medio de un conjunto de atributos y a partir de esto devuelve una respuesta la cual en últimas es una decisión que es tomada a partir de las entradas. Los valores que pueden tomar las entradas y las salidas pueden ser valores discretos o continuos. Se utilizan más los valores discretos por simplicidad, cuando se utilizan valores discretos en las funciones de una aplicación se denomina clasificación y cuando se utilizan los continuos se denomina regresión. 61 Un árbol de decisión lleva a cabo un test a medida que este se recorre hacia las hojas para alcanzar así una decisión. El árbol de decisión suele contener vértices internos, vértices de probabilidad, vértices hojas y aristas. Un vértice interno contiene un test sobre algún valor de una de las propiedades. Un vértice de probabilidad indica que debe ocurrir un evento aleatorio de acuerdo a la naturaleza del problema, este tipo de vértices es redondo, los demás son cuadrados. Un vértice hoja representa el valor que devolverá el árbol de decisión. Y finalmente las ramas brindan los posibles caminos que se tienen de acuerdo a la decisión tomada. El árbol de decisión es un diagrama que representa en forma secuencial condiciones y acciones; muestra qué condiciones se consideran en primer lugar, en segundo lugar y así sucesivamente. Este método permite mostrar la relación que existe entre cada condición y el grupo de acciones permisibles asociado con ella. Se recomienda el uso del árbol de decisión cuando el número de acciones es pequeño y no son posibles todas las combinaciones. Los árboles de decisión se utilizan en cualquier proceso que implique toma de decisiones, ejemplos de estos procesos son: Búsqueda Binaria Sistemas Expertos Árboles de juegos Los árboles de decisión generalmente son binarios, es decir que cuentan con dos opciones, aunque esto no significa que no puedan existir árboles de 3 o más opciones. 62 EJEMPLO: BUSQUEDA BINARIA Método se basa en partir el árbol en dos partes, a continuación tenemos el siguiente árbol: 20 7 3 25 23 10 30 40 FIGURA 33: Representación de un árbol de decisión. Con el árbol anterior realizaremos una búsqueda binaria a través de un árbol de decisión. Supongamos que deseas buscar un numero X en el árbol - Comparamos si el numero que estamos buscando es igual a la raíz, si es igual devuelve la raíz y se termina la búsqueda. - Si no es igual se compara nuevamente el número para saber si es mayor o menor que la raíz con lo que se ahorraría la totalidad del árbol, y así volver más eficiente la búsqueda. - Si es menor recorremos la búsqueda hacia el lado izquierdo hasta encontrar el siguiente elemento del árbol, el cual volvemos a comparar como lo hicimos con la raíz. - Si es mayor se realiza la búsqueda hacia el lado derecho del árbol, el cual tomamos como si fuera una raíz y comparamos de la misma forma que la primera raíz. 63 El procedimiento anterior se realiza hasta encontrar el número buscado o hasta llegar a NULL, pueda que el número no se encuentre en la FIGURA 31. 20.1 VENTAJAS Facilita la interpretación de la decisión adoptada. Proporciona un alto grado de compresión del conocimiento utilizado en la toma de decisiones. Reduce el número de variables independientes. Es una magnifica herramienta para el control de la gestión empresarial. 20.2 APLICACIONES DE ÁRBOLES BINARIOS CODIFICACION DE HUFFMAN Los árboles binarios han sido usados para muchas aplicaciones informáticas, como uno de estos casos es el algoritmo de Huffman. FIGURA 34: David Huffman Este algoritmo fue usado para compresión de datos. El termino se refiere al uso de una tabla de códigos de longitud variable para codificar un determinado símbolo (como puede ser un caracter en un archivo), donde la tabla ha sido rellenada de una manera específica basándose en la probabilidad estimada de aparición de cada posible 64 valor de dicho símbolo. Dicho algoritmo fue desarrollado por David A. Huffman mientras era estudiante de doctorado en el MIT. La codificación Huffman usa un método específico para elegir la representación de cada símbolo, que da lugar a un código prefijo (es decir, la cadena de bits que representa a un símbolo en particular nunca es prefijo de la cadena de bits de un símbolo distinto) que representa los caracteres más comunes usando las cadenas de bits más cortas, y viceversa. Huffman fue capaz de diseñar el método de compresión más eficiente de este tipo: ninguna representación alternativa de un conjunto de símbolos de entrada produce una salida media más pequeña cuando las frecuencias de los símbolos coinciden con las usadas para crear el código. Posteriormente se encontró un método para llevar esto a cabo en un tiempo lineal si las probabilidades de los símbolos de entrada (también conocidas como "pesos") están ordenadas. A continuación se hará un ejemplo para tener un mejor entendimiento en que se basa la codificación de Huffman. Por lo tanto codificaremos la palabra: - Palabra a codificar: "Esto es un ejemplo de árbol de Huffman". Haremos una tabla para representar cada carácter es importante saber su numero de frecuencia, y su código, es bueno organizar cada carácter de mayor a menor, esto significa que aquel carácter que tenga el numero de frecuencia mayor será el primero y así sucesivamente (frecuencia asumirlo como numero de repeticiones que presenta un carácter). CARACTER Espacio E O N U S M FRECUENCIA 7 6 3 2 2 2 2 65 CODIGO 00 100 1100 1110 0100 0101 1010 F L D A B H J P R T 2 2 2 2 1 1 1 1 1 1 1011 0110 0111 11010 110110 110111 111100 111101 111110 111111 TABLA 4: Tabla codificación de huffman 2. A continuación se realizara el árbol de huffman generado de la anterior tabla. 38 17 24 7„‟ 9 10 14 6E 5 4 4 7 7 2D 3U 2A 2L 2M 2F 4 3N 30 4 2S 1B 66 2 1H 2 2 1J 1P 1R 1T FIGURA 35: Árbol Binario que representa el código de huffman. ARBOLES B+ Los arboles B+ son una alternativa a los archivos secuenciales indexados, este mecanismo de indexación ayuda a acelerar el acceso a los datos deseados, un ejemplo concreto para esto puede ser cuando queremos encontrar un capitulo especifico en un índice alfabético en un libro estos mecanismos son importantes para que el usuario tenga una respuesta rápida de lo que quiere encontrar. GRAFOS CONEXION HISTORIA ARBOLES OBJETIVOS FIGURA 36: Representación de un árbol B+ para consultas en bases de datos La FIGURA 36 quiere mostrar una representación de cómo son manejados los arboles B+ en una base de datos que contiene información del índice de un libro, en este caso este documento+, la cual tienen la misma función de búsqueda que un árbol binario con la diferencia de que este tipo de árbol puede aceptar más de dos hijos a diferencia de un árbol binario que nada mas acepta dos hijos como máximo. Aplicaciones de árboles: Arboles de Búsqueda 67 Un árbol binario es una estructura de datos útil cuando se trata de hacer modelos de procesos en donde se requiere tomar decisiones en uno de dos sentidos en cada parte del proceso. Supongamos que tenemos un arreglo en el cual tenemos que buscar un dato duplicado, una manera de encontrar los elementos duplicados en un arreglo es recorrerlo todo y comparar con cada uno de los elementos del arreglo. Si en esta situación tuviéramos un arreglo de n posiciones se deben hacer n comparaciones, siendo n un número pequeño, no habría ningún problema. Pero se va complicando más a medida que n aumenta. Si usamos un árbol binario, el número de comparaciones se reduce bastante. Como por ejemplo: El primer número del arreglo se coloca en la raíz del árbol (como en este ejemplo siempre vamos a trabajar con árboles binarios, simplemente diremos árbol, para referirnos a un árbol binario) con sus sub-árboles izquierdo y derecho vacíos. Luego, cada elemento del arreglo se compara con la información del vértice raíz y se crean los nuevos hijos con el siguiente criterio: Si el elemento del arreglo es igual que la información del vértice raíz, entonces notificar duplicidad. Si el elemento del arreglo es menor que la información del vértice raíz, entonces se crea un hijo izquierdo. Si el elemento del arreglo es mayor que la información del vértice raíz, entonces se crea un hijo derecho. Una vez que ya está creado el árbol, se pueden buscar los elementos repetidos. Si x es el elemento buscado, se debe recorrer el árbol del siguiente modo: Sea k la información del nodo actual p. Si k>x entonces cambiar el vértice actual a right(p)(Véase el algoritmo a continuación), en caso contrario, en caso de que x=k 68 informar una ocurrencia duplicada y en caso de que x≥k cambiar el vértice actual a left(p)(Véase el algoritmo a continuación). Algoritmo para la búsqueda de duplicados leer numero buscado >> n tree=makeTree(n) while(hay numeros en el arreglo){ leeSiguienteNumero >> k p=q=tree; while(k!=info(p)&&q!=NULL){ p=q if(k<info(p)) q=left(p) else q=right(p) } if(k==info(p)) despliega<<" el numero es duplicado"; else if (k<info(p)) setLeft(p,k) else setRight(p,k) } El arreglo usado para crear el árbol binario de búsqueda fue <14,15,4,9,7,18,3,5,16,4,20,17,9,14,5> El árbol de ordenamiento es el que se muestra en la FIGURA. 69 FIGURA 37: Árbol binario para ordenar una secuencia de números Para ordenar los elementos de este arreglo basta recorrer el árbol en forma de in-orden. 20.3 APLICACIONES INFORMATICAS DE ÁRBOLES DE DECISION ÁRBOLES DE DECISION EN UNA CRISIS EMPRESARIAL El análisis de la crisis empresarial se configura como un aspecto clave en el análisis de estados financieros al permitir a la empresa disponer de un sistema de diagnóstico que abarque los aspectos de solvencia y de rentabilidad. La preocupación por el cumplimiento del objetivo de solvencia ha originado la elaboración de distintos modelos de predicción del fracaso empresarial obtenidos mediante el empleo de diferentes técnicas estadísticas como el análisis univariante o el multivariante en los que los radios contables funcionan como variables explicativas. Para esto se utilizan los árboles de decisión. Un árbol de decisión representa la relación existente entre la conclusión-decisión y sus atributos. Es decir, se produce un proceso de generalización de forma que el árbol 70 de decisión generado clasifica correctamente los datos. Este árbol, además, se caracteriza por ser el óptimo en el sentido que minimiza el número de atributos requeridos para alcanzar la conclusión-decisión, siendo esta la explicación de por qué ciertos atributos no aparecen en el árbol. Por ejemplo, considerando el árbol de decisión que a continuación se presenta, puede comprobarse que los atributos de los que depende el tomar una u otra decisión son: Importe (menor de 100.000, entre 100.000 y 500.000, mayor de 500.000) Solvencia (alta, media y baja) La decisión a tomar variará entre contado y crédito. El árbol representa la dependencia lógica entre la decisión a tomar y los atributos considerados. IMPORTE X<100000 or X>500000 X<100000 and X>500000 CONTADO SOLVENCIA Alta media CREDITO FIGURA 38: Representación de un Árbol de Decisión 71 baja CONTADO Aunque ese árbol, que se lee de izquierda a derecha y desde arriba a abajo, es equivalente a las cinco reglas siguientes: Regla 1: SI importe = menor de 100.000, ENTONCES decisión = contado. Regla 2: SI importe = mayor de 500.000, ENTONCES decisión = contado. Regla 3: SI importe = entre 100.000 y 500.000 Y solvencia = alta, ENTONCES decisión = crédito. Regla 4: SI importe = entre 100.000 y 500.000 Y solvencia = media, ENTONCES decisión = crédito. Regla 5: SI importe = entre 100.000 y 500.000 Y solvencia = baja, ENTONCES decisión = contado La estructura del árbol representa la trayectoria óptima para alcanzar una decisión en ese conjunto de reglas. Al utilizar los árboles de decisión podemos tener como conclusiones lo siguiente: Resume los ejemplos de partida, permitiendo la clasificación de nuevos casos siempre y cuando no existan modificaciones sustanciales en las condiciones bajo las cuales se generaron los ejemplos que sirvieron para su construcción. Facilita la interpretación de la decisión adoptada. Proporciona un alto grado de comprensión del conocimiento utilizado en la toma de decisiones. Explica el comportamiento respecto a una determinada tarea de decisión. Reduce el número de variables independientes. Es una magnifica herramienta para el control de la gestión empresarial. 20.4 ÁRBOLES DE JUEGOS Los árboles de juegos son también una aplicación de los árboles de decisión. Tomemos por ejemplo el conocido juego de Triqui y consideremos una función que 72 evalúa una posición del tablero y nos devuelve un valor numérico (entre mas grande es este valor, mas buena es esta posición).Un ejemplo de la implantación de esta función es considerando el numero de renglones, columnas y diagonales restantes abiertas para un jugador menos el numero de las mismas para su oponente, por ejemplo la siguiente posición en un juego y sus posibles continuaciones: FIGURA 39: Representación de un Árbol de Decisión en una posición del juego Triqui. Nota: La estructura que esta hecha para este determinado juego de triqui es que muestran todas las posibilidades para que el signo (x) gane pero también se puede hacer una estructura para que pueda también ganar el signo (o), probabilidad al azar que para este caso seria organizar de mejor manera las diferentes jugadas que puede hacer un determinado jugador. Este esquema lo que queremos mostrar es como pueden ser muy aplicables los arboles de decisión en la programación, pero seria interesante hacer de aplicación un juego triquis pensando en todas las distintas jugadas que puede hacer un jugador teniendo como ganador el signo (x) o el signo (o). Dada un posición del tablero, el mejor movimiento siguiente esta determinado por la consideración de todos los movimientos posibles y las posiciones resultantes. Tal análisis no conduce sin embargo al mejor movimiento, como se ve en el ejemplo anterior cuando las cuatro primeras posibilidades dan todos los mismos valores de evaluación, sin embargo la cuarta posición es sin duda mejor, por lo que se debe mejorar esta 73 función. Ahora se introduce la posibilidad de prever varios movimientos. Entonces la función se mejorará en gran medida; se inicia con cualquier posición y se determinan todos los posibles movimientos en un árbol hasta un determinado nivel de previsión. Este árbol se conoce como árbol de juego cuya profundidad es igual a la profundidad de dicho árbol. Así es como funciona un árbol de juego que es una aplicación de un árbol de decisión, ya que se genera el árbol de acuerdo al nivel de previsión y cada jugador va decidiendo que jugada le conviene más de acuerdo a la evaluación de una determinada posición. ÁRBOLES DE DECISIÓN UTILIZADOS EN SISTEMAS EXPERTOS Los árboles de decisión se usan en los sistemas expertos porque son más precisos que el hombre para poder desarrollar un diagnóstico con respecto a algo, ya que el hombre puede dejar pasar sin querer un detalle, en cambio la máquina mediante un sistema experto con un árbol de decisión puede dar un resultado exacto. Una deficiencia de éste es que puede llegar a ser mas lento pues analiza todas las posibilidades pero esto a su vez es lo que lo vuelve mas preciso que al hombre. A continuación se presenta un ejemplo de un sistema experto y de cómo puede llegar a diagnosticar que se emplee un fármaco X en una persona con presión arterial. 74 FIGURA 40: Ejemplo de Árbol de Decisión en sistemas Expertos. Se le administra un fármaco X al paciente si: 1.- Tiene presión alta, su azúcar en la sangre es alto, es alérgico a antibióticos y NO tiene otras alergias. 2.- Tiene presión alta, su azúcar en la sangre es alto, y NO es alérgico a antibióticos. 3.- Tiene presión arterial alta y su azúcar en la sangre es bajo. 4.- Tiene presión arterial media y su índice de colesterol es bajo. 5.- Tiene presión arterial baja. No le se le administra el fármaco X si: 1.- Tiene presión arterial alta, su azúcar en la sangre es bajo, es alérgico a los antibióticos y SI tiene otras alergias. 75 2.- Tiene presión arterial media y su índice de colesterol es alto. A continuación en la FIGURA 41, presentamos un árbol de decisión para un problema medico real que se presenta a diario en todos los hospitales del mundo y que se encuentra entre las primeras causas de muerte en los países desarrollados y que constituye causa de invalidez e incapacidad física: el dolor precordial como síntoma de las enfermedades del corazón. El árbol nos permite tomar decisiones y llegar a una solución ante cada problema que se nos presenta en un cuerpo de guardia con un paciente que acuda a nosotros con dolor precordial. . 76 FIGURA 41: Representación de un sistema Experto con Árboles de Decisión en una situación real. 77 21 ARBOL RECUBRIDOR Dado un grafo conexo, un árbol recubridor de ese grafo es un sub-grafo que es un árbol y conecta todos los vértices. Se le puede asignar un peso a cada arista, que es un número que representa qué tan adecuado es, y se usa para asignar un peso al árbol recubridor mínimo computando la suma de todos los pesos de las aristas del árbol en cuestión. Un árbol recubridor o un árbol expandido es un árbol recubridor que pesa menos o igual que otros árboles recubridores. Todo grafo tiene un bosque recubridor mínimo. El árbol recubridor es usado frecuentemente para algoritmos informáticos, los algoritmos más destacados se explicaran a continuación. FIGURA 42: Ejemplo de un árbol recubridor mínimo. 78 22 ALGORITMO DE KRUSKAL El algoritmo de Kruskal es un algoritmo de la teoría de grafos para encontrar un árbol recubridor mínimo en un grafo conexo y ponderado. Es decir, busca un subconjunto de aristas que, formando un árbol, incluyen todos los vértices y donde el valor total de todas las aristas del árbol es el mínimo MST (Mínimum Spanning Tree) que sirve para solucionar problemas relacionados con distribución de redes de energía, redes de comunicaciones y demás problemas donde se pueda llevar este a un modelo de grafos y aquí aplicar el algoritmo de Kruskal para hallar la solución al problema. FIGURA 43: Joseph Kruskal Las aplicaciones de los árboles abarcadores mínimos son múltiples: obtención de redes eléctricas o de comunicaciones eficientes, creación de laberintos aleatorios. Entre los problemas sobre grafos, uno de los de mayor interés por su enorme abanico de aplicaciones es la obtención del Árbol de recubrimiento de peso mínimo. En lo que sigue nos referiremos a éste árbol por las siglas de su nombre en inglés, MST. La determinación del MST tiene innumerables aplicaciones en diversas ramas de la ciencia y la tecnología. Por ejemplo, este tipo de árboles pueden usarse directamente 79 como base para optimizar el diseño de redes de transmisión de energía o de información cuando la topología de las conexiones debe ser (o conviene que sea) arborescente. En otras áreas, el MST puede usarse para determinar agrupamientos naturales de datos. Si tenemos una colección de datos y alguna manera de medir la disimilitud o “distancia” entre ellos, podemos ver esta colección como el conjunto de vértices de un grafo y las disimilitudes entre objetos como aristas de un grafo completamente interconectado. El MST de un grafo de este tipo tiene la propiedad de que si se eliminan sus aristas de mayor peso (disimilitud) se obtiene un “bosque” en el que cada sub-árbol agrupa todos los datos similares o “próximos” entre sí. Para ejecutar bien el algoritmo hay que seguir los siguientes pasos: 1. Se marca la arista con menor valor. Si hay más de una, se elige cualquiera de ellas. 2. De las aristas restantes, se marca la que tenga menor valor, si hay más de una, se elige cualquiera de ellas. 3. Repetir el paso 2 siempre que la arista elegida no forme un ciclo con las ya marcadas. 4. El proceso termina cuando tenemos todos los vértices del grafo en alguna de las aristas marcadas, es decir, cuando tenemos marcados n-1 arcos, siendo n el número de vértices del grafo. Ejemplo: Determinar el árbol de mínima expansión (MST) para el siguiente grafo: 3 1 7 2 9 4 7 1 8 3 5 6 2 5 4 1 FIGURA 44: Representación de un grafo 80 6 Siguiendo el algoritmo de Kruskal, en nuestro software llamado ALGORITMOS VORACES, tenemos los siguientes pasos: o Elegimos, por ejemplo, la arista (5, 6) = 1 (menor valor) y la marcamos. o Elegimos la siguiente arista con menor valor (1, 3) = 1 y la marcamos. o Elegimos la siguiente arista con menor valor (5, 7) = 2 y la marcamos, ya que no forma ciclos con ninguna arista de las marcadas anteriormente. o Elegimos la siguiente arista con menor valor (1, 2) = 3 y la marcamos, ya que no forma ciclos con ninguna arista de las marcadas anteriormente. o Elegimos la siguiente arista con menor valor (6, 7) = 4 y la desechamos, ya que forma ciclos con las aristas (5, 7) y (5, 6) marcadas anteriormente. o Elegimos la siguiente arista con menor valor (2, 5) = 5 y la marcamos, ya que no forma ciclos con ninguna arista de las marcadas anteriormente. o Elegimos la siguiente arista con menor valor (4, 5) = 6 y la marcamos, ya que no forma ciclos con ninguna arista de las marcadas anteriormente. o FIN. Finalizamos dado que los 7 vértices del grafo están en alguna de las aristas, o también ya que tenemos marcadas 6 aristas (n-1). o Por tanto el árbol de mínima expansión resultante sería: 81 FIGURA 45: Representación de una Árbol de Expansión Mínima. COMO DISEÑAR UNA RED CABLEADA DE DATOS O TELEFONIA EN FORMA OPTIMA FIGURA 46: Dos Ejemplos de Árboles. Tenemos una área determinada donde existen una cantidad n de oficinas y en cada oficina uno o mas puntos de red, el punto es hacer el diseño correcto del cableado estructurado de esta red, de tal manera que utilicemos la menor cantidad posible de cable de red en unir todas las oficinas y los puntos de red que hay en ella. Utilizaremos, como se ve en la FIGURA 45, la topología de estrella. 82 La aplicación practica del Algoritmo Kruskal es la de encontrar un árbol generador mínimo es decir buscar un árbol donde los vértices y donde el valor de total de todas las aristas del árbol sea el mínimo posible Un árbol de peso mínimo es un árbol optimo. En el algoritmo de kruskal se tiene como origen a un grafo no dirigido, conexo y sin lazos. 23 ALGORITMO DE PRIM Este algoritmo fue diseñado en 1930 por el matemático Vojtech Jarnik y luego de manera independiente por el científico computacional Robert C. Prim en 1957 y redescubierto por Dijkstra en 1959. Por esta razón, el algoritmo es también conocido como algoritmo DJP o algoritmo de Jarnik. FIGURA 47: Robert C Prim El algoritmo de Prim es un algoritmo de la teoría de grafos para encontrar un árbol recubridor mínimo (MST) en un grafo conexo (igual que el algoritmo de kruskal), no 83 dirigido y cuyas aristas están etiquetados. Por así decirlo, dicho algoritmo encuentra un subconjunto de aristas que forman un árbol con todos los vértices, donde el peso total de todas las aristas en el árbol es el mínimo posible. Si el grafo no es conexo, entonces el algoritmo encontrara el árbol recubridor mínimo para uno de los componentes conexos que forman dicho grafo no conexo. A continuación se ilustrara el código en JAVA del algoritmo de prim, que puede servir de mucho para aplicaciones para comunicaciones y redes, bases de datos y otros temas de interés para la parte informática. CODIGO EN JAVA La idea básica consiste en añadir, en cada paso, una arista de peso mínimo a un árbol previamente construido. Más explícitamente: Paso 1. Se elige un vértice u de G y se considera el árbol S={u} Paso 2. Se considera la arista e de mínimo peso que une un vértice de S y un vértice que no es de S, y se hace S= S+e Paso 3. Si el nº de aristas de T es n-1 el algoritmo termina. En caso contrario se vuelve al paso 2 A continuación se muestra el código en java del algoritmo de prim: public class Algorithms 84 { public static Graph PrimsAlgorithm (Graph g, int s) { int n = g.getNumberOfVertices (); Entry[] table = new Entry [n]; for (int v = 0; v < n; ++v) table [v] = new Entry (); table [s].distance = 0; PriorityQueue queue = new BinaryHeap (g.getNumberOfEdges()); queue.enqueue ( new Association (new Int (0), g.getVertex (s))); while (!queue.isEmpty ()) { Association assoc = (Association) queue.dequeueMin(); Vertex v0 = (Vertex) assoc.getValue (); int n0 = v0.getNumber (); if (!table [n0].known) { table [n0].known = true; Enumeration p = v0.getEmanatingEdges (); while (p.hasMoreElements ()) { Edge edge = (Edge) p.nextElement (); Vertex v1 = edge.getMate (v0); int n1 = v1.getNumber (); Int wt = (Int) edge.getWeight (); int d = wt.intValue (); if (!table[n1].known && table[n1].distance>d) { table [n1].distance = d; table [n1].predecessor = n0; queue.enqueue ( new Association (new Int (d), v1)); } } } } Graph result = new GraphAsLists (n); for (int v = 0; v < n; ++v) result.addVertex (v); for (int v = 0; v < n; ++v) 85 if (v != s) result.addEdge (v, table [v].predecessor); return result; } } NOTA: Es importante saber que para la implementación del algoritmo de prim, fue necesario tomar como base la creación de una clase grafo, por lo que ya explicado en la definición de dicho algoritmo es basado o derivado a través de la teoría de grafos, por lo que es importante implementar un grafo, ya explicado en capítulos anteriores podrá ser fácil de implementar. DEMOSTRACION DEL ALGORITMO DE PRIM Sea G un grafo conexo y ponderado. En toda iteración del algoritmo de Prim, se debe encontrar una arista que conecte un vértice del sub-grafo a otro vértice fuera del sub-grafo. Ya que G es conexo, siempre habrá un camino para todo vértice. La salida Y del algoritmo de prim es un árbol porque las aristas y los vértices agregados a Y están conectados. Sea Y el árbol recubridor mínimo de G. Si Y1 = Y → Y es el árbol recubridor mínimo. Si no, sea e la primera arista agregada durante la construcción de Y, que no esta en Y1 y sea V el conjunto de vértices conectados por las aristas agregadas antes que e. Entonces un extremo de e esta en V y el otro no. Ya que Y1 es el árbol recubridor mínimo de G hay un camino en Y1 que une los dos extremos. Mientras que uno se mueve por el camino, se debe encontrar una arista f uniendo un vértice en V a uno que no esta en V. En la iteración que e se agrega a Y, f también se podría haber agregado y se hubiese agregado en vez de e si su peso fuera menor que el de e. Ya que f no se agrego se concluye: 86 P(f) ≥ P(e) Sea Y2 el grafo obtenido al remover f y agregando e € Y1. Es fácil mostrar que Y2 conexo tiene la misma cantidad de aristas que Y1, y el peso total de sus aristas no es mayor que el de Y1, entonces también es un árbol recubridor mínimo de G y contiene a e y todas las aristas agregadas anteriormente durante la construcción de V. Si se repiten los pasos esto demuestra que Y es el árbol recubridor mínimo de G. EJEMPLO DE EJECUCION PARA EL ALGORITMO DE PRIM EN EL SOFTWARE ALGORITMOS VORACES Estas imágenes son obtenidas en base de los resultados obtenidos en el software ALGORITMOS VORACES. IMAGEN DESCRIPCION Este es el grafo que será puesto de partida. No es un árbol ya que requiere que no haya circuitos y en este grafo los hay. Los números cerca de las aristas indican el peso. Ninguna de las aristas esta marcada, y el vértice D ha sido elegido arbitrariamente como el punto de partida. 87 No vistos En el grafo C, G A,B, E, F En el árbol D El segundo vértice es el más cercano a D: A esta a 5 de distancia, B a 9, E a 15 y F a 6. De estos, 5 es el valor mas pequeño, así que marcamos la arista DA. El próximo vértice a elegir es el mas cercano a D o A. B esta a 9 de distancia de D y a 7 de A, E esta a 15 y F esta a 6. 6 es el menor C, G B,E,F A,D C B,E,G A,D,F C,E,G A,D,F,B El algoritmo continúa. El vértice B que esta a una NULL distancia de 7 de A, es el siguiente marcado. En este punto la arista DB es marcada porque sus dos extremos ya están en el árbol y por lo tanto no podrá ser utilizado. 88 Aquí hay que elegir entre C, E Y G. C esta a 8 de distancia NULL de B, E esta a 7 de distancia de B, y G esta a 11 de distancia de F. E esta mas cerca, entonces marcamos el vértice E y la arista EB. Otras dos aristas fueron marcadas porque ambos vértices que unen fueron agregados al árbol. Solo quedan NULL disponibles C y G. C esta a 5 de distancia de E, y G a 9 de distancia de E. Se elige C, y se marca con el arco EC. El arco BC también se marca. G es el único vértice pendiente, y esta mas NULL cerca de E que de F, asi que se agrega EG al árbol. Todos los vértices están ya marcados, el árbol de expansión minimo se muestra. En este caso con un peso de 39. TABLA 5. TABLA DE COMPARACION PRIM Y KRUSKAL 89 C,G A,D,F,B,E G A,D,F,B,E, C NULL A,D,F,B,E, C,G Cada algoritmo tanto Kruskal como prim son de gran ayuda para implementaciones informáticas, lo importante es que cada una tiene su propia función, por lo cual es necesario que cuando se programe o se aplique cada una de ellas se haga con sus respectivos pasos. KRUSKAL PRIM Se marca la arista con menor valor. Si hay más de una, se elige cualquiera de ellas. Se marca un vértice cualquiera, será el vértice de partida. De las aristas restantes, se marca la que tenga menor valor, si hay más de una, se elige cualquiera de ellas. Seleccionamos la arista de menor valor incidente en el vértice marcado anteriormente, y marcamos el otro vértice en el que incide. Repetir el paso 2 siempre que la arista elegida no forme un ciclo con las ya marcadas. El proceso termina cuando tenemos todos los vértices del grafo en alguna de las aristas marcadas, es decir, cuando tenemos marcados n-1 aristas, siendo n el número de vértices del grafo. Repetir el paso 2 siempre que la arista elegida enlace un vértice marcado y otro que no lo este. El proceso termina cuando tenemos todos los vértices del grafo marcados. TABLA 6. Tabla comparativa para el manejo de los algoritmos de Kruskal y Prim. 90 24 BIBLIOGRAFIA ROSEN, K. Matemática Discreta y sus Aplicaciones 5o Edición. México: Mc Graww Hill. 2004 J. Gross, J. Yellen: "Graph Theory and its Applications" . CRC Press, 1999 GRIMALDI, R. Matemáticas Discretas y Combinatoria 3o Edición. México: Pearson. 1998 GARCIA, F. Matemática Discreta. México: Thompson. 2001 Redes De Computadoras 3Ed - Tanenbaum, Andrew STALLINGS W, SISTEMAS OPERATIVOS, 2ED PRENTICE HALL Introducción al diseño y análisis de algoritmos, McGraw hill Introducción a las bases de datos, prentice hall Paternostro, Carlos y Piedra, Viviana Algoritmos Voraces 2009 91 PONTIFICIA UNIVERSIDAD JAVERIANA FACULTAD DE CIENCIAS CARRERA DE INFORMATICA MATEMATICA APLICACIONES DE LA TEORIA DE GRAFOS EN LA INFORMÁTICA Autores: Carlos Paternostro Viviana Piedra Director: Gustavo Nieto CONTENIDO Introducción Proposito Formulacion del problema y justificacion Objetivos Grafos Historia Definicion Tipos de grafos Modelos de los grafos Aplicaciones Arboles Arbol Binario Arbol de decision y aplicaciones Software algoritmos voraces INTRODUCCIÓN La teoría de grafos también llamada teoría de las gráficas, es una disciplina que es importante tanto para las matemáticas como para la teoría de la computación. En esta última disciplina todo es manejado a través de los grafos que son estructuras discretas que constan de puntos y de líneas que se conectan entre sí. Es importante saber que existen diferentes tipos de grafos, que se distinguen entre si por el tipo y el número de líneas que pueden conectar para cada par de puntos. PROPOSITO Se encuentran muchos problemas informáticos que pueden ser resueltos a través de la teoría de grafos. El propósito principal es mostrar algunas de las aplicaciones que contienen la teoría de grafos y cómo se pueden resolver, con la ayuda de las matemáticas. Algunos de los temas relacionados con dichas aplicaciones son: Las estructuras de datos como los grafos. El diseño de circuitos planos. La solución de variados problemas en campos tan particulares como la teoría de juegos, redes telefónicas, eléctricas, bases de datos, sistemas operativos y de comunicaciones en general. FORMULACION DEL PROBLEMA Y JUSTIFICACION Formulación del problema El problema básicamente se centra en la falta de información sobre algunas aplicaciones informáticas desde un tema tan amplio como es la teoría de grafos. Lo que pretendemos solucionar es contar rápidamente con un texto, en el cual se puedan encontrar algunas de las más importantes aplicaciones informáticas en el ámbito de la teoría de grafos. Justificación de la investigación La finalidad de nuestro trabajo es proveer de un texto en donde se encuentren algunas de las más grandes e importantes aplicaciones informáticas, teoría y terminología básica de la teoría de grafos, a los estudiantes de informática matemática e ingeniería de Sistemas, los cuales apenas empiezan a estudiar la teoría de grafos y a comprender que ésta puede ser de gran ayuda para la ciencia de la computación ya que a través de ella se logran muchas de las aplicación mostradas alrededor de toda su carrera. OBJETIVOS Objetivo General: Conformar un proyecto que muestre algunas de las aplicaciones de la teoría de grafos en las redes de comunicaciones, manejo de información y secuencia de programas. Objetivos Específicos: Mostrar ejemplos y aplicaciones de la teoría de grafos en el diseño y estructura de redes de comunicaciones. Establecer situaciones donde se muestra la importancia de los grafos dirigidos en la ejecución de programas Diseñar estructuras de bases de datos mostrando la utilidad de los grafos a través de ejemplos ilustrados. HISTORIA DE LA TEORIA DE GRAFOS Sus ideas básicas las introdujo el matemático suizo Leonhard Paul Euler en el siglo XVIII. En 1736 realizó el trabajo de los puentes de Konigsberg. Euler demostró que no era posible puesto que el número de líneas que inciden en cada punto no es par, (condición necesaria para entrar y salir de un mismo punto). Así nació la teoría de grafos. Gustav Kirchhoff, quien publicó sus leyes de los circuitos para calcular el voltaje y la corriente en los circuitos eléctricos, usando grafos conexos de medida minima. El Problema de los cuatro colores En 1852 Francis Guthrie, se preguntó si sería posible demostrar matemáticamente que son suficientes cuatro tintas para colorear cualquier mapa de forma que países con frontera común tengan asignados colores distintos. GRAFOS Estructura que consta de un conjunto de puntos y lineas. REPRESENTACIÓN DE GRAFOS EN PROGRAMAS Representación mediante matrices Representación mediante listas TIPOS DE GRAFOS Grafo simple Grafo dirigido Multigrafo Pseudografo MODELOS CON GRAFOS Grafos de llamadas Grafo de la Red La red de Internet se puede representar mediante un grafo dirigido en el que cada pagina Web esta representada por un vértice y en el que una arista comienza en la pagina a y termina en la pagina b si hay un enlace en la pagina a que conduce a la pagina b. Grafos de precedencia y procesamiento concurrente Puede usarse un multigrafo dirigido para representar llamadas: cada vértice representa un número de teléfono y cada arista representa una llamada. La arista que representa una llamada sale del número del teléfono desde el que se hace la llamada y llega al número de que lo recibe. Los Sistemas Operativos, pueden ejecutarse más rápidamente si ciertas sentencias se ejecutan simultáneamente. Es importante no ejecutar sentencias que requieran el resultado de sentencias no ejecutadas. La dependencia de sentencias con respecto a sentencias previas se puede representar por medio de un grafo dirigido. Cada sentencia se representa por un vértice, y hay una arista de un vértice a un segundo si la sentencia representada por el segundo vértice no puede ejecutarse hasta la sentencia representada por el primero se ha ejecutado. Diseño de bases de datos Empresa: Vértices: Empleados, trabajos, departamentos y Empresa. Enlaces: La comunicación. APLICACIONES Un sistema de adquisición de datos supervisa continuamente un cierto proceso físico, para registrar su comportamiento, información cambios significativos y enviar comandos a un controlando de proceso. R (recoger), G (guardar), C (calcular), I (imprimir) y E (enviar) APLICACIONES INFORMÁTICAS EN GRAFOS BIPARTITOS Comparación de archivos de computador, utilizando el problema de la Longest Common Subsequence (LCS), en español Subsecuencia Común Más Larga. Dadas dos palabras X e Y sobre un alfabeto finito cualquiera, pretende encontrar cuál es el largo máximo que puede tener una palabra que sea subsecuencia de X e Y simultáneamente. El largo de una LCS se usa comúnmente como criterio de comparación de palabras, pues está relacionada con la cantidad de "pasos" necesarios para ir de una palabra a la otra mediante operaciones de inserción, eliminación y reemplazo de caracteres. Todo par de palabras puede representarse convenientemente como un grafo bipartito donde los arcos unen a los caracteres coincidentes de ambas palabras. Un matching en un grafo arbitrario (no necesariamente bipartito) es cualquier conjunto de arcos que no comparten extremos; un PM es un matching en donde los arcos no se cruzan ni comparten extremos. Así, calcular la LCS entre dos palabras no es más que calcular el matching planar de costo máximo del grafo bipartito asociado a dichas palabras, donde todos los arcos tienen costo igual a 1. ATMIA APLICACIONES INFORMATICAS PARA LA CONEXIÓN ENTRE GRAFOS ( I ) Seguridad para las bases de datos de una empresa Funciones a diferentes departamentos para el manejo de inserción, eliminación y actualización de los diferentes empleados que trabajan para cada departamento. E= Empresa DS= Departamento de sistemas DC= Departamento de contaduría DG= Departamento para la gerencia ES= Empleados para el departamento de sistemas EC= Empleados para el departamento de contabilidad EG= Empleados que hacen parte con la gerencia de la empresa APLICACIONES INFORMATICAS PARA LA CONEXIÓN ENTRE GRAFOS ( II ) Redes de comunicaciones móviles. Los patrones de comunicación de millones de usuarios de teléfonos móviles, los grafos permiten estudiar simultáneamente la estructura local y la global de una sociedad en toda la red de comunicación, en las cuales se observan acoplamientos entre la interacción fuertes y una red de la estructura local. Cada enlace representa la comunicación mutua entre los usuarios de la red de comunicación, y todos los nodos que se muestran son la distancia inferior a seis desde usuario seleccionado, marcado por un círculo en el centro. ÁRBOLES Un árbol es un grafo sin circuitos. Se usarán árboles siempre que se quiera representar información jerarquizada, cuando esta converja en un solo punto. ARBOL BINARIO Un árbol binario es el que cumple que el subárbol izquierdo de cualquier nodo (si no está vacío) contiene valores menores que el que contiene dicho nodo, y el subárbol derecho (si no está vacío) contiene valores mayores. Usos comunes de los árboles binarios son los árboles binarios de búsqueda y codificación de huffman. ÁRBOLES DE DECISIÓN Un árbol de decisión es un modelo de predicción utilizado en el ámbito de la inteligencia artificial. Dada una base de datos se construyen estos diagramas de construcciones lógicas. Puede Contener: Un vértice interno contiene un test sobre algún valor de una de las propiedades. Un vértice de probabilidad indica que debe ocurrir un evento aleatorio de acuerdo a la naturaleza del problema, este tipo de vértices es redondo, los demás son cuadrados. Un vértice hoja representa el valor que devolverá el árbol de decisión. Las ramas brindan los posibles caminos que se tienen de acuerdo a la decisión tomada. Los árboles de decisión se utilizan en cualquier proceso que implique toma de decisiones, ejemplos de estos procesos son: Búsqueda Binaria Sistemas Expertos Árboles de juegos APLICACIONES INFORMATICAS DE ÁRBOLES DE DECISION ( I ) CODIFICACION DE HUFFMAN Este algoritmo fue usado para compresión de datos. El termino se refiere al uso de una tabla de códigos de longitud variable para codificar un determinado símbolo (como puede ser un caracter en un archivo), donde la tabla ha sido rellenada de una manera específica basándose en la probabilidad estimada de aparición de cada posible valor de dicho símbolo. La codificación Huffman usa un método específico para elegir la representación de cada símbolo, que da lugar a un código prefijo (es decir, la cadena de bits que representa a un símbolo en particular nunca es prefijo de la cadena de bits de un símbolo distinto) que representa los caracteres más comunes usando las cadenas de bits más cortas, y viceversa. EJEMPLO FRASE a codificar: "Esto es un ejemplo de árbol de Huffman". APLICACIONES INFORMATICAS DE ÁRBOLES DE DECISION ( II ) Haremos una tabla para representar cada carácter es importante saber su numero de frecuencia, y su código, es bueno organizar cada carácter de mayor a menor, esto significa que aquel carácter que tenga el numero de frecuencia mayor será el primero y así sucesivamente (frecuencia asumirlo como numero de repeticiones que presenta un carácter). CARÁCTER FRECUENCIA CODIGO Espacio 7 00 E 6 100 O 3 1100 N 2 1110 U 2 0100 S 2 0101 M 2 1010 F 2 1011 L 2 0110 D 2 0111 A 2 11010 B 1 110110 H 1 110111 J 1 111100 P 1 111101 R 1 111110 T 1 111111 ARBOL REPRESENTACION CODIFICACION DE HUFFMAN APLICACIONES INFORMATICAS DE ÁRBOLES DE DECISION ( III ) Árboles de decisión en una crisis empresarial. El análisis de la crisis empresarial se configura como un aspecto clave en el análisis de estados financieros al permitir a la empresa disponer de un sistema de diagnóstico que abarque los aspectos de solvencia y de rentabilidad. Un árbol de decisión representa la relación existente entre la conclusión-decisión y sus atributos. Importe (menor de 100.000, entre 100.000 y 500.000, mayor de 500.000) Solvencia (alta, media y baja) APLICACIONES INFORMATICAS DE ÁRBOLES DE DECISION ( V ) Arboles de juego Genera el árbol de acuerdo al nivel de previsión y cada jugador va decidiendo que jugada le conviene más de acuerdo a la evaluación de una determinada posición. APLICACIONES INFORMATICAS DE ÁRBOLES DE DECISION ( IV ) Árboles de decisión utilizados en sistemas expertos. Puede llegar a ser lento pues analiza todas las posibilidades pero esto a su vez es lo que lo vuelve mas preciso que al hombre. ARBOL RECUBRIDOR Dado un grafo conexo, un árbol recubridor de ese grafo es un sub-grafo que es un árbol y conecta todos los vértices. Se le puede asignar un peso a cada arista, que es un número que representa qué tan adecuado es, y se usa para asignar un peso al árbol recubridor mínimo computando la suma de todos los pesos de las aristas del árbol en cuestión. Un árbol recubridor o un árbol expandido es un árbol recubridor que pesa menos o igual que otros árboles recubridores. Todo grafo tiene un bosque recubridor mínimo. El árbol recubridor es usado frecuentemente para algoritmos informáticos, los algoritmos más destacados se explicaran a continuación. SOFTWARE ALGORITMOS VORACES ALGORITMO DE KRUSKAL Encuentra el árbol recubridor mínimo en un grafo conexo y ponderado. Algoritmo: 1. 2. 3. 4. Se marca la arista con menor valor. Si hay más de una, se elige cualquiera de ellas. De las aristas restantes, se marca la que tenga menor valor, si hay más de una, se elige cualquiera de ellas. Repetir el paso 2 siempre que la arista elegida no forme un ciclo con las ya marcadas. El proceso termina cuando tenemos todos los vértices del grafo en alguna de las aristas marcadas, es decir, cuando tenemos marcados n-1 arcos, siendo n el número de vértices del grafo. Public Sub kruskal() Dim ut As Integer = 0 Call traskruskal() 'se va escogiendo el menor de la matriz que no tenga los dos destinos conectados Dim i As Integer = 0, j As Integer = 0 Dim menorvalor As Integer = 15000 Dim nodotemp As New nodoPeso indParejas = 0 Do While kruskalVisitoTodos() = False For i = 0 To maxNodos For j = 0 To maxNodos If MatGrafokruskal(i, j) <> 0 And MatGrafokruskal(i, j) < menorvalor And kruskal_conectados(i, j) = False Then nodotemp.nodepeso = MatGrafokruskal(i, j) nodotemp.inicio = i nodotemp.fin = j menorvalor = MatGrafokruskal(i, j) End If Next Next vectorparejaK(indParejas).a = nodotemp.inicio vectorparejaK(indParejas).b = nodotemp.fin indParejas += 1 VectVisitaKruskal(indiceVisitasK) = nodotemp.inicio indiceVisitasK += 1 VectVisitaKruskal(indiceVisitasK) = nodotemp.fin indiceVisitasK += 1 MatGrafoKruskaldibuja(nodotemp.inicio, nodotemp.fin) = nodotemp.nodepeso menorvalor = 15000 Loop Dim m As Integer, n As Integer, q As Integer, s As Integer For i = 0 To maxNodos ut = 0 For j = 0 To maxNodos ut += MatGrafoKruskaldibuja(i, j) Next If ut = 0 Then n = 15000 q = -1 For m = 0 To maxNodos If Kruskal_conectados2(i, m) = False And MatGrafokruskal(i, m) < n And MatGrafokruskal(i, m) <> 0 And DijkstraKruskal(i, m) = False Then n = MatGrafokruskal(i, m) q=m s=i End If Next If q <> -1 Then MatGrafoKruskaldibuja(s, q) = 1 End If End If Next End Sub Public Sub traskruskal() Dim i As Integer, j As Integer For i = 0 To maxNodos For j = 0 To maxNodos MatGrafokruskal(i, j) = MatGrafo(i, j) Next Next End Sub SOFTWARE ALGORITMOS VORACES ALGORITMO DE DIJKSTRA También conocido como ruta más corta; a partir de un vértice determinado se obtienen todas las rutas más cortas hacia todos los demás vértices. Los pasos a seguir para el algoritmo son: 1. 2. 3. 4. 5. 6. 7. 8. 9. Conocer el vértice de origen y el vértice de destino. Marcar el vértice de origen y conocer a sus vecinos Mirar los costos de las rutas hacia sus vecinos Marcar el vecino de la ruta más corta El vecino marcado se convierte en el nuevo vértice de origen Hace paso 2 y 3 Comparar todas las rutas que hay de sus vecinos y no vecinos no marcados que ya tengan costo asociado. Obtener el vértice de costo mínimo asociado y marcarlo Volver a el paso 2 Vértice 1 2 3 4 5 6 7 Ruta - 1,2 1,3 1,4 1,3,5 1,3,6 1,3,5,7 Costo 0 9 7 8 10 12 18 Public Sub Dijkstra() Dim nNodo As Integer = InputBox("Digite la id del vertice inicio:", "", "1") nNodo -= 1 Dim i As Integer = 0 TextBox1.Text = "" For i = 0 To indiceNodos - 2 ap.Clear() If i <> nNodo Then ValorMinimo = 20000 indRecorridoDij = 0 ap.Add(nNodo) digcal(nNodo, nNodo, nNodo, i, 0) TextBox1.Text = TextBox1.Text & vbNewLine & "V[" & CStr(nNodo + 1) & "]-[" & CStr(i + 1) & "] menor peso: " & ValorMinimo & " Lista : " & ImpListaRec() End If Public Function digcal(ByVal porigen As Integer, ByVal DondeVengo As Integer, ByVal dondeEstoy As Integer, ByVal dondeVoy As Integer, ByVal suma As Integer) As Integer Dim val1 As Integer = 0 Dim val2 As Boolean = False Dim i As Integer If dondeEstoy = dondeVoy Then 'se encontro If suma < ValorMinimo Then ValorMinimo = suma indRecorridoDij = 0 For i = 0 To ap.Count - 1 recorridoDij(i).a = ap(i) Next indRecorridoDij = ap.Count End If Return suma Else Dim res As Integer For i = 0 To maxNodos val1 = MatGrafoDijkstra(dondeEstoy, i) val2 = estaLista(i) If val1 <> 0 And val2 = False And i <> dondeEstoy Then ap.Add(i) res = digcal(porigen, dondeEstoy, i, dondeVoy, suma + MatGrafoDijkstra(dondeEstoy, i)) ap.Remove(i) End If Next End If End Function SOFTWARE ALGORITMOS VORACES ALGORITMO DE PRIM El algoritmo de Prim es un algoritmo de la teoría de grafos para encontrar un árbol recubridor mínimo (MST) en un grafo conexo (igual que el algoritmo de kruskal), no dirigido y cuyas aristas están etiquetados. Si el grafo no es conexo, entonces el algoritmo encontrara el árbol recubridor mínimo para uno de los componentes conexos que forman dicho grafo no conexo. Dim inicio As Integer = 0 Dim i As Integer Dim menorE As New nodoPeso Dim menorEM As New nodoPeso Dim menorvalor As Integer = 15000 Call trasprim() Call limpiarVisitas() vectVisitaNodo(indiceVisitas) = inicio indiceVisitas += 1 Do While primVisitoTodos() = False menorvalor = 15000 For i = 0 To indiceVisitas - 1 menorE = NodoMenor(vectVisitaNodo(i)) If menorE.nodepeso < menorvalor And menorE.nodepeso <> 0 Then 'colocar en una varuable vectVisitaNodo(i) y el fin que es nodoE menorvalor = menorE.nodepeso menorEM.inicio = vectVisitaNodo(i) menorEM.nodoE = menorE.nodoE menorEM.nodepeso = menorE.nodepeso End If If visitado(menorEM.nodoE) = False Then ' no ha sdo visitado vectVisitaNodo(indiceVisitas) = menorEM.nodoE indiceVisitas += 1 'dibuje el arco entre vectVisitaNodo(i) y menor e MatGrafoPrimdibuja(menorEM.inicio, menorEM.nodoE) = menorEM.nodepeso End If Loop menorvalor = 15000 End Sub Public Sub trasprim() Dim i As Integer, j As Integer For i = 0 To maxNodos For j = 0 To maxNodos MatGrafoPrim(i, j) = MatGrafo(i, j) Next Next For i = 0 To maxNodos For j = 0 To maxNodos If MatGrafoPrim(j, i) <> 0 Then MatGrafoPrim(i, j) = MatGrafoPrim(j, i) End If Next Next Next End Sub SOFTWARE ALGORITMOS VORACES IMAGEN DESCRIPCION No vistos En el grafo En el árbol Este es el grafo que será puesto de partida. No es un árbol ya que requiere que no haya circuitos y en este grafo los hay. Los números cerca de las aristas indican el peso. Ninguna de las aristas esta marcada, y el vértice D ha sido elegido arbitrariamente como el punto de partida. C, G A, B, E, F D El segundo vértice es el más cercano a D: A esta a 5 de distancia, B a 9, E a 15 y F a 6. De estos, 5 es el valor mas pequeño, así que marcamos la arista DA. C, G B, E, F A, D El próximo vértice a elegir es el mas cercano a D o A. B esta a 9 de distancia de D y a 7 de A, E esta a 15 y F esta a 6. 6 es el menor C B, E, G A, D, F SOFTWARE ALGORITMOS VORACES El algoritmo continúa. El vértice B que esta a una distancia de 7 de A, es el siguiente marcado. En este punto la arista DB es marcada porque sus dos extremos ya están en el árbol y por lo tanto no podrá ser utilizado. NULL C,E,G A,D,F,B Aquí hay que elegir entre C, E Y G. C esta a 8 de distancia de B, E esta a 7 de distancia de B, y G esta a 11 de distancia de F. E esta mas cerca, entonces marcamos el vértice E y la arista EB. Otras dos aristas fueron marcadas porque ambos vértices que unen fueron agregados al árbol. NULL C,G A,D,F,B,E Solo quedan disponibles C y G. C esta a 5 de distancia de E, y G a 9 de distancia de E. Se elige C, y se marca con el arco EC. El arco BC también se marca. NULL G A,D,F,B,E, C G es el único vértice pendiente, y esta mas cerca de E que de F, asi que se agrega EG al árbol. Todos los vértices están ya marcados, el árbol de expansión minimo se muestra. En este caso con un peso de 39. NULL NULL A,D,F,B,E, C,G MUCHAS GRACIAS