# Ordenação topológica

Em teoria dos grafos, uma ordenação topológica de um digrafo acíclico (DAG) é uma ordem linear de seus nós em que cada nó vem antes de todos nós para os quais este tenha arestas de saída. Cada DAG tem uma ou mais ordenações topológicas.
Mais formalmente, define-se a relação acessibilidade R sobre os nós do DAG tal que xRy se e somente se existe um caminho dirigido de x para y. Então, R é uma ordem parcial, e uma ordenação topológica é uma extensão linear desta ordem parcial, isto é, uma ordem total compatível com a ordem parcial.

## Exemplos

A aplicação canônica da ordenação topológica (ordem topológica) está na programação de uma sequência de trabalhos ou tarefas; tem uso potencial todas as vezes em que o problema abordado envolve uma ordem parcial; algoritmos de ordenação topológica começaram a ser estudados no início dos anos 1960 no contexto da técnica PERT para a agendamento de tarefas em gerenciamento de projetos. Os trabalhos são representados por vértices, e existe uma aresta de x para y se o trabalho x deve estar concluído antes do trabalho y poder ser iniciado (por exemplo, ao lavar roupas, a máquina de lavar deve terminar antes de se poder colocar as roupas para secar). Em seguida, uma ordenação topológica dá uma ordem na qual se possa realizar os trabalhos.
Em informática, as aplicações deste tipo surgem em agendamentos de instruções, ordenação de fórmulas de avaliação de células quando recalculando os valores de fórmulas em planilhas, síntese lógica, determinação da ordem das tarefas de compilação para executar em arquivos "make", e resolução de dependências de símbolos em ligadores.
* O grafo mostrado à esquerda tem muitas ordenações topológicas, incluindo:
* 7, 5, 3, 11, 8, 2, 9, 10 (visual esquerda-para-direita, de-cima-para-baixo)
* 3, 5, 7, 8, 11, 2, 9, 10 (vértice de menor número disponível primeiro)
* 3, 7, 8, 5, 11, 10, 2, 9
* 5, 7, 3, 8, 11, 10, 2, 9 (menor número de arestas primeiro)
* 7, 5, 11, 3, 10, 8, 9, 2 (vértice de maior número disponível primeiro)
* 7, 5, 11, 2, 3, 8, 9, 10

## Algoritmos

Os algoritmos usuais de ordenação topológica tem tempo de execução linear no número de nós, mais o número de arestas (O(|V|+|E|)).
Um desses algoritmos, descrito pela primeira vez por Kahn, trabalha escolhendo vértices na mesma ordem da eventual ordenação topológica. Primeiro, encontra uma lista de nós "íniciais", que não tem arestas de entrada e os insere em um conjunto S; pelo menos um nó devem existir se o grafo é acíclico. Então:
Se o grafo é um digrafo acíclico (DAG), a solução está contida na lista L (a solução não é única). Caso contrário, o grafo tem pelo menos um ciclo e, portanto, uma ordenação topológica é impossível.
Note-se que, reflectindo a não-exclusividade da ordenação resultante, a estrutura S pode ser simplesmente um conjunto ou uma fila ou uma pilha. Dependendo da ordem em que os nodos n são removidos do conjunto S, uma solução diferente é criada.
Um algoritmo alternativo para a ordenação topológica é baseado em uma busca em profundidade. Para este algoritmo, as arestas apontam na direção oposta, como o algoritmo anterior (e no sentido oposto ao mostrado no diagrama na seção de exemplos acima). Existe uma aresta de x para y se a tarefa x depende da tarefa y (em outras palavras, se a tarefa y deve ser concluída antes da tarefa x poder ser iniciada). O algoritmo faz um loop através de cada nó do grafo, em uma ordem arbitrária, iniciando uma busca em profundidade que termina quando se atinge qualquer nó que já foi visto desde o início da ordenação topológica:
Note que cada nodo n é adicionado à lista de saída L somente após considerar todos os outros nodos dos quais n depende (todos os nodos descendentes de n no grafo). Especificamente, quando o algoritmo acrescenta o nodo n, temos a garantia que todos os nodos dos quais n depende já estão na lista de saída L: eles foram adicionados a L tanto pela chamada recursiva anterior à visite, ou por uma chamada anterior à visite. Uma vez que cada aresta e nodo é visitado uma vez, o algoritmo executa em tempo linear. Note que o simples pseudocódigo acima não consegue detectar o caso de erro, onde o grafo de entrada contém ciclos. O algoritmo pode ser refinado para detectar os ciclos, observando nodos que são visitados mais de uma vez durante toda a seqüência de chamadas recursivas aninhadas à visite (por exemplo, passar uma lista adiante como um argumento extra para visite, indicando que nodos já foram visitados na pilha de chamada corrente).
Este algoritmo de busca em profundidade é o descrito por Cormen, Leiserson, Rivest e Stein; parece ter sido descrito pela primeira vez em artigo por Tarjan

## Unicidade

Se uma ordenação topológica tem a propriedade de todos os pares de vértices consecutivos na ordem de classificação serem conectados por arestas, essas arestas formam um caminho hamiltoniano dirigido no DAG. Se existe um caminho Hamiltoniano, a ordenação topológica é única, nenhuma outra ordem respeita as arestas caminho. Inversamente, se uma ordenação topológica não formar um caminho Hamiltoniano, o DAG terá duas ou mais ordenações topológicas válidas, porque neste caso, é sempre possível formar-se uma segunda ordenação válida ao se trocar dois vértices consecutivos, que não são ligados por uma aresta, uns com os outros. Portanto, é possível testar em tempo polinomial se existe uma única ordenação, e se existe um caminho hamiltoniano, apesar da característica NP-hard do problema do caminho hamiltoniano para grafos dirigidos mais gerais