{"id":490,"date":"2007-08-13T22:05:51","date_gmt":"2007-08-13T22:05:51","guid":{"rendered":"http:\/\/scientopia.org\/blogs\/goodmath\/2007\/08\/13\/traversing-graphs\/"},"modified":"2007-08-13T22:05:51","modified_gmt":"2007-08-13T22:05:51","slug":"traversing-graphs","status":"publish","type":"post","link":"http:\/\/www.goodmath.org\/blog\/2007\/08\/13\/traversing-graphs\/","title":{"rendered":"Traversing Graphs"},"content":{"rendered":"<p> One amusing thing in graph theory is graph traversal. Many of the interesting algorithms on graph<br \/>\nare ultimately based on the idea of iterating through the nodes of the graph in some order that is<br \/>\nrelated to the structure of the graph.<\/p>\n<p> There are two fundamental orders of graph traversal, known as <em>breadth-first<\/em> and <em>depth-first<\/em>.<\/p>\n<p><!--more--><\/p>\n<p> They&#8217;re actually hard to explain in a comprehensible way &#8211; but they&#8217;re pretty easy to understand by<br \/>\nexample. So let&#8217;s look at a graph, and do its depth-first and breadth-first traversals; then we&#8217;ll look at<br \/>\nsome pseudo-code to explain the details.<\/p>\n<p><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" alt=\"traversal-graph.png\" src=\"https:\/\/i0.wp.com\/scientopia.org\/img-archive\/goodmath\/img_247.png?resize=284%2C225\" width=\"284\" height=\"225\" \/><\/p>\n<p> We&#8217;ll start with a depth-first traversal from A. What we&#8217;ll do is visit A, and then go to one of its children, doing a p depth first traversal of as much of the graph as we can from that child of A. So suppose we go to D first. Then<br \/>\nwe&#8217;ll start doing a depth-first traversal from D &#8211; so we go to M. From M we go to H. From H to N. From N we can&#8217;t go anywhere else &#8211; so we go back to H, and go to its next child, which is L. L to Q; Q to J; J to P; P to O. Then we&#8217;re at a dead end again. So we go back to P. Since O is already visited, P is a dead end. So we go back to J. From J, we can to go E. From E to F; F to C, C to B, B to I, I to K, and K to G. Then everything has been visited, and we&#8217;re done. So the full depth-first traversal that we just did was A,D,M,H,N,L,Q,J,P,O,E,F,C,B,I,K,G. The depth-first does pretty much exactly what the name sounds like: it pushes deep into the graph as quickly as possible.<\/p>\n<p> The breadth-first traversal is quite different. It first visits everything 1 step from its start; then 2 steps from its start; then 3; and it preserves path ordering it each level. What I mean by that will become clear from the example.<\/p>\n<p> We start again with A. Then we visit each node adjacent to A: A, F, D. Then we visit each node adjacent to F: C, B, E.<br \/>\nThen we visit each node adjacent to D: M. Then each node adjacent to C; nothing unvisited yet. Then adjacent to B: I is unvisited. Then E: J. Then M: H, Q.  Then I: K, G. Then J: P. Then H: N, L. Then we go through a bunch where there&#8217;s nothing unvisited, until we get to P, which gives us O. So the full ordering is: A, F, D, C, B, E, M, I, J, H, Q, K, G, P, N, L, O. <\/p>\n<p> To see what I mean about path ordering, let&#8217;s look at the paths to some of the vertices in the breadth-first traversal: A, AF, AD, AFC, AFB, AFE, ADM, AFBI, AFEJ, ADMH, ADMQ, &#8230; Since we visited F before we visited D, we&#8217;ll always visit things on paths through F before we visit things on paths of the same length through D. <\/p>\n<p> Another way of thinking about the traversals is as a way of generating a spanning tree for the graph. Here&#8217;s a depth-first spanning tree for our example graph. As you can see, the depth first approach<br \/>\ngenerates a very long, very narrow tree with a small number of branches. That&#8217;s what you&#8217;ll generally see in a depth first traversal.<\/p>\n<p><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" alt=\"depth-first-tree.png\" src=\"https:\/\/i0.wp.com\/scientopia.org\/img-archive\/goodmath\/img_248.png?resize=421%2C160\" width=\"421\" height=\"160\" \/><\/p>\n<p> And here&#8217;s a breadth-first spanning tree. The breadth first approach produces a much shallower,<br \/>\nbushier tree.<\/p>\n<p><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" alt=\"breadth-first-tree.png\" src=\"https:\/\/i0.wp.com\/scientopia.org\/img-archive\/goodmath\/img_249.png?resize=230%2C281\" width=\"230\" height=\"281\" \/><\/p>\n<p> Finally, a bit of pseudocode, to give you the details:<\/p>\n<pre>\n<b>Depth-First-Search<\/b>(Graph, Vertex, Visited):\nvisit(Vertex)\nadd Vertex to Visited\nfor each vertex <em>vert<\/em> adjacent to Vertex in G:\nif <em>vert<\/em> is not in Visited:\n<b>Depth-First-Search<\/b>(Graph, <em>vert<\/em>, Visited)\nend if\nend for\nend\n<\/pre>\n<pre>\n<b>Breadth-First-Search<\/b>(Graph, Vertex, Visited)\nlet <em>queue<\/em> = new Queue\nadd Vertex to end of <em>queue<\/em>\nwhile <em>queue<\/em> is not empty:\nlet <em>v<\/em> = remove-first(<em>queue<\/em>)\nif <em>v<\/em> is not in Visited:\nvisit(<em>v<\/em>)\nadd <em>v<\/em> to Visited\nfor each vertex <em>w<\/em> adjacent to <em>v<\/em> in G:\nadd <em>w<\/em> to end of <em>queue<\/em>\nend for\nend if\nend while\nend\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>One amusing thing in graph theory is graph traversal. Many of the interesting algorithms on graph are ultimately based on the idea of iterating through the nodes of the graph in some order that is related to the structure of the graph. There are two fundamental orders of graph traversal, known as breadth-first and depth-first.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[25],"tags":[],"class_list":["post-490","post","type-post","status-publish","format-standard","hentry","category-graph-theory"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p4lzZS-7U","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"_links":{"self":[{"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/posts\/490","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/comments?post=490"}],"version-history":[{"count":0,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/posts\/490\/revisions"}],"wp:attachment":[{"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/media?parent=490"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/categories?post=490"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/tags?post=490"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}