সোমবার, ২৬ জানুয়ারী, ২০১৫

Kakai duo's Algorithm Tutorial series:Tarzan's algorithm for finding strongly connected components

Intuitions behind the Tarzan’s algorithm for finding strongly connected components:


So today,after waking up,I saw Zaheen reading the Tarzan comics and Aarish playing with his toys.Suddenly the elder one asked the younger one,

:Do you know why Tarzan is called the king of jungle?
-Yap,he was born and bred there,fed there,and lived all through his life there as the saviour of wildlife.
:Well,that's the easy one,not the tricky one ;)
-Like?
:Coz Tarzan had so many important works on forests :p
-Can’t understand bro :/
:I’m talking about  Robert Endre Tarzan,an american computer scientist.He had important contributions to graph theory.
-Oh,I didn't know.Can you enlighten me a bit ?
:Of course,lil' bro :)

*****************************************************************
Tha'ts how their conversation about Tarzan’s SCC finding algorithm started.I .as per I always do,am going to mention the extract from there:


-So now,tell me,what’s his most important contribution?
:Well I guess,you know about Kosaraju’s algorithm for finding the SCCs of a graph right?
-Which one?The one with two DFS’s?
:Yap.
-Yap,I learnt it from kakai(the writer).

:What if,the same thing can be done using only a single DFS?

-I wish it could be done :(
:don’t be sad,it can actually be done ;).Tarzan did it?
-Wao!!but how?
:Remember the low(u) thing?in fact this low(u) idea was a brainchild of Tarzan,he simplified so many problems introducing this :)
-Yap,I can remember.But how can it help me in finding SCCs?
:Well,at first do a simple dfs like previous ones,this time with a directed graph.
-(after a bit) Ok,here it is ,done.
:Now look carefully,you can easily determine the SCCs manually,right?
-Yap
:Look at the tree,is it the case anywhere that parts of same SCCs are in different subtrees?
-No,how can they be?If so,they wouldn't be connected in the first place.

:Good,so u at least have an idea now:SCCs will be in subtree form.One SCC will have its own subtree.

-Ya.And I think there can’t be a backedge from a SCC related subtree to another SCC related subtree?
:why so,my brother?
-Because it would mean you can go from one SCC to another and vice versa;i.e-they will be on same SCC.But they aren’t!!!
:Love you man,exactly.And what does this backedge thing reminds you ?
-low(u)?oldest ancestor to be visited from u?
:Yes,suppose that an SCC is defined by a subtree rooted by u.can low(u) be higher than discovery time of u?
-No,as per I said earlier,no backedge between SCCs.so its not possible.
:Ok,now tell me,if low(u)=discovery time of u,what would it mean?
-Well,it means the subtree rooted by u ,i.e:the possible members of u’s SCC can at most have back edge to the root u itself.Wait,doesn’t it mean if i find low(u)=disc(u) for a node u,I just should output the subtree under u?Shouldn’t they be the member of a SCC?
:Excellent lad ;) .So how’r u gonna output these nodes?
-ah,what if,I use a stack ,put nodes while visiting them,and start printing the nodes after popping  when I find low(u)==disc(u)?and stop doing so after popping u itself?
:Great.Do you think your algorithm is fulfilled now?
-I guess so ^_^
:Sorry lad,its not over yet.Don’t forget it’s a directed graph?
-Wait,I forgot about handling the case of forward age :o ! It was not a problem in undirected graph.But its a problem in directed one :(
:I can give you tips about handling the situation:Output only the nodes when they are in stack.
-Why?

:uff,read this extract from wikipedia -_-

   “Stack invariant[edit]

The nodes are placed on a stack in the order in which they are visited. When the depth-first search recursively explores a node v and its descendants, those nodes are not all necessarily popped from the stack before this recursive call returns. The crucial invariant property is that a node remains on the stack after exploration if and only if it has a path to some node earlier on the stack.
At the end of the call that explores v and its descendants, we know whether v itself has a path to any node earlier on the stack.[i.e - low(v)>disc(v) ]  If so, the call returns, leaving v on the stack to preserve the invariant. If not, then v must be the root of its strongly connected component, which consists of v together with any later nodes on the stack (such nodes all have paths back to v but not to any earlier node, because if they had paths to earlier nodes then v would also have paths to earlier nodes which is false ). This entire component is then popped from the stack and returned, again preserving the invariant.



-Now I understand ,forward edges’s endpoints won’t be in stack .So they won’t be printed.Right?

:Yes,you are right lad :) 

রবিবার, ২৫ জানুয়ারী, ২০১৫

Kakai duo's Algorithm Tutorial series:Articulation Bridge

Intuition behind the algorithm of finding articulation bridges:


So the other night ,while I posting in my blog about articulation point,I heard these two little pal chatting again about something related to graph theory.being a eager learner of graph theory,I tried to pick words from their conversation .They were having it about articulation bridge:


-So,now I have come across about a new topic:articulation bridge.Did you know about it?
:A bit,but never went through it carefully.
-Surprised,its so much similar with the articulation point thing you taught me.
:Great!Then it should be a cakewalk for you to understand the inner things. Btw,now it’s your turn to define articulation bridge
-Easy,its the edges whose removal causes the number of connected components to increase.
:So I guess,there is a similarly naive algorithm for it too?
-Of course,go through each edge;remove it;find if the graph is still connected or not;if so,not a bridge,if not so,its a bridge.Return the edge again in the graph,repeat.
:I can sense a quadratic complexity here.
-Yah,O(E(V+E))
:So is there any smart algo for it?
-Yes.And guess what?It needs the idea of low(u) too,the thing u taught me earlier in articulation point!!
:Great!!how??
-Simple.First run a dfs and get a dfs tree.There will be some edges lost.Will there be any articulation bridge in it?
:I don’t think so.Had there been any bridge that is not in dfs tree,the tree would have lost its connectivity.As there is no other way to reach fro one part to another.
-Yes.So just run a dfs first and you only look after the tree edges for finding the bridge.
:Wao!Damn easy!!
-Not yet the job is done.Think now how can you use low(u) now?
:Ok,let me think.Ummm.......ok,if the removal of an edge(v,u) divides the graph into two components,there should be no back edge from the connected component containing u to the connected component containing v.
-Interpret it using low(u) B-)
:Wait,let me define -

   from the connected component containing u-->subtree rooted at u

   The oldest ancestor from subtree(u) =low(u)
   No back edge from subtree(u) o the connected component containing v.
== Even if there is a back edge,its younger than v
==>low(u)>dfs(v)
Is this?
-You are a maverick B-)

Kakai duo's Algorithm Tutorial series:Articulation Point

Intuition behind the algorithm of finding articulation point in a graph:


My two nephews ,Aarish and Zaheen,are two of the most intelligent lads I have ever seen.The things they talk about often surprises me due to their intelligence level.One day I heard them about talking about articulation points.Infact,it was like a gift,as I myself was preparing to learn about it;but could not understand the intuition behind it.So I decided to listen to their conversation.Here is the extract of it

***********************************
-Brother,what is an articulation point?

:Well,Articulation points in a graph are the points whose removal divides the graph in two or more connected components.
-Umm,easy to understand.Is there any algorithm to find those points?
:I know about such an algorithm.But you should ask yourself first.can you think about any approach?

-Ah,If we think naively,then its not that hard to find the articulation points using the basic graph algorithms we know.Here is a naive algorithm

for all vertices v belongs to G.V:
Remove v from G
See if G is connected using bfs/dfs
If G is not connected,v is an articulation point,otherwise no
Return the removed vertex in the graph
:Good one!!! :D

-Nah,I don’t like it :/ . This algorithm takes ,
O( loop iteration)*O(dfs/bfs)=O(V)*O(V+E)=O(V(V+E)) times.It is a quadratic time algorithm.too much for a dense graph.
:Well,We can upgrade it although to a linear time one,if we have some insight about the properties of articulation points.
-How ??
:To do so,let’s make our hand a little dirty,do a simple DFS a bit :)
(After a bit of time)
Ok,so your dfs is done.Now look at the graph carefully.What can you see now?
-Simple,a DFS tree -_-

:Good,so can you classify the nodes according to some criteria?
-Of course;Root,internal nodes and leaves.But why?
:Well,if you can classify the nodes,then it will be easy for you to apply conditions to define articulation points differently as per their classification
-Please explain a bit :3
:Well,you can determine if a root is an articulation point in a different way,determine if an internal node is an articulation point in another way and determine  if a leaf is an articulation point in .........

-Wait,I have something to say!!
:Well,what?
-Can any leaf be an articulation point :/ ?
:Well,why?
-You see,if the removal of a leaf node disconnects the graph,then it means the graph can be divided into two components such that the leaf node acts as the connection between them,right?
:I agree.Then?

-Then ,it means that leaf has edges with both the connected components.One connected component has the root of the dfs tree,other one doesn’t.
:Ok

-Then while doing dfs,you could have visited to the “not-root-containing component” via that leaf from the “root-containing component”,right?
:Yes.
-So,if there is a connected component whom you can visit through a node during DFS,can that node be regarded as leaf?I don’t think so.
:You are goddamn right:LEAVES ARE NEVER ARTICULATION POINTS :D

-ah,relieved :)
:Ok,then now tell if you have anything to say about the root node?
-Umm,still nothing to say.Can you do this?

:Ok,assume that the root has one child.Can it be an articulation point?
-Don’t think so.Remove the root,you still get the DFS tree connected.So ,no.
:Ok,what if it has two children?

-Ah,well then.if I remove the root,there are two subtrees with no tree edge between them.So,there are disconnected components.
:So,you want to say that the root is...
-No no,still not;what if there is a cross edge between the subtrees?they will still be connected...
:Sure ;) ?

-Ah wait,how can there be cross edges?the graph is undirected :o
:So,the root is?
-AN ARTICULATION POINT IF IT HAS TWO ..WAIT ....MORE THAN TWO CHILDREN!!!
:BAZINGA!!Now you are talking lad :D
-Ok,then lets see how can we encounter the cases of internal nodes.

:Ok bro,In fact it will be the trickiest one.
-Indeed ,I can feel it.I am feeling blank a bit about it.Can you show some light?
:Ok,lets just think about it.Say ,we have just removed an internal node.What will happen now?

-Well,then the tree will be disconnected.Not sure about the graph though.
:Good,when the disconnected tree will result in disconnected graph too?

-Umm...if there is no bypass way between the root and any of the subtrees under the removed node?
:You mean,a backedge from a subtree under the removed node to one of the proper ancestors of the removed node.
-Yes,yes!!!But how can we detect them in linear time?
:Ok,what if we keep the track about a particular property of every nodes?and call it low(removed node) ?
-What property?
:The oldest ancestor that can be visited from the subtree rooted by that node?
-benefit?

:Lets think that the removed node is V.and there are two children of it:x,y.Assume that we have somehow counted low(x) and low(y).
-Ok,then?
:Then ,what do you think,how can this will help you to see if v is an AP or not?

-Well,I guess,I can check whether any of low(x) and low(y) is greater than or equal to the discovery time of v.
:Interesting,but why ;) ?

-If it happens,it will mean the oldest ancestor of either x or y through a back edge is still not the ancestor of v.It means there is no back edge or bypass from x(or y) to a proper ancestor of v!!!So obviously,if so happens,then v IS AN ARTICULATION POINT!!!
:Excellent brother,just excellent!!You really can read me well.....

-Well ,I ain’t convinced yet.You haven’t still said about how can we count low(v).Can we do so in linear time?
:That’s the tweak lad,think recursively ;)
-Recursively -_- ?
:Yes,lets think about v and its children again,what do you think,how can you count low(v) from low(x) and low(y)?
- Ah,I see.Low(v) means the oldest ancestor that can be visited from the subtree rooted by v.That visit can either start from a node situated in subtree rooted by x,or from a subtree rooted by y or from v itself?
:You are in form today.Then?

-The first two cases points to low(x) and low(y) respectively.But about the last case,well,I think,separate checkings of back edges need to be done.Oh and btw,in case of leaf nodes,it will be equal to their discovery time.
:I am proud of you brother.Infact,THIS IS THE RECURSIVE SOLUTION!!!
 LOW(V)=MIN (  DISCOVERY TIME OF v,
                 MIN( LOW(X) FOR EVERY CHILDREN X OF V),
                 MIN( DISCOVERY TIME OF U FOR EVERY BACKEDGE(V,U)
              )

-But still,can this recursive thing be done in linear time?
:Well,what about doing it simultaneously with the DFS ?in O(V+E) time?
-You are awesome :) 


   

Kakai duo's Algorithm Tutorial series:Prelude


I have started contest programming again;this time,with a renewed vigor not to repeat the same mistakes I made in the past.

To do so,I have started revising the old algorithms I learnt and reading about new algorithms.And I think that without understanding the inner idea and insights of an algorithm,it is fruitless to apply some mere pseudo codes. Besides,I also think ,writing what I have just learnt will have a permanent impression on the mind.

To do both things effectively,I have decided to start a series about the intuitions behind the algorithms I have learnt.And to make it more interesting,I have decided to write it in the form of fictional conversations between two little but most precious gifts of my life: Aarish and Zaheen-my little nephews.

I wish and pray to the Almighty that one day these conversations will turn into reality,I have such high hopes for them :)

Take care and learn :)