τTau SolutionsApéndices

Grafos y expresiones regulares

Avanzado · Actualizado el 16 de agosto de 2026

Este apéndice recoge las definiciones y resultados sobre grafos que los capítulos «4», «7» y «14» usan: caminos, ciclos, componentes fuertemente conexas, bosques y árboles, dominadores, y el orden inverso de postorden, que es el que hace rápidos los algoritmos de lista de trabajo. Cierra con las expresiones regulares de caminos, base de los métodos de eliminación.

C.1 Grafos, caminos y ciclos

Un grafo dirigido (digraph) G = (N, A) consta de un conjunto finito N de nodos y un conjunto A ⊆ N × N de aristas. Una arista (n₁, n₂) tiene origen n₁ y destino n₂, y se dice que va de n₁ a n₂; si n₁ = n₂ es un bucle propio (self-loop). Cuando no hay bucles propios se habla simplemente de grafo.

Un camino dirigido, o camino a secas, del nodo n₀ al nodo nm es una secuencia de aristas (n₀,n₁), (n₁,n₂), …, (nm-1, nm) en la que el destino de cada arista es el origen de la siguiente. Su origen es n₀, su destino nm, y su longitud es m ≥ 0. El camino es trivial si m = 0, y vacío si la secuencia de aristas es vacía. La concatenación de dos caminos con destino y origen coincidentes es un camino. Diremos que n' es alcanzable desde n si existe un camino, posiblemente trivial, de n a n'.

Se escribe el camino por la secuencia de nodos visitados,

p = [n₀, n₁, n₂, …, nm]

y se define el conjunto de caminos de n a n':

pathsA(n, n') = \{ [n₀,…,nm] : m ≥ 0 ∧ n₀ = n ∧ nm = n' ∧ ∀i < m . (nᵢ, ni+1) ∈ A \}

Un ciclo es un camino no trivial de un nodo a sí mismo; el caso m = 1 es el bucle propio. Los ciclos de n a n son

cycles(n) = \{ [n₀,…,nm] : m ≥ 1 ∧ n₀ = n ∧ nm = n \}

y se observa que cycles(n) = { p ∈ pathsA(n,n) : p ≠ [n] }. Un ciclo [n₀,…,nm] es de entrada múltiple (multiple entry) si contiene dos nodos distintos n₁ y n₂ a los que se puede llegar desde fuera del ciclo. Ésa es exactamente la caracterización de la irreducibilidad del capítulo «4».

Un grafo sin ciclos es acíclico; un grafo dirigido acíclico es un DAG. Una ordenación topológica de un grafo dirigido es un orden total sobre sus nodos tal que si (n, n') ∈ A entonces n va estrictamente antes que n'. Un grafo dirigido admite ordenación topológica si y sólo si es acíclico.

C.2 Componentes fuertemente conexas

Dos nodos n y n' son fuertemente conexos si hay un camino, posiblemente trivial, de n a n' y otro de n' a n. Definiendo

SC = \{ (n, n') : n\ y\ n'\ son\ fuertemente\ conexos \}

se obtiene una relación binaria sobre N.

En el CFG de un programa escrito en un lenguaje estructurado, el cuerpo de un bucle constituye una componente fuertemente conexa, y esto vale tanto para el grafo de flujo hacia adelante como para el invertido. Es la base del algoritmo de iteración por componentes fuertemente conexas mencionado en el capítulo «7»: se resuelve componente a componente, en orden topológico del grafo reducido, y dentro de cada una se itera hasta punto fijo.

C.3 Asideros, bosques y árboles

Un asidero (handle) de un grafo G = (N, A) es un conjunto H ⊆ N tal que todo nodo de N es alcanzable desde algún nodo de H. Una raíz es un r ∈ N tal que {r} es asidero. Todo grafo tiene al menos un asidero, a saber H = N; un asidero es minimal si ningún subconjunto propio suyo lo es. Los asideros minimales siempre existen, pero no tienen por qué ser únicos, y sólo si el grafo tiene raíz un asidero minimal es un conjunto unitario.

Dado un asidero H, el conjunto de caminos de H a un nodo n es

pathH*(n) = ⋃ \{ pathsA(h, n) : h ∈ H \}

y cuando H está claro por el contexto se escribe path*(n).

Grados. El grado de entrada (in-degree) de un nodo n es el cardinal de {n' : (n', n) ∈ A}; el grado de salida, el de {n' : (n, n') ∈ A}. En el vocabulario del capítulo «4», un nodo de confluencia es uno de grado de entrada mayor que 1, y uno de bifurcación tiene grado de salida mayor que 1.

Bosques y árboles. Un bosque (forest) es un grafo dirigido acíclico en el que todos los nodos tienen grado de entrada a lo sumo 1. El conjunto de nodos de grado de entrada 0 constituye un asidero minimal. Si (n, n') ∈ A se dice que n es el padre de n' y n' un hijo de n; ancestro y descendiente son las clausuras reflexiva y transitiva de padre e hijo. Un árbol (tree) es un bosque con raíz.

Un bosque de recubrimiento (spanning forest) de un grafo es un bosque con los mismos nodos y un subconjunto de las aristas.

Dominadores. Dado un grafo G = (N, A) con asidero H, un nodo n' domina a n si todo camino, posiblemente trivial, de H a n contiene a n'.

C.4 Orden inverso de postorden

Ésta es la sección con más consecuencias prácticas del apéndice.

El algoritmo de bosque de recubrimiento en profundidad (depth-first spanning forest, DFSF) construye no deterministamente un bosque de recubrimiento y, en paralelo, genera una numeración de los nodos:

ENTRADA:  un grafo dirigido (N, A) con k nodos y asidero H
SALIDA:   (1) un DFSF  T = (N, A_T)
          (2) una numeracion rPostorder de los nodos que indica el orden
              inverso en el que fueron visitados por ultima vez

METODO:
    i := k
    marcar todos los nodos de N como no visitados
    A_T := vacio
    while queden nodos no visitados en H do
        elegir h en H no visitado
        DFS(h)

procedure DFS(n):
    marcar n como visitado
    while exista (n, n') en A con n' no visitado do
        anadir (n, n') a A_T
        DFS(n')
    rPostorder[n] := i
    i := i - 1

La numeración se llama orden inverso de postorden (reverse postorder, rPO) y se representa como un array indexado por los nodos. Si el DFSF es un árbol se llama árbol de recubrimiento en profundidad (DFST); nótese que el algoritmo no especifica qué nodo no visitado se elige en cada paso, así que el bosque no es único.

Clasificación de las aristas. Dado un bosque de recubrimiento, las aristas del grafo original se clasifican en cuatro clases:

  • aristas de árbol (tree edges): las presentes en el bosque de recubrimiento;
  • aristas hacia adelante (forward edges): las que no son de árbol y van de un nodo a un descendiente propio suyo en el árbol;
  • aristas de retroceso (back edges): las que van de un descendiente a un ancestro, incluidos los bucles propios;
  • aristas cruzadas (cross edges): las que van entre nodos no relacionados por ancestro/descendiente.

C.5 Expresiones regulares de caminos

La última pieza. El conjunto de caminos de un nodo a otro en un grafo finito es en general infinito —hay ciclos— pero es siempre un lenguaje regular sobre el alfabeto de las aristas. Por tanto puede describirse mediante una expresión regular de caminos (path expression), construida con concatenación, unión y clausura de Kleene.

Eso abre una vía alternativa para resolver problemas de flujo de datos, los llamados métodos de eliminación (elimination methods), por oposición a los métodos iterativos del capítulo «7»:

  1. calcular una expresión regular que describa el conjunto de caminos desde la entrada hasta cada nodo;
  2. interpretar esa expresión en el dominio abstracto, sustituyendo la concatenación por composición de funciones de transferencia, la unión por y la clausura de Kleene por el cierre de la función de transferencia, f* = ⊔ₙ fⁿ.

El resultado es la solución MOP del capítulo «7», calculada sin iterar. Su interés práctico es doble: es más eficiente en grafos con estructura regular, y es la técnica natural cuando el mismo grafo se analiza muchas veces con dominios distintos, porque la expresión de caminos se calcula una sola vez.

Su limitación es que requiere poder calcular el cierre f* en el dominio abstracto, cosa que no siempre es posible ni barata; en los marcos de vector de bits es trivial, en los dominios numéricos no.

Las expresiones regulares de caminos aparecen también en el capítulo «16», en el cálculo de las puertas de la forma GSA: la puerta de una función γ es precisamente la expresión de caminos de la arista de entrada correspondiente.

C.6 Notas

El capítulo «4» cubre este mismo material desde el punto de vista del análisis de binarios y añade la frontera de dominancia; los algoritmos eficientes de cálculo de dominadores se citan allí.

La «sección C.5 · Expresiones regulares de caminos» sintetiza la literatura sobre métodos de eliminación, cuya referencia canónica es Tarjan (1981).