WhatsApp

  

Algoritmo Laplaciano de un Grafo: Teoría, Implementación en Python y Buenas Prácticas

Guía completa sobre el Laplaciano de grafos, su cálculo, aplicaciones y ejemplos prácticos en Python con NetworkX, NumPy y SciPy.

Algoritmo Laplaciano de un Grafo

Introducción

El Laplaciano de un grafo es una matriz que captura la conectividad estructural de una red. Se utiliza en áreas como clustering espectral, segmentación de imágenes, optimización de redes y machine learning sobre grafos. En este artículo explicaremos su definición matemática, propiedades clave y cómo calcularlo de forma eficiente en Python.

Definiciones fundamentales

  • Matriz de adyacencia (A): A_{ij}=1 si existe una arista entre los vértices i y j, 0 en caso contrario.
  • Matriz de grado (D): matriz diagonal donde D_{ii}=\sum_j A_{ij}, es decir, el grado del vértice i.
  • Laplaciano no normalizado (L): L = D - A.
  • Laplaciano normalizado (L_{sym}): L_{sym}= I - D^{-1/2} A D^{-1/2}.
  • Laplaciano de paseo aleatorio (L_{rw}): L_{rw}= I - D^{-1} A.

Propiedades clave

  • Es simétrica y semidefinida positiva (para grafos no dirigidos).
  • El menor valor propio es siempre 0. La multiplicidad del 0 corresponde al número de componentes conexos.
  • Los vectores propios asociados a los valores propios más pequeños revelan la estructura de comunidad del grafo.

Cálculo del Laplaciano en Python

Utilizaremos NetworkX para generar grafos y NumPy/SciPy para operar con matrices densas o esparcidas.

Ejemplo 1: Grafo pequeño (matriz densa)


import networkx as nx
import numpy as np
# Crear un grafo no dirigido simple
G = nx.Graph()
G.add_edges_from([(0,1), (1,2), (2,3), (3,0), (0,2)])
# Matriz de adyacencia y de grado
A = nx.adjacency_matrix(G).todense()
D = np.diag([d for n,d in G.degree()])
# Laplaciano no normalizado
L = D - A
print('Laplaciano L:\n', L)
    

Ejemplo 2: Grafo grande (matriz esparcida) y Laplaciano normalizado


import networkx as nx
import scipy.sparse as sp
# Generar un grafo aleatorio de Erdos‑Renyi con 10,000 nodos y p=0.001
n = 10000
p = 0.001
G = nx.erdos_renyi_graph(n, p, seed=42)
# Matriz de adyacencia esparcida
A = nx.adjacency_matrix(G)  # formato CSR
# Grados como vector
deg = A.sum(axis=1).A1
D_inv_sqrt = sp.diags(1.0/np.sqrt(deg))
# Laplaciano normalizado L_sym = I - D^{-1/2} A D^{-1/2}
I = sp.identity(n, format='csr')
L_sym = I - D_inv_sqrt @ A @ D_inv_sqrt
print('Laplaciano normalizado (esparcido) creado. Shape:', L_sym.shape)
    

Comparativa de variantes del Laplaciano

Laplaciano no normalizado (L)

  • Fácil de interpretar.
  • Requiere la matriz de grado completa.
  • Escala con el grado máximo del grafo.
  • Uso típico en teoría espectral básica.

Laplaciano normalizado (Lsym y Lrw)

  • Elimina la dependencia del tamaño del grado.
  • Más estable numéricamente para grafos heterogéneos.
  • Lsym es simétrico → eigen‑descomposición directa.
  • Lrw se interpreta como operador de paseo aleatorio.

Aplicaciones típicas

  1. Clustering espectral: usar los k menores vectores propios de Lsym como embeddings y aplicar k‑means.
  2. Detección de comunidades: el valor propio algebraico (Fiedler) indica cuán “cortable” es el grafo.
  3. Reducción de dimensionalidad en grafos de alta dimensión.
  4. Simulación de procesos de difusión (p. ej., propagación de información).

Rendimiento y escalabilidad

El cálculo directo de eigen‑valores con matrices densas tiene complejidad O(n³), lo cual es inviable para grafos con millones de nodos. Las estrategias recomendadas son:

  • Utilizar matrices esparcidas (SciPy csr_matrix).
  • Aplicar algoritmos iterativos como scipy.sparse.linalg.eigsh o lobpcg que solo requieren multiplicaciones matriciales.
  • Emplear GPU con cuGraph para grafos extremadamente grandes.
  • Dividir el grafo en sub‑componentes y procesarlos en paralelo (p. ej., con Dask o Ray).

Resolución de problemas comunes (troubleshooting)

  • Errores de división por cero al normalizar grados cero. Solución: eliminar nodos aislados o añadir un pequeño epsilon (1e-10) al denominador.
  • Memoria insuficiente al convertir una matriz esparcida a densa. Solución: mantener siempre el formato csr y usar funciones esparcidas para eigen‑descomposición.
  • Convergencia lenta de eigsh. Solución: proporcionar un buen vector de inicio (v0) o usar which='SM' para los menores valores propios.

Buenas prácticas y recomendaciones

  • Siempre validar que el grafo sea no dirigido antes de usar el Laplaciano simétrico.
  • Preferir el Laplaciano normalizado cuando los grados varían mucho.
  • Documentar versiones de librerías (networkx>=3.0, numpy>=1.26, scipy>=1.12) para reproducibilidad.
  • Usar tipos de datos float32 en GPUs para reducir consumo de memoria sin perder precisión significativa.

© 2025 BlogTech – Todos los derechos reservados.



Algoritmo Laplaciano de un Grafo: Teoría, Implementación en Python y Buenas Prácticas
ASIMOV Ingeniería S. de R.L. de C.V., Emiliano Nava 13 noviembre, 2025
Compartir
Iniciar sesión dejar un comentario

  
Algoritmos de Matrices y Grafos en Python: Guía Completa con Ejemplos Prácticos
Aprende a implementar y optimizar algoritmos clásicos de matrices y grafos en Python con ejemplos detallados, comparativas de estructuras y buenas prácticas para rendimiento y escalabilidad.