Por favor, perdoe-me por fazer uma pergunta iniciante, mas sou iniciante em algoritmos e complexidades, e às vezes é difícil entender como surgiu a complexidade de um algoritmo específico.
Eu estava lendo o algoritmo DFS de Introduction to Algorithms by Cormen , e este era o algoritmo:
G -> graph
G.V -> set of vertices in G
u.π -> parent vertex of vertex u
G.Adj[u] -> adjacency list of vertex u
DFS(G)
1 for each vertex u ∈ G.V
2 u.color = WHITE
3 u.π = NIL
4 time = 0
5 for each vertex u ∈ G.V
6 if u.color == WHITE
7 DFS-VISIT(G,u)
DFS-VISIT(G,u)
1 time = time + 1 // white vertex u has just been discovered
2 u.d = time
3 u.color = GRAY
4 for each v ∈ G.Adj[u] // explore edge u
5 if v.color == WHITE
6 v.π = u
7 DFS-VISIT(G,v)
8 u.color = BLACK // blacken u; it is finished
9 time = time + 1
10 u.f = time
Dizia então linhas 1-3
e 5-7
é O(V)
, exclusivo do tempo para executar as chamadas DFS-VISIT()
. In DFS-VISIT()
, linhas 4-7
são O(E)
, porque a soma das listas de adjacência de todos os vértices é o número de arestas. E então concluiu que a complexidade total de DFS()
é O(V + E)
.
Eu não entendo como isso aconteceu. DFS-VISIT()
é chamado por dentro DFS()
. Então, se as linhas 5-7
de DFS()
são O(V)
e DFS-VISIT()
são O(E)
, então a complexidade total de tempo não deveria DFS()
ser O(VE)
?
fonte
DFS-VISIT()
", isso já responde à sua pergunta: "exclusivo deDFS-VISIT()
" significa que o tempo indicado não inclui o tempo gastoDFS-VISIT()
.Respostas:
O livro está contando o número de vezes que cada linha é executada durante toda a execução de uma chamada do DFS, em vez do número de vezes que é executado em cada chamada da sub-rotina DFS-VISIT. Talvez o exemplo mais simples a seguir deixe isso claro:
Em cada execução de A, a linha 1 de B é executada vezes, e a própria B é executada vezes. No entanto, o tempo de execução é e não .n n O(n) O(n2)
Aqui está outro exemplo, no qual uma matrizT[1…n] está envolvido.
O procedimento COUNT conta o número de 1s na matriz de entrada T. Mesmo que ADVANCE possa ser chamado atén vezes por COUNT e, no pior dos casos, o tempo de execução de ADVANCE é O(n) , as linhas 1–2 da ADVANCE são executadas no máximo n tempos e, portanto, o tempo de execução geral é O(n) ao invés de O(n2) .
fonte
B()
éO(1)
, portanto, sei
for chamada de1 to n
, então será n-timesO(1)
->O(n)
. Você diz que a linha 1 de B é executada n vezes e a própria B é executada n vezes, mas elas não são a mesma coisa?