Escolha uma representação de dados
Primeiro, observe o tamanho do resultado. Você deseja a coleção dos caminhos mais curtos de ss para todos os outros nós. A menos que o comprimento médio de um caminho seja limitado por uma constante (o que não é: qualquer lista é unipath, e se você usar a raiz por s,s o comprimento total dos caminhos será n ( n - 1 ) / 2n(n−1)/2 onde nn é o comprimento da lista), você precisará ter cuidado na sua representação de dados: a estrutura que contém os caminhos precisará usar o compartilhamento entre os caminhos.
Excluindo ciclos, existe um único caminho de s para qualquer outro nó u . Se esse caminho passa por um nó intermediário t , o primeiro segmento do caminho é o caminho desejado de s para t . sutst
Proponho armazenar o resultado em uma matriz, indexada por nós numerados de 0 a | E | - 1 , com s = 0 . Cada elemento da matriz armazena o índice do nó anterior no caminho para esse nó (use, por exemplo, - 1 como um marcador especial para nós inacessíveis a partir de s ). O caminho de s a t será ( s = R [ … R [ t ] … ] , … , R [ R [ t0|E|−1s=0−1sst] ] , R [ t ] , t ) .(s=R[…R[t]…],…,R[R[t]],R[t],t)
Atravessar o gráfico
Inicialize R para todos - 1 .R−1
Execute um percurso de profundidade primeiro ou largura primeiro do gráfico iniciando em s . Cada vez que um nó u é alcançado, defina R [ u ] como seu antecessor.suR[u]
Como existem ciclos, um nó pode ser alcançado mais de uma vez. Ter R [ u ] ≠ - 1 indica que você já foi visitado.R[u]≠−1u
Prove a correção
Por causa da propriedade unipathic, não importa como alcançamos cada nó, desde que não tenhamos completado um ciclo. Existe apenas um caminho simples.
Prove a complexidade
O algoritmo pode alcançar cada nó mais de uma vez, portanto, não está claro se sua complexidade é O ( | V | ) . O trabalho realizado é de fato Θ ( | E 0 | ), em que V 0 são as arestas alcançáveis a partir da origem. Mais precisamente, atingimos um nó mais de uma vez apenas em uma circunstância: se o nó é o primeiro que atingimos em um ciclo específico e, nesse caso, atingimos duas vezes (uma de um caminho simples e uma vez após concluir o ciclo) )O(|V|)Θ(|E0|)V0
Bem então. Vamos provar que, em um gráfico unipático, o número de ciclos elementares cresce no máximo linearmente com o número de nós. (Um ciclo elementar é aquele que não contém um ciclo mais curto.) Na discussão a seguir, assumirei que o gráfico não possui aresta própria (sem aresta de um nó para si mesmo; essas arestas são irrelevantes para a construção do caminho) )
Gráficos unipáticos podem ter ciclos, mas de uma maneira muito restrita. Seria bom se, de alguma forma, pudéssemos associar cada ciclo a um nó distinto (ou pelo menos, no máximo, um número limitado de ciclos por nó). Os ciclos podem compartilhar um nó? Infelizmente sim.
Você pode ter m ciclos de tudo partilha um nó um e nenhum outro nó. O gráfico resultante é unipático. Com ciclos de comprimento 2, esse é um padrão de estrela com um nó central a e qualquer número de nós b i de modo que ∀ i , a ⇆ b i .maabi∀i,a⇆bi
Então, precisamos trabalhar mais. Bem, vamos tentar provar isso indutivamente. Seja # V ( G ) o número de nós em um gráfico G , # E ( G ) o número de arestas e # C ( G ) o número de ciclos elementares que não são auto-arestas. Afirmo que se G é unipático e não está vazio, então # C ( G ) ≤ # V ( G ) - 1 .#V(G)G#E(G)#C(G)G#C(G)≤#V(G)−1
Para um gráfico com um ou dois nós, isso é óbvio. Suponha que a asserção seja válida para todos os gráficos, de modo que # V ( G ) < n e seja G um gráfico unipático com n nós. Se G não tiver ciclo, 0 = # C ( G ) < # V ( G ) , caso encerrado. Caso contrário, deixe ( um 1 , ... , um m ) ser um ciclo elementar.#V(G)<nGnG0=#C(G)<#V(G)(a1,…,am)
Recolher o ciclo de: deixar G ' ser o gráfico cujos nós são aqueles de L menos { um 1 , ... , um m } além de um nó de um e cujas arestas são todos os bordos de L que não envolvam a um i 's, mais uma → L ' b sempre ∃ i , um i → L b e b → L ' um sempre que ∃ i , b →G′G{a1,…,am}aGaia→G′b∃i,ai→Gbb→G′aG a i . Todo caminho em G ' induz um caminho em G (se o caminho envolver b → a → c , substitua-o por b → a i → a i + 1 → ... → a j → c em G ). Portanto, G ' é unipático. Além disso, como os ciclos em G não compartilham arestas, G ′ possui todos os ciclos em G, exceto o que eliminamos: # C∃i,b→GaiG′Gb→a→cb→ai→ai+1→…→aj→cGG′GG′G( G ′ ) = # C ( G ) - 1 . Por indução, # C ( G ′ ) ≤ # V ( G ′ ) - 1 . Como # V ( G ′ ) = # V ( G ) - m + 1 , temos # C ( G ) = # C ( G ′ ) +#C(G′)=#C(G)−1#C(G′)≤#V(G′)−1#V(G′)=#V(G)−m+11≤#V(G)−m=n−m≤n−1#C(G)=#C(G′)+1≤#V(G)−m=n−m≤n−1.
This concludes the proof. The traversal follows at most 2|V|−22|V|−2 edges.