Aprendizaje Interactivo de Teoría de Grafos
Aprendizaje Interactivo de Teoría de Grafos
Guest User
Using app without sign in
Buscador de componentes fuertemente conexas
Halla componentes fuertemente conexas con dos recorridos y el grafo transpuesto
Selecciona un algoritmo y genera pasos para comenzar la visualización
El algoritmo de Kosaraju calcula las componentes fuertemente conexas de un grafo dirigido con dos pasadas de búsqueda en profundidad, una sobre el grafo original y otra sobre su traspuesta (todas las aristas invertidas). Es conceptualmente el algoritmo lineal de SCC más simple.
La primera DFS registra los vértices en orden decreciente de tiempo de finalización. Luego se traspone el grafo y una segunda DFS procesa los vértices en ese orden; cada árbol formado en la segunda pasada es exactamente una componente fuertemente conexa. La corrección se debe a que invertir las aristas conserva las SCC pero rompe las conexiones entre ellas. Dos pasadas lineales dan O(V + E) en total.
El algoritmo de Kosaraju sirve a las mismas aplicaciones que el de Tarjan: solucionadores 2-SAT, análisis de compiladores, estructura de comunidades en redes sociales y condensación de dependencias. Su estructura de dos pasadas es más fácil de explicar e implementar desde cero, lo que lo hace una respuesta de entrevista popular para hallar SCC.
Dos búsquedas en profundidad y un grafo transpuesto. Dentro de cada pasada no ocurre nada ingenioso; todo el trabajo lo hace el orden en que se ejecuta la segunda.
Kosaraju(grafo):
// Pasada 1: registrar el orden de finalización
orden = []
para cada u no visitado: dfs1(u)
dfs1(u): marcar u visitado
para cada arista (u,v): si no visitado: dfs1(v)
orden.añadir(u) // al terminar
// Pasada 2: DFS sobre la transpuesta en orden inverso
gt = transponer(grafo) // invertir cada arista
para cada u en inverso(orden):
si u no visitado:
el árbol que crece desde u en gt es una SCCPor qué funciona: invertir todas las aristas deja intactas las componentes fuertemente conexas, ya que si podías ir de x a y y volver, sigues pudiendo. Lo que sí cambia la inversión es la dirección de las aristas entre componentes. Empezar por el vértice que terminó el último garantiza que arrancas en una componente que es fuente de la condensación, de modo que el segundo DFS no puede escaparse de ella hacia otra componente.
Ejecuta Kosaraju sobre el mismo grafo dirigido usado en el ejemplo de Tarjan, para poder compararlos directamente.
Grafo de ejemplo: Aristas dirigidas A a B, B a C, C a A, B a D, D a E, E a D, y C a F.
Las componentes son {A, B, C}, luego {D, E}, luego {F}. Compáralo con Tarjan sobre el mismo grafo, que emite {F}, luego {D, E}, luego {A, B, C}. Ambos son correctos y ambos hallan las mismas tres componentes, pero Kosaraju las emite en orden topológico directo de la condensación mientras que Tarjan las emite en orden inverso. Si a tu código posterior le importa el orden, esa diferencia es la razón para elegir uno u otro.
Tiempo: O(V + E) · Espacio: O(V + E)
Dos búsquedas en profundidad cuestan O(V + E) cada una, y construir el grafo transpuesto requiere una pasada sobre todas las aristas, también O(V + E). Sumando queda O(V + E) en total. El espacio es donde Kosaraju pierde de verdad frente a Tarjan: debe almacenar la estructura de adyacencia transpuesta, que es una segunda copia completa de la lista de aristas con O(V + E), mientras que Tarjan solo necesita O(V) de contabilidad sobre el grafo original. En un grafo con decenas de millones de aristas esa diferencia es el factor decisivo, y por eso Tarjan suele ganar en producción aunque los dos sean idénticos en tiempo asintótico.
Todos los algoritmos lineales de SCC cuestan O(V + E). Las diferencias están en memoria, número de pasadas y facilidad para escribir el código correctamente.
| Alternativa | Prefiérela cuando | Coste |
|---|---|---|
| Algoritmo de Tarjan | Una pasada, sin transpuesta, O(V) de espacio extra. Preferible cuando la memoria importa o el grafo es enorme. | O(V + E), una pasada |
| SCC basado en caminos | Una pasada como Tarjan, pero con dos pilas explícitas en lugar de aritmética de low-link. A algunos les resulta más fácil de razonar. | O(V + E) |
| Condensación a un DAG | Las componentes son un medio y no un fin. Kosaraju te las entrega ya en orden topológico directo. | O(V + E) |
| Union-Find | El grafo es no dirigido, donde las componentes conexas son un problema mucho más simple. | O(E·α(V)) |
Leer el artículo completo: Graph Algorithms and Their Complexity
Algoritmos relacionados: Algoritmo de Tarjan (CFC), Búsqueda en Profundidad