¿Qué es un Grafo?

Un grafo es una estructura de datos que se utiliza para representar relaciones entre pares de objetos. Los grafos están compuestos por:

  • Vértices (o nodos): Representan los objetos.
  • Aristas (o enlaces): Representan las relaciones entre los objetos.

Terminología Básica

  • Vértice (Nodo): Un punto en el grafo.
  • Arista (Enlace): Una conexión entre dos vértices.
  • Grado de un vértice: Número de aristas que inciden en un vértice.
  • Camino: Una secuencia de vértices conectados por aristas.
  • Ciclo: Un camino que comienza y termina en el mismo vértice.
  • Grafo dirigido (Digrafo): Las aristas tienen una dirección.
  • Grafo no dirigido: Las aristas no tienen dirección.
  • Grafo ponderado: Las aristas tienen un peso asociado.

Ejemplo de un Grafo

Consideremos un grafo no dirigido con 4 vértices y 4 aristas:

  A -- B
  |    |
  C -- D

En este grafo:

  • Los vértices son A, B, C y D.
  • Las aristas son (A-B), (A-C), (B-D) y (C-D).

Tipos de Grafos

Grafos Dirigidos y No Dirigidos

  • Grafo Dirigido (Digrafo): Las aristas tienen una dirección, representada por flechas.

    • Ejemplo: Un grafo que representa las rutas de vuelo entre ciudades, donde cada arista indica la dirección del vuelo.
    A → B
    ↓   ↑
    C → D
    
  • Grafo No Dirigido: Las aristas no tienen dirección.

    • Ejemplo: Un grafo que representa las conexiones de amistad en una red social.
    A -- B
    |    |
    C -- D
    

Grafos Ponderados y No Ponderados

  • Grafo Ponderado: Las aristas tienen un peso asociado, que puede representar distancia, costo, tiempo, etc.

    • Ejemplo: Un grafo que representa las distancias entre ciudades.
    A --5-- B
    |      |
    2      3
    |      |
    C --4-- D
    
  • Grafo No Ponderado: Las aristas no tienen peso.

    • Ejemplo: Un grafo que representa las conexiones de amistad en una red social.
    A -- B
    |    |
    C -- D
    

Representación de Grafos

Matriz de Adyacencia

Una matriz de adyacencia es una forma de representar un grafo mediante una matriz 2D. Si hay una arista entre el vértice i y el vértice j, entonces matriz[i][j] es 1 (o el peso de la arista en un grafo ponderado), de lo contrario, es 0.

Ejemplo de una matriz de adyacencia para un grafo no dirigido:

  A B C D
A 0 1 1 0
B 1 0 0 1
C 1 0 0 1
D 0 1 1 0

Lista de Adyacencia

Una lista de adyacencia es una forma de representar un grafo mediante una lista donde cada vértice tiene una lista de los vértices adyacentes.

Ejemplo de una lista de adyacencia para un grafo no dirigido:

A: B, C
B: A, D
C: A, D
D: B, C

Ejemplo Práctico en Python

A continuación, se muestra cómo representar un grafo utilizando una lista de adyacencia en Python:

class Grafo:
    def __init__(self):
        self.grafo = {}

    def agregar_vertice(self, vertice):
        if vertice not in self.grafo:
            self.grafo[vertice] = []

    def agregar_arista(self, vertice1, vertice2):
        if vertice1 in self.grafo and vertice2 in self.grafo:
            self.grafo[vertice1].append(vertice2)
            self.grafo[vertice2].append(vertice1)  # Para grafos no dirigidos

    def mostrar_grafo(self):
        for vertice in self.grafo:
            print(f"{vertice}: {', '.join(self.grafo[vertice])}")

# Crear un grafo
g = Grafo()
g.agregar_vertice('A')
g.agregar_vertice('B')
g.agregar_vertice('C')
g.agregar_vertice('D')

# Agregar aristas
g.agregar_arista('A', 'B')
g.agregar_arista('A', 'C')
g.agregar_arista('B', 'D')
g.agregar_arista('C', 'D')

# Mostrar el grafo
g.mostrar_grafo()

Explicación del Código

  1. Clase Grafo: Define la estructura del grafo.
  2. Método agregar_vertice: Agrega un vértice al grafo.
  3. Método agregar_arista: Agrega una arista entre dos vértices.
  4. Método mostrar_grafo: Muestra el grafo en formato de lista de adyacencia.

Ejercicio Práctico

Ejercicio 1

Crea un grafo dirigido que represente las siguientes relaciones:

A → B
A → C
B → D
C → D
D → A

Solución

class GrafoDirigido:
    def __init__(self):
        self.grafo = {}

    def agregar_vertice(self, vertice):
        if vertice not in self.grafo:
            self.grafo[vertice] = []

    def agregar_arista(self, vertice1, vertice2):
        if vertice1 in self.grafo:
            self.grafo[vertice1].append(vertice2)

    def mostrar_grafo(self):
        for vertice in self.grafo:
            print(f"{vertice}: {', '.join(self.grafo[vertice])}")

# Crear un grafo dirigido
g = GrafoDirigido()
g.agregar_vertice('A')
g.agregar_vertice('B')
g.agregar_vertice('C')
g.agregar_vertice('D')

# Agregar aristas
g.agregar_arista('A', 'B')
g.agregar_arista('A', 'C')
g.agregar_arista('B', 'D')
g.agregar_arista('C', 'D')
g.agregar_arista('D', 'A')

# Mostrar el grafo
g.mostrar_grafo()

Explicación del Código

  1. Clase GrafoDirigido: Define la estructura del grafo dirigido.
  2. Método agregar_vertice: Agrega un vértice al grafo.
  3. Método agregar_arista: Agrega una arista dirigida entre dos vértices.
  4. Método mostrar_grafo: Muestra el grafo en formato de lista de adyacencia.

Conclusión

En esta lección, hemos introducido los conceptos básicos de los grafos, incluyendo su terminología, tipos y formas de representación. También hemos visto ejemplos prácticos de cómo implementar grafos en Python. En la próxima lección, profundizaremos en las diferentes formas de representar grafos y exploraremos algoritmos de búsqueda en grafos.

© Copyright 2024. Todos los derechos reservados