<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>BFS algorithm &#8211; stoimen&#039;s web log</title>
	<atom:link href="/tag/bfs-algorithm/feed/" rel="self" type="application/rss+xml" />
	<link></link>
	<description>on web development</description>
	<lastBuildDate>Tue, 13 Feb 2018 08:18:15 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=5.0.3</generator>
	<item>
		<title>Computer Algorithms: Dijkstra Shortest Path in a Graph</title>
		<link>/2012/10/15/computer-algorithms-dijkstra-shortest-path-in-a-graph/</link>
		<comments>/2012/10/15/computer-algorithms-dijkstra-shortest-path-in-a-graph/#comments</comments>
		<pubDate>Mon, 15 Oct 2012 14:12:50 +0000</pubDate>
		<dc:creator><![CDATA[Stoimen]]></dc:creator>
				<category><![CDATA[algorithms]]></category>
		<category><![CDATA[data structures]]></category>
		<category><![CDATA[Graphs]]></category>
		<category><![CDATA[BFS algorithm]]></category>
		<category><![CDATA[Breadth-first search]]></category>
		<category><![CDATA[Depth-first search]]></category>
		<category><![CDATA[Dijkstra algorithm]]></category>
		<category><![CDATA[Dijkstra's algorithm]]></category>
		<category><![CDATA[Distance]]></category>
		<category><![CDATA[Graph]]></category>
		<category><![CDATA[Graph theory]]></category>
		<category><![CDATA[library SPL]]></category>
		<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[Network theory]]></category>
		<category><![CDATA[path]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Routing algorithms]]></category>
		<category><![CDATA[search algorithms]]></category>
		<category><![CDATA[Shortest path problem]]></category>
		<category><![CDATA[The algorithm]]></category>
		<category><![CDATA[Theoretical computer science]]></category>
		<category><![CDATA[USD]]></category>

		<guid isPermaLink="false">/?p=3381</guid>
		<description><![CDATA[Introduction We already know how we can find the shortest paths in a graph starting from a given vertex. Practically we modified breadth-first search in order to calculate the distances from s to all other nodes reachable from s. We know that this works because BFS walks through the graph level by level. Some sources &#8230; <a href="/2012/10/15/computer-algorithms-dijkstra-shortest-path-in-a-graph/" class="more-link">Continue reading <span class="screen-reader-text">Computer Algorithms: Dijkstra Shortest Path in a Graph</span> <span class="meta-nav">&#8594;</span></a><div class='yarpp-related-rss'>

Related posts:<ol>
<li><a href="/2012/10/08/computer-algorithms-shortest-path-in-a-graph/" rel="bookmark" title="Computer Algorithms: Shortest Path in a Graph">Computer Algorithms: Shortest Path in a Graph </a></li>
<li><a href="/2012/10/28/computer-algorithms-shortest-path-in-a-directed-acyclic-graph/" rel="bookmark" title="Computer Algorithms: Shortest Path in a Directed Acyclic Graph">Computer Algorithms: Shortest Path in a Directed Acyclic Graph </a></li>
<li><a href="/2012/10/22/computer-algorithms-bellman-ford-shortest-path-in-a-graph/" rel="bookmark" title="Computer Algorithms: Bellman-Ford Shortest Path in a Graph">Computer Algorithms: Bellman-Ford Shortest Path in a Graph </a></li>
<li><a href="/2012/09/10/computer-algorithms-graph-breadth-first-search/" rel="bookmark" title="Computer Algorithms: Graph Breadth First Search">Computer Algorithms: Graph Breadth First Search </a></li>
</ol>
</div>
]]></description>
				<content:encoded><![CDATA[<h2>Introduction</h2>
<p>We already know how we can find the shortest paths in a graph starting from a given vertex. Practically we modified breadth-first search in order to calculate the distances from s to all other nodes reachable from s. We know that this works because BFS walks through the graph level by level.</p>
<figure id="attachment_3397" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/10/1.-BFS-Shortest-Paths.png"><img src="/wp-content/uploads/2012/10/1.-BFS-Shortest-Paths.png" alt="BFS Shortest Paths" title="BFS Shortest Paths" width="620" height="399" class="size-full wp-image-3397" srcset="/wp-content/uploads/2012/10/1.-BFS-Shortest-Paths.png 620w, /wp-content/uploads/2012/10/1.-BFS-Shortest-Paths-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">BFS is often used to find shortest paths between a starting node (s) and all other reachable nodes in a graph!</figcaption></figure>
<p>Some sources give a very simple explanation of how BFS finds the shortest paths in a graph. We must just think of the graph as a set of balls connected through strings. </p>
<figure id="attachment_3398" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/10/2.-The-Graph-as-Balls-and-Strings.png"><img src="/wp-content/uploads/2012/10/2.-The-Graph-as-Balls-and-Strings.png" alt="The Graph as Balls and Strings" title="The Graph as Balls and Strings" width="620" height="399" class="size-full wp-image-3398" srcset="/wp-content/uploads/2012/10/2.-The-Graph-as-Balls-and-Strings.png 620w, /wp-content/uploads/2012/10/2.-The-Graph-as-Balls-and-Strings-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">We can think of a graph as a set of balls connected through strings!</figcaption></figure>
<p>As we can see by lifting the ball called “S” all other balls fall down. The closest balls are directly connected to “s” and this is the first level, while the outermost balls are those with longest paths.</p>
<figure id="attachment_3399" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/10/3.-The-Graph-as-Balls-and-Strings-Levels.png"><img src="/wp-content/uploads/2012/10/3.-The-Graph-as-Balls-and-Strings-Levels.png" alt="The Graph as Balls and Strings Levels" title="The Graph as Balls and Strings Levels" width="620" height="399" class="size-full wp-image-3399" srcset="/wp-content/uploads/2012/10/3.-The-Graph-as-Balls-and-Strings-Levels.png 620w, /wp-content/uploads/2012/10/3.-The-Graph-as-Balls-and-Strings-Levels-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">Breadth-first search works much like the image above &#8211; it explores the graph level by level, thus we&#8217;re sure that all the paths are the shortest!</figcaption></figure>
<p>Clearly edges like those between A and B doesn’t matter for our BFS algorithm because they don’t make the path from S to C through B shorter. This is also known as the triangle inequality, where the sum of the lengths of two of the sides of the triangle is always greater than the length of the third side.</p>
<figure id="attachment_3400" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/10/4.-Triangle-inequality.png"><img src="/wp-content/uploads/2012/10/4.-Triangle-inequality.png" alt="Triangle inequality" title="Triangle inequality" width="620" height="399" class="size-full wp-image-3400" srcset="/wp-content/uploads/2012/10/4.-Triangle-inequality.png 620w, /wp-content/uploads/2012/10/4.-Triangle-inequality-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">What the triangle inequality says us is that if we have a direct edge between two nodes &#8211; that must be the shortest path between them!</figcaption></figure>
<p>We must only answer the question is BFS the best algorithm that finds the shortest path between any two nodes of the graph? This is a reasonable question because as we know by using BFS we don’t find only the shortest path between given vertices i and j, but we also get the shortest paths between i and all other vertices of G. This is an information that we actually don’t need, but can we find the shortest path between i and j without that info?<span id="more-3381"></span></p>
<p>The answer is simply “no”! Practically depth-first search can’t help us. Even worse &#8211; we can find paths that are far not the shortest ones.</p>
<figure id="attachment_3401" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/10/5.-DFS-and-shortest-path.png"><img src="/wp-content/uploads/2012/10/5.-DFS-and-shortest-path.png" alt="DFS and shortest path" title="DFS and shortest path" width="620" height="399" class="size-full wp-image-3401" srcset="/wp-content/uploads/2012/10/5.-DFS-and-shortest-path.png 620w, /wp-content/uploads/2012/10/5.-DFS-and-shortest-path-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">DFS actually can find the longest path in some cases and can&#8217;t be used for finding shortest path!</figcaption></figure>
<p>In the image above using DFS the distance between 1 and 7 is 7 while practically there is an edge between them.</p>
<p>So BFS is the optimal algorithm for finding shortest paths in a graph. But there’s a catch! This algorithm works fine when we assume that all the edges are the same length. In the examples so far each edge has the value of 1. So N edges between s and i made the distance between them of a length N.</p>
<h2>Overview</h2>
<p>As we know in practice different edges can have different values. Exactly that was the case in weighted graphs. Going back to the road map example the distances between different cities are commonly evaluated in miles or kilometers. Of course we can associate any other meaningful value to this edges. This can be either time in hours to travel between cities, money for fuel or anything else.</p>
<figure id="attachment_3403" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/10/6.-Weighted-Graphs-in-Practice.png"><img src="/wp-content/uploads/2012/10/6.-Weighted-Graphs-in-Practice.png" alt="Weighted Graphs in Practice" title="Weighted Graphs in Practice" width="620" height="399" class="size-full wp-image-3403" srcset="/wp-content/uploads/2012/10/6.-Weighted-Graphs-in-Practice.png 620w, /wp-content/uploads/2012/10/6.-Weighted-Graphs-in-Practice-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">In practice is more common to use weighted graphs than non-weighted graphs!</figcaption></figure>
<p>Now BFS can’t help us any more. Why? Because using non-equal values for the edges the triangle inequality is no longer true. Now the edge (the direct path) between A and B can be greater than the sum of the two edges (A, C) + (C, B)!</p>
<figure id="attachment_3404" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/10/7.-Triangle-Inequality-Problem.png"><img src="/wp-content/uploads/2012/10/7.-Triangle-Inequality-Problem.png" alt="Triangle Inequality Problem" title="Triangle Inequality Problem" width="620" height="399" class="size-full wp-image-3404" srcset="/wp-content/uploads/2012/10/7.-Triangle-Inequality-Problem.png 620w, /wp-content/uploads/2012/10/7.-Triangle-Inequality-Problem-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">In a weighted graph the edges aren&#8217;t equal for our BFS algorithm so we can&#8217;t use it!</figcaption></figure>
<p>In other words, assuming the same abstraction with balls and wires the hanging wires can’t be discarded so easily.</p>
<figure id="attachment_3405" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/10/8.-The-Graph-as-Balls-and-Strings.png"><img src="/wp-content/uploads/2012/10/8.-The-Graph-as-Balls-and-Strings.png" alt="Weighted Graph as Balls and Strings" title="Weighted Graph as Balls and Strings" width="620" height="399" class="size-full wp-image-3405" srcset="/wp-content/uploads/2012/10/8.-The-Graph-as-Balls-and-Strings.png 620w, /wp-content/uploads/2012/10/8.-The-Graph-as-Balls-and-Strings-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">On weighted graphs BFS is no longer useful!</figcaption></figure>
<p>So now how can we solve this problem? A very dummy approach is to break apart each edge with dummy vertices in order to make BFS work again.</p>
<figure id="attachment_3406" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/10/9.-Breaking-apart-edges.png"><img src="/wp-content/uploads/2012/10/9.-Breaking-apart-edges.png" alt="Breaking apart edges" title="Breaking apart edges" width="620" height="399" class="size-full wp-image-3406" srcset="/wp-content/uploads/2012/10/9.-Breaking-apart-edges.png 620w, /wp-content/uploads/2012/10/9.-Breaking-apart-edges-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">Since the graph is weighted we can decompose its edges to more &#8220;dummy&#8221; edges!</figcaption></figure>
<p>However this approach has several weak points. The major one is that we’ll have to keep much more information, which means more memory usage, for even small graphs. This is done in case we break each edge on too many parts.</p>
<p>The solution of this problem was given by <a href="http://en.wikipedia.org/wiki/Edsger_W._Dijkstra" title="Edsger W. Dijkstra" target="_blank">Edsger Dijkstra</a> in 1956 and published in 1959. The only thing we should do now is to be sure that even discarding the triangle inequality we have the shortest paths. The first thing to do is to keep information for the distance from s to the parent (previous) node of i in the graph in order to calculate which distance is shorter.</p>
<p>In BFS we used a queue in order to walk through all the ancestors of a node. This was made consecutively. Thus for the graph G on the next image the order of enqueuing the ancestors of S was A, B, C.</p>
<figure id="attachment_3409" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/10/10.-Order-of-enqueuing.png"><img src="/wp-content/uploads/2012/10/10.-Order-of-enqueuing.png" alt="Order of enqueuing" title="Order of enqueuing" width="620" height="399" class="size-full wp-image-3409" srcset="/wp-content/uploads/2012/10/10.-Order-of-enqueuing.png 620w, /wp-content/uploads/2012/10/10.-Order-of-enqueuing-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">The order of enqueuing in BFS is consecutive &#8211; something that isn&#8217;t working for weighted graphs!</figcaption></figure>
<p>The Dijkstra’s algorithm make use of a priority queue, also know as a heap. This fact combined by the fact we keep info for the shortest path so far help us find shortest paths in a weighted graphs.</p>
<p>Why this works? To answer this question let’s see the next very basic example, assuming the graph G from the next image. As we can see the triangle inequality isn’t true.</p>
<figure id="attachment_3410" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/10/11.-Weighted-graph.png"><img src="/wp-content/uploads/2012/10/11.-Weighted-graph.png" alt="Weighted graph" title="Weighted graph" width="620" height="399" class="size-full wp-image-3410" srcset="/wp-content/uploads/2012/10/11.-Weighted-graph.png 620w, /wp-content/uploads/2012/10/11.-Weighted-graph-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">A weighted graph that doesn&#8217;t follow the triangle inequality!</figcaption></figure>
<p>OK, we see that the path [S, B, A] is shorter than [S, A] although the edge (S, A) exists. How the Dijkstra algorithm overcomes this problem.</p>
<p>First we have no information about the distances (S, A) and (S, B), the only thing we know is that S is the starting point, its distance is 0 and its path so far is the empty set. So first we enqueue in a priority the distances from S to A and B.</p>
<figure id="attachment_3411" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/10/12.-Dijkstra-Priority-Queue.png"><img src="/wp-content/uploads/2012/10/12.-Dijkstra-Priority-Queue.png" alt="Dijkstra Priority Queue" title="Dijkstra Priority Queue" width="620" height="399" class="size-full wp-image-3411" srcset="/wp-content/uploads/2012/10/12.-Dijkstra-Priority-Queue.png 620w, /wp-content/uploads/2012/10/12.-Dijkstra-Priority-Queue-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">The algorithm of Dijkstra make use of a priority queue!</figcaption></figure>
<p>Now we dequeue the minimum (first in the heap) element from the queue &#8211; the closest node to S, which is B. Then all the nodes adjacent to S in the queue are tested for adjacency to B, thus if we have already the distance between S and A now we can test if its longer than (S, B) + (B, A) &#8211; the triangle inequality!</p>
<p>So far we know that we must change a bit BFS to get the Dijkstra algorithm. The only thing to do is to keep info for each node for the path through its parent and to use a priority queue.</p>
<h2>Code</h2>
<p>Implementing this algorithms isn’t much more difficult than BFS, so here’s the code in <a href="/category/php/" title="PHP on Stoimen.com">PHP</a>. However this example make use of the standard php library SPL and the PriorityQueue data structure, but any developer can code <a href="/2012/08/07/computer-algorithms-heap-and-heapsort-data-structure/" title="Computer Algorithms: Heap and Heapsort">his own heap</a>.</p>
<p>Here&#8217;s the graph from the code:</p>
<figure id="attachment_3413" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/10/0.-Graph.png"><img src="/wp-content/uploads/2012/10/0.-Graph.png" alt="The Graph from the Code" title="The Graph from the Code" width="620" height="399" class="size-full wp-image-3413" srcset="/wp-content/uploads/2012/10/0.-Graph.png 620w, /wp-content/uploads/2012/10/0.-Graph-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">The graph!</figcaption></figure>
<pre lang="PHP">
class vertex
{
    public $key         = null;
    public $visited     = 0;
    public $distance    = 1000000;  // infinite
    public $parent      = null;
    public $path        = null;
    
    public function __construct($key) 
    {
        $this->key  = $key;
    }
}

class PriorityQueue extends SplPriorityQueue
{
    public function compare($a, $b)
    {
        if ($a === $b) return 0;
        return $a > $b ? -1 : 1;
    }
}

$v0 = new vertex(0);
$v1 = new vertex(1);
$v2 = new vertex(2);
$v3 = new vertex(3);
$v4 = new vertex(4);
$v5 = new vertex(5);

$list0 = new SplDoublyLinkedList();
$list0->push(array('vertex' => $v1, 'distance' => 3));
$list0->push(array('vertex' => $v3, 'distance' => 1));
$list0->rewind();

$list1 = new SplDoublyLinkedList();
$list1->push(array('vertex' => $v0, 'distance' => 3));
$list1->push(array('vertex' => $v2, 'distance' => 7));
$list1->rewind();

$list2 = new SplDoublyLinkedList();
$list2->push(array('vertex' => $v1, 'distance' => 7));
$list2->push(array('vertex' => $v3, 'distance' => 8));
$list2->push(array('vertex' => $v4, 'distance' => 12));
$list2->rewind();

$list3 = new SplDoublyLinkedList();
$list3->push(array('vertex' => $v0, 'distance' => 1));
$list3->push(array('vertex' => $v2, 'distance' => 8));
$list3->rewind();

$list4 = new SplDoublyLinkedList();
$list4->push(array('vertex' => $v2, 'distance' => 12));
$list4->push(array('vertex' => $v5, 'distance' => 3));
$list4->rewind();

$list5 = new SplDoublyLinkedList();
$list5->push(array('vertex' => $v4, 'distance' => 3));
$list5->rewind();

$adjacencyList = array(
    $list0,
    $list1,
    $list2,
    $list3,
    $list4,
    $list5,
);

function calcShortestPaths(vertex $start, &$adjLists)
{
    // define an empty queue
    $q = new PriorityQueue();
    
    // push the starting vertex into the queue
    $q->insert($start, 0);
    $q->rewind();
    
    // mark the distance to it 0
    $start->distance = 0;
    
    // the path to the starting vertex
    $start->path = array($start->key);
    
    while ($q->valid()) {
        $t = $q->extract();
        $t->visited = 1;
        
        $l = $adjLists[$t->key];
        while ($l->valid()) {
            $item = $l->current();
            
            if (!$item['vertex']->visited) {
                if ($item['vertex']->distance > $t->distance + $item['distance']) {
                    $item['vertex']->distance = $t->distance + $item['distance'];
                    $item['vertex']->parent = $t;
                }
                
                $item['vertex']->path = array_merge($t->path, array($item['vertex']->key));
                
                $q->insert($item["vertex"], $item["vertex"]->distance);
            }
            $l->next();
        }
        $q->recoverFromCorruption();
        $q->rewind();
    }
}

calcShortestPaths($v0, $adjacencyList);

// The path from node 0 to node 5
// [0, 1, 2, 4, 5]
echo '[' . implode(', ', $v5->path) . ']';
</pre>
<h2>Complexity</h2>
<p>The complexity of that code is based on the complexity of BFS with the main difference that we keep a priority queue. For BFS we knew that the complexity was O(|V| + |E|), while Dijkstra&#8217;s algorithm has running time of O((|V| + |E|).log(|V|)). That is quite natural since the heapsort&#8217;s complexity is O(n.log(n))!</p>
<h2>Application</h2>
<p>Since the basic BFS can&#8217;t help us for weighted graphs and there are plenty of problems designed with weighted graphs obviously Dijkstra&#8217;s algorithm can be very handy. The only thing we should be aware of is the positive values of the edges.</p>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<li><a href="/2012/10/08/computer-algorithms-shortest-path-in-a-graph/" rel="bookmark" title="Computer Algorithms: Shortest Path in a Graph">Computer Algorithms: Shortest Path in a Graph </a></li>
<li><a href="/2012/10/28/computer-algorithms-shortest-path-in-a-directed-acyclic-graph/" rel="bookmark" title="Computer Algorithms: Shortest Path in a Directed Acyclic Graph">Computer Algorithms: Shortest Path in a Directed Acyclic Graph </a></li>
<li><a href="/2012/10/22/computer-algorithms-bellman-ford-shortest-path-in-a-graph/" rel="bookmark" title="Computer Algorithms: Bellman-Ford Shortest Path in a Graph">Computer Algorithms: Bellman-Ford Shortest Path in a Graph </a></li>
<li><a href="/2012/09/10/computer-algorithms-graph-breadth-first-search/" rel="bookmark" title="Computer Algorithms: Graph Breadth First Search">Computer Algorithms: Graph Breadth First Search </a></li>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>/2012/10/15/computer-algorithms-dijkstra-shortest-path-in-a-graph/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
