5

I was asked for my homework to write an efficient algorithm that finds all the vertices in a directed graph which have even length of path to them from the given vertex.

This is what I thought of:

(It's very similar to "Visit" algorithm of DFS)

Visit(vertex u)

     color[u]<-gray
     for each v E adj[u]
       for each w E adj[v]
            if color[w] = white then
                     print w
                     Visit(w)

I think it works but I'm having hard time calculating it's efficiency, especially when the graph is with cycles. Could you help me?

Alex Shesterov
  • 26,085
  • 12
  • 82
  • 103
Chen Saranga
  • 51
  • 1
  • 4

2 Answers2

6

If I may suggest an alternative - I would have reduced the problem and use DFS instead of modifying DFS.

Given a graph G = (V,E), cretae a graph G' = (V,E') where E'={(u,v) | there is w in V such that (u,w) and (w,v) are in E)
In other words - we are creating a graph G', which has edge (u,v) if and only if there is a path of length 2 from u to v.

Given that graph, we can derive the following algorithm [high level pseudo-code]:

  1. Create G' from G
  2. run DFS on G' from the source s, and mark the same nodes DFS marked.

Correctness and time complexity analysis of the solution:

Complexity: The complexity is obviously O(min{|V|^2,|E|^2} + |V|), because of part 1 - since there are at most min{|E|^2,|V|^2} edges in G', so DFS on step 2 runs in O(|E'| + |V|) = O(min{|V|^2,|E|^2} + |V|)

Correctness:
If the algorithm found that there is a path from v0 to vk, then from the correctness of DFS - there is a path v0->v1->...->vk on G', so there is a path v0->v0'->v1->v1'->...->vk of even length on G.
If there is a path of even length on G from v0 to vk, let it be v0->v1->...->vk. then v0->v2->...->vk is a path on G', and will be found by DFS - from the correctness of DFS.

As a side note:
Reducing problems instead of modifying algorithms is usually less vulnurable to bugs, and easier to analyze and prove correctness on, so you should usually prefer these over modifying algorithms when possible.

EDIT: regarding your solution: Well, analysing it shows they are both pretty much identical - with the exception of I was generating E' as pre-processing, and you are generating it on the fly, in each iteration.
Since your solution is generating the edges on the fly - it might to doing some work more then once. However, it is bounded to the job at most |V| times more, since each vertex is being visited at most once.
Assuming |E| = O(|V|^2) for simplicity, giving us total an upper bound for the run time of O(|V|^3) for your solution.
It is also a lower bound, look at the example of a clique, During each visit() of any node, the algorithm will do O(|V|^2) to generate all possibilities, and visit() one of the possibilities, since we visit exactly |V| nodes, we get total run time of Omega(|V|^3)
Since we found the solution is both O(|V|^3) and Omega(|V|^3), it is total of Theta(O(|V|^3))

amit
  • 175,853
  • 27
  • 231
  • 333
  • Thank you Amit for your answer:) but they required the algorithm to be as efficient as you can and I think they meant linear efficiency.. I just wonder if mine is... – Chen Saranga Apr 17 '12 at 12:47
  • @ChenSaranga: If you regard to `|E| = O(|V|^2)` [which is usually the assumption], this is just as good as DFS, which runs in `O(|V| + |E|) = O(|V|^2 + |V|) = O(|V|^2)` - which is the same as this algorithm in this case, since `min{|E|^2,|V|^2} = |V|^2` with this assumption. – amit Apr 17 '12 at 12:49
  • @ChenSaranga: P.S. I *think* your suggested solution has the same time complexity, I'll need to think about it a bit more, and I'll edit the answer and include an explanation for it when I find one. – amit Apr 17 '12 at 12:51
  • Thank you! do you think I can give a tightly bound for the running time in my algorithm? (theta) – Chen Saranga Apr 17 '12 at 12:54
  • @ChenSaranga: I think they are both `Theta(|V|^2)` worst case, for the example of a [clique](http://en.wikipedia.org/wiki/Clique_%28graph_theory%29) - they both need to do `Omega(|V|^2)` ops. [your algorithm will do it in the nested double loop, mine will do it in both stage (1) and (2)], so - both have lower bound of `Omega(|V|^2)`, and upper bound of `O(|V|^2)`, which makes them `Theta(|V|^2)` which is [not surprisingly] **same as DFS**. – amit Apr 17 '12 at 12:59
  • We learned that DFS is Theta(|V| + |E|), and i think this is the efficiency they want for this one.. anyway thank you so much for your help I think Theta(|V|^2) it's not what they want. – Chen Saranga Apr 17 '12 at 13:04
  • @ChenSaranga: Look at my edit, my early assumption was wrong regarding your solution - it is `O(|V|^3)` assuming `|E| = O(|V|^2)`. Regarding `O(|V|+|E|)` solution - I doubt one exists, but I'd be glad if someone can prove me wrong:) – amit Apr 17 '12 at 13:16
1

For each undirected graph G(V,E) we should rebuilt the mentioned graph to be bipartite graph G'(V',E') when:

  • V' = V1 ∪ V2
  • E'={(u1,v2):(u,v)∈E, u1∈V1, v2∈V2}
  • V1={v1: v∈V}
  • V2={v2: v∈V}

For example the graph

given graph

becomes

bipartite graph

On this graph (bipartite graph) we should run BFS algorithm - BFS(G',S1'). After running BFS(G',S1') we should return array d that contains length of shortest even path δ(s1,u1)

amain
  • 1,668
  • 13
  • 19