El orden topológico está definido para un grafo dirigido acíclico (DAG). Si los vértices representan tareas y las aristas representan dependencias entre las tareas, consistente en ordenar linealmente los vértices de forma tal que si se realizan las tareas en ese orden se respetan todas las dependencias.
Más formalmente, si existe una arita
El siguiente DAG admite un único orden topológico:
A --> B --> C
Mientras que este otro DAG admite varios:
A --.--> C
B -´
Si el grafo es dirigido pero tiene ciclos, entonces no existe ningún orden topológico posible.
Existen varias formas de obtener un orden topológico. Podemos extender una implementación de DFS para que agregue adelante de la lista enlazada L
cada vértice que termina de visitar (es decir, cuando vuelve del llamado recursivo de todos sus vecinos).
Esta implementación tiene como precondición que G sea un DAG. Si no, se puede utilizar el mismo DFS para detectar los back edges (que indican que hay un ciclo) y retornar algún error.
def topological_sort(G):
L = []
# Cada vez que terminamos de visitar un vértice
# lo agregamos al principio de la lista enlazada L.
dfs(G, L)
return L
Lema
Sea
$G$ es acíclico (es un DAG)$\iff$ DFS(G) no encuentra back edges.
Demo por el contrarrecíproco: un grafo dirigido
Teorema
Con este lema podemos probar más facilmente la correctitud del algoritmo. Lo que queremos ver es que al terminar el DFS, la lista enlazada
La lista enlazada
Supongamos que DFS tomó el camino por la arista
Si
En ambos casos, terminamos de visitar
Lineal: