<?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>Dijkstra&#8217;s algorithm &#8211; stoimen&#039;s web log</title>
	<atom:link href="/tag/dijkstras-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: Topological Sort Revisited</title>
		<link>/2012/12/10/computer-algorithms-topological-sort-revisited/</link>
		<comments>/2012/12/10/computer-algorithms-topological-sort-revisited/#comments</comments>
		<pubDate>Mon, 10 Dec 2012 15:45:16 +0000</pubDate>
		<dc:creator><![CDATA[Stoimen]]></dc:creator>
				<category><![CDATA[algorithms]]></category>
		<category><![CDATA[data structures]]></category>
		<category><![CDATA[Graphs]]></category>
		<category><![CDATA[Adjacency list]]></category>
		<category><![CDATA[Adjacency matrix]]></category>
		<category><![CDATA[Breadth-first search]]></category>
		<category><![CDATA[Dijkstra's algorithm]]></category>
		<category><![CDATA[Directed acyclic graph]]></category>
		<category><![CDATA[Graph]]></category>
		<category><![CDATA[graph algorithms]]></category>
		<category><![CDATA[Graph theory]]></category>
		<category><![CDATA[ineffective algorithm]]></category>
		<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[time consuming algorithm]]></category>
		<category><![CDATA[Topological sorting]]></category>
		<category><![CDATA[Vertex]]></category>

		<guid isPermaLink="false">/?p=3494</guid>
		<description><![CDATA[Introduction We already know what’s topological sort of a directed acyclic graph. So why do we need a revision of this algorithm? First of all I never mentioned its complexity, thus to understand why we do need a revision let’s get again on the algorithm. We have a directed acyclic graph (DAG). There are no &#8230; <a href="/2012/12/10/computer-algorithms-topological-sort-revisited/" class="more-link">Continue reading <span class="screen-reader-text">Computer Algorithms: Topological Sort Revisited</span> <span class="meta-nav">&#8594;</span></a><div class='yarpp-related-rss'>

Related posts:<ol>
<li><a href="/2012/10/01/computer-algorithms-topological-sort-of-a-graph/" rel="bookmark" title="Computer Algorithms: Topological Sort of a Graph">Computer Algorithms: Topological Sort of 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/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>
<li><a href="/2012/08/31/computer-algorithms-graphs-and-their-representation/" rel="bookmark" title="Computer Algorithms: Graphs and their Representation">Computer Algorithms: Graphs and their Representation </a></li>
</ol>
</div>
]]></description>
				<content:encoded><![CDATA[<h2>Introduction</h2>
<p>We already know what’s topological sort of a directed acyclic graph. So why do we need a revision of this algorithm? First of all I never mentioned its complexity, thus to understand why we do need a revision let’s get again on the algorithm.</p>
<p>We have a directed acyclic graph (DAG). There are no cycles so we must go for some kind of order putting all the vertices of the graph in such an order, that if there’s a directed edge (u, v), u must precede v in that order. </p>
<figure id="attachment_3506" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/12/1.-Topological-Sort.png"><img src="/wp-content/uploads/2012/12/1.-Topological-Sort.png" alt="Topological Sort" title="Topological Sort" width="620" height="399" class="size-full wp-image-3506" srcset="/wp-content/uploads/2012/12/1.-Topological-Sort.png 620w, /wp-content/uploads/2012/12/1.-Topological-Sort-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">&nbsp;</figcaption></figure>
<p>The process of putting all the vertices of the DAG in such an order is called topological sorting. It’s commonly used in task scheduling or while finding the shortest paths in a DAG.</p>
<p>The algorithm itself is pretty simple to understand and code. We must start from the vertex (vertices) that don’t have predecessors. </p>
<p><figure id="attachment_3513" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/12/2.-Topological-Sort-step-1.png"><img src="/wp-content/uploads/2012/12/2.-Topological-Sort-step-1.png" alt="Topological Sort - step 1" title="Topological Sort - step 1" width="620" height="399" class="size-full wp-image-3513" srcset="/wp-content/uploads/2012/12/2.-Topological-Sort-step-1.png 620w, /wp-content/uploads/2012/12/2.-Topological-Sort-step-1-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">&nbsp;</figcaption></figure><span id="more-3494"></span></p>
<p>We put them in our sorted list in random order. Since they don’t depend on each other we can assume they are equally sorted already. Indeed thinking of a task schedule if there are tasks that don’t have predecessors (they don’t depend on other tasks before them) and that don’t depend on each other we can put them in random order (and execute them in random order).</p>
<figure id="attachment_3512" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/12/3.-Topological-Sort-Order.png"><img src="/wp-content/uploads/2012/12/3.-Topological-Sort-Order.png" alt="Topological Sort - Order" title="Topological Sort - Order" width="620" height="399" class="size-full wp-image-3512" srcset="/wp-content/uploads/2012/12/3.-Topological-Sort-Order.png 620w, /wp-content/uploads/2012/12/3.-Topological-Sort-Order-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">&nbsp;</figcaption></figure>
<p>Once we have the vertices with no predecessors we must remove the edges starting from them. Then – go again with the vertices with no predecessors. </p>
<figure id="attachment_3511" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/12/4.-Topological-Sort-step-2.png"><img src="/wp-content/uploads/2012/12/4.-Topological-Sort-step-2.png" alt="Topological Sort - step 2" title="Topological Sort - step 2" width="620" height="399" class="size-full wp-image-3511" srcset="/wp-content/uploads/2012/12/4.-Topological-Sort-step-2.png 620w, /wp-content/uploads/2012/12/4.-Topological-Sort-step-2-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">&nbsp;</figcaption></figure>
<p>It’s as simple as that, so why do we need a revision of this algorithm? Well, basically because of its efficiency. </p>
<h2>Overview</h2>
<p>As we know most of the graph algorithms depend on the way the graph is represented in our application. We consider as the two main representations the adjacency matrix … </p>
<figure id="attachment_3510" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/12/5.-Adjacency-Matrix.png"><img src="/wp-content/uploads/2012/12/5.-Adjacency-Matrix.png" alt="Adjacency Matrix" title="Adjacency Matrix" width="620" height="399" class="size-full wp-image-3510" srcset="/wp-content/uploads/2012/12/5.-Adjacency-Matrix.png 620w, /wp-content/uploads/2012/12/5.-Adjacency-Matrix-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">&nbsp;</figcaption></figure>
<p>… and adjacency lists.</p>
<figure id="attachment_3509" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/12/6.-Adjacency-Lists.png"><img src="/wp-content/uploads/2012/12/6.-Adjacency-Lists.png" alt="Adjacency Lists" title="Adjacency Lists" width="620" height="399" class="size-full wp-image-3509" srcset="/wp-content/uploads/2012/12/6.-Adjacency-Lists.png 620w, /wp-content/uploads/2012/12/6.-Adjacency-Lists-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">&nbsp;</figcaption></figure>
<p>Let’s first take a look of some of the main approaches to get the topologically sorted list at the end of the algorithm. </p>
<p>What can we do in order to find the vertices with no predecessors? We can only scan the entire list of vertices. </p>
<h3>Adjacency Matrix</h3>
<p>In case we’re using adjacency matrix we need|V|^2 space to store the graph. To find the vertices with no predecessors we have to scan the entire graph, which will cost us O(|V|^2) time.  And we’ll have to do that |V| times. This will be |V|^3 time consuming algorithm and for dense graphs this will be quite an ineffective algorithm.</p>
<h3>Adjacency Lists</h3>
<p>What about the adjacency list? There we need |E| space to store a directed graph. How fast can we find a node with no predecessor? Practically we’ll need O(|E|) time.  Thus in the worst case we have again O(|V|^2) time consuming programs.</p>
<p>So what can be done in order to optimize this algorithm?</p>
<p>Practically we can start by picking up a random vertex and “go back” until we get a node with no predecessors. This approach can be very effective yet also very ineffective. First of all if we have to scan all the way back to a node with no predecessors this will cost us |V| time, but if we stuck on a node that don’t have a preceding node then we’ll have a constant speed.</p>
<p>This means that we can modify the algorithm a bit in order to improve a lot the algorithm. We just need to store both incoming and outgoing edges and slightly modify the adjacency lists.</p>
<figure id="attachment_3508" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/12/7.-Modified-Adjacency-Lists.png"><img src="/wp-content/uploads/2012/12/7.-Modified-Adjacency-Lists.png" alt="Modified Adjacency Lists" title="Modified Adjacency Lists" width="620" height="399" class="size-full wp-image-3508" srcset="/wp-content/uploads/2012/12/7.-Modified-Adjacency-Lists.png 620w, /wp-content/uploads/2012/12/7.-Modified-Adjacency-Lists-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">&nbsp;</figcaption></figure>
<p>What’s the algorithm now?</p>
<p>First we easily find the nodes with no predecessors. Then, using a queue, we can keep the nodes with no predecessors and on each dequeue we can remove the edges from the node to all other nodes.</p>
<h2>Pseudo Code</h2>
<pre>
1. Represent the graph with two lists on each vertex (incoming edges and outgoing edges)
2. Make an empty queue Q;
3. Make an empty topologically sorted list T;
4. Push all items with no predecessors in Q;
5. While Q is not empty
   a. Dequeue from Q into u;
   b. Push u in T;
   c. Remove all outgoing edges from u;
6. Return T;
</pre>
<p>This approach will give us a better performance than the “brute force” approach. The running time complexity is O(|V| + |E|). The problem is that we need additional space and an operational queue, but this approach is a perfect example of how by using additional space you can get a better performing algorithm.</p>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<li><a href="/2012/10/01/computer-algorithms-topological-sort-of-a-graph/" rel="bookmark" title="Computer Algorithms: Topological Sort of a Graph">Computer Algorithms: Topological Sort of 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/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>
<li><a href="/2012/08/31/computer-algorithms-graphs-and-their-representation/" rel="bookmark" title="Computer Algorithms: Graphs and their Representation">Computer Algorithms: Graphs and their Representation </a></li>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>/2012/12/10/computer-algorithms-topological-sort-revisited/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Computer Algorithms: Shortest Path in a Directed Acyclic Graph</title>
		<link>/2012/10/28/computer-algorithms-shortest-path-in-a-directed-acyclic-graph/</link>
		<comments>/2012/10/28/computer-algorithms-shortest-path-in-a-directed-acyclic-graph/#comments</comments>
		<pubDate>Sun, 28 Oct 2012 19:24:22 +0000</pubDate>
		<dc:creator><![CDATA[Stoimen]]></dc:creator>
				<category><![CDATA[algorithms]]></category>
		<category><![CDATA[data structures]]></category>
		<category><![CDATA[Graphs]]></category>
		<category><![CDATA[Bellman–Ford algorithm]]></category>
		<category><![CDATA[Dijkstra's algorithm]]></category>
		<category><![CDATA[Directed acyclic graph]]></category>
		<category><![CDATA[Distance]]></category>
		<category><![CDATA[faster algorithm]]></category>
		<category><![CDATA[Ford Motor Company]]></category>
		<category><![CDATA[Graph theory]]></category>
		<category><![CDATA[Longest path problem]]></category>
		<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[Network theory]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Routing algorithms]]></category>
		<category><![CDATA[Shortest path problem]]></category>
		<category><![CDATA[Theoretical computer science]]></category>
		<category><![CDATA[Topological sorting]]></category>

		<guid isPermaLink="false">/?p=3419</guid>
		<description><![CDATA[Introduction We saw how to find the shortest path in a graph with positive edges using the Dijkstra’s algorithm. We also know how to find the shortest paths from a given source node to all other nodes even when there are negative edges using the Bellman-Ford algorithm. Now we’ll see that there’s a faster algorithm &#8230; <a href="/2012/10/28/computer-algorithms-shortest-path-in-a-directed-acyclic-graph/" class="more-link">Continue reading <span class="screen-reader-text">Computer Algorithms: Shortest Path in a Directed Acyclic Graph</span> <span class="meta-nav">&#8594;</span></a><div class='yarpp-related-rss'>

Related posts:<ol>
<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/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/15/computer-algorithms-dijkstra-shortest-path-in-a-graph/" rel="bookmark" title="Computer Algorithms: Dijkstra Shortest Path in a Graph">Computer Algorithms: Dijkstra Shortest Path in a Graph </a></li>
<li><a href="/2012/12/03/computer-algorithms-longest-increasing-subsequence/" rel="bookmark" title="Computer Algorithms: Longest Increasing Subsequence">Computer Algorithms: Longest Increasing Subsequence </a></li>
</ol>
</div>
]]></description>
				<content:encoded><![CDATA[<h2>Introduction</h2>
<p>We saw how to find the shortest path in a graph with positive edges using the <a href="/2012/10/15/computer-algorithms-dijkstra-shortest-path-in-a-graph/" title="Computer Algorithms: Dijkstra Shortest Path in a Graph">Dijkstra’s algorithm</a>. We also know how to find the shortest paths from a given source node to all other nodes even when there are negative edges using <a href="/2012/10/22/computer-algorithms-bellman-ford-shortest-path-in-a-graph/" title="Computer Algorithms: Bellman-Ford Shortest Path in a Graph">the Bellman-Ford algorithm</a>. Now we’ll see that there’s a faster algorithm running in linear time that can find the shortest paths from a given source node to all other reachable vertices in a directed acyclic graph, also known as a DAG.</p>
<p>Because the DAG is acyclic we don’t have to worry about negative cycles. As we already know it’s pointless to speak about shortest path in the presence of negative cycles because we can “loop” over these cycles and practically our path will become shorter and shorter.</p>
<figure id="attachment_3431" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/10/1.-Negative-Cycles.png"><img src="/wp-content/uploads/2012/10/1.-Negative-Cycles.png" alt="Negative Cycles" title="Negative Cycles" width="620" height="399" class="size-full wp-image-3431" srcset="/wp-content/uploads/2012/10/1.-Negative-Cycles.png 620w, /wp-content/uploads/2012/10/1.-Negative-Cycles-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">The presence of a negative cycles make our atempt to find the shortest path pointless!</figcaption></figure>
<p>Thus we have two problems to overcome with Dijkstra and the Bellman-Ford algorithms. First of all we needed only positive weights and on the second place we didn’t want cycles. Well, we can handle both cases in this algorithm.<span id="more-3419"></span></p>
<h2>Overview</h2>
<p>The first thing we know about DAGs is that they can easily be topologically sorted. <a href="/2012/10/01/computer-algorithms-topological-sort-of-a-graph/" title="Computer Algorithms: Topological Sort of a Graph">Topological sort</a> can be used in many practical cases, but perhaps the mostly used one is when trying to schedule dependent tasks.</p>
<figure id="attachment_3429" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/10/2.-Topological-Sort.png"><img src="/wp-content/uploads/2012/10/2.-Topological-Sort.png" alt="Topological Sort" title="Topological Sort" width="620" height="399" class="size-full wp-image-3429" srcset="/wp-content/uploads/2012/10/2.-Topological-Sort.png 620w, /wp-content/uploads/2012/10/2.-Topological-Sort-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">Topological sort is often used to &#8220;sort&#8221; dependent tasks!</figcaption></figure>
<p>After a topological sort we end with a list of vertices of the DAG and we’re sure that if there’s an edge (u, v), u will precede v in the topologically sorted list.</p>
<figure id="attachment_3430" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/10/3.-Topological-Sort-part-2.png"><img src="/wp-content/uploads/2012/10/3.-Topological-Sort-part-2.png" alt="Topological Sort (part 2)" title="Topological Sort (part 2)" width="620" height="399" class="size-full wp-image-3430" srcset="/wp-content/uploads/2012/10/3.-Topological-Sort-part-2.png 620w, /wp-content/uploads/2012/10/3.-Topological-Sort-part-2-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">If there&#8217;s an edge (u,v) then u must precede v. This results in the more general case from the image. There&#8217;s no edge between B and D, but B precedes D!</figcaption></figure>
<p>This information is precious and the only thing we need to do is to pass through this sorted list and to calculate distances for a shortest paths just like the algorithm of Dijkstra.</p>
<p>OK, so let’s summarize this algorithm:<br />
&#8211;	First we must topologically sort the DAG;<br />
&#8211;	As a second step we set the distance to the source to 0 and infinity to all other vertices;<br />
&#8211;	Then for each vertex from the list we pass through all its neighbors and we check for shortest path;</p>
<p>It’s pretty much like the Dijkstra’s algorithm with the main difference that we used a priority queue then, while this time we use the list from the topological sort.</p>
<h2>Code</h2>
<p>This time the code is actually a pseudocode. Altough all the examples so far was in PHP, perhaps pseudocode is easier to understand and doesn&#8217;t bind you in a specific language implementation. Also if you don&#8217;t feel comforatable with the given programming language it can be more difficult for you to understand the code than by reading pseudocode.</p>
<pre lang="PHP line="1">
1. Topologically sort G into L;
2. Set the distance to the source to 0;
3. Set the distances to all other vertices to infinity;
4. For each vertex u in L
5.    - Walk through all neighbors v of u;
6.    - If dist(v) > dist(u) + w(u, v) 
7.       - Set dist(v) <- dist(u) + w(u, v);
</pre>
<h2>Application</h2>
<p>It’s clear why and where we must use this algorithm. The only problem is that we must be sure that the graph doesn’t have cycles. However if we’re aware of how the graph is created we may have some additional information if there are cycles or not – then this linear time algorithm can be very applicable. </p>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<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/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/15/computer-algorithms-dijkstra-shortest-path-in-a-graph/" rel="bookmark" title="Computer Algorithms: Dijkstra Shortest Path in a Graph">Computer Algorithms: Dijkstra Shortest Path in a Graph </a></li>
<li><a href="/2012/12/03/computer-algorithms-longest-increasing-subsequence/" rel="bookmark" title="Computer Algorithms: Longest Increasing Subsequence">Computer Algorithms: Longest Increasing Subsequence </a></li>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>/2012/10/28/computer-algorithms-shortest-path-in-a-directed-acyclic-graph/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Computer Algorithms: Bellman-Ford Shortest Path in a Graph</title>
		<link>/2012/10/22/computer-algorithms-bellman-ford-shortest-path-in-a-graph/</link>
		<comments>/2012/10/22/computer-algorithms-bellman-ford-shortest-path-in-a-graph/#comments</comments>
		<pubDate>Mon, 22 Oct 2012 13:55:28 +0000</pubDate>
		<dc:creator><![CDATA[Stoimen]]></dc:creator>
				<category><![CDATA[algorithms]]></category>
		<category><![CDATA[data structures]]></category>
		<category><![CDATA[Graphs]]></category>
		<category><![CDATA[Adjacency matrix]]></category>
		<category><![CDATA[Algebraic graph theory]]></category>
		<category><![CDATA[Bellman–Ford algorithm]]></category>
		<category><![CDATA[Dijkstra's algorithm]]></category>
		<category><![CDATA[Floyd–Warshall algorithm]]></category>
		<category><![CDATA[Graph theory]]></category>
		<category><![CDATA[Lester Ford Jr.]]></category>
		<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[Matrix]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Richard E. Bellman]]></category>
		<category><![CDATA[Routing algorithms]]></category>
		<category><![CDATA[Shortest path problem]]></category>
		<category><![CDATA[The algorithm]]></category>
		<category><![CDATA[Theoretical computer science]]></category>

		<guid isPermaLink="false">/?p=3417</guid>
		<description><![CDATA[Introduction As we saw in the previous post, the algorithm of Dijkstra is very useful when it comes to find all the shortest paths in a weighted graph. However it has one major problem! Obviously it doesn’t work correctly when dealing with negative lengths of the edges. We know that the algorithm works perfectly when &#8230; <a href="/2012/10/22/computer-algorithms-bellman-ford-shortest-path-in-a-graph/" class="more-link">Continue reading <span class="screen-reader-text">Computer Algorithms: Bellman-Ford 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/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/15/computer-algorithms-dijkstra-shortest-path-in-a-graph/" rel="bookmark" title="Computer Algorithms: Dijkstra Shortest Path in a Graph">Computer Algorithms: Dijkstra Shortest Path in a Graph </a></li>
<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/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>As we saw in the previous post, <a title="Computer Algorithms: Dijkstra Shortest Path in a Graph" href="/2012/10/15/computer-algorithms-dijkstra-shortest-path-in-a-graph/">the algorithm of Dijkstra</a> is very useful when it comes to find all the shortest paths in a weighted graph. However it has one major problem! Obviously it doesn’t work correctly when dealing with negative lengths of the edges.</p>
<p>We know that the algorithm works perfectly when it comes to positive edges, and that is absolutely normal because we try to optimize the inequality of the triangle.</p>
<figure id="attachment_3420" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/10/1.-Dijkstras-Approach.png"><img class="size-full wp-image-3420" title="Dijkstra's Approach" src="/wp-content/uploads/2012/10/1.-Dijkstras-Approach.png" alt="Dijkstra's Approach" width="620" height="399" srcset="/wp-content/uploads/2012/10/1.-Dijkstras-Approach.png 620w, /wp-content/uploads/2012/10/1.-Dijkstras-Approach-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">Since all the edges are positive we get the closest one!</figcaption></figure>
<p>Since Dijkstra’s algorithm make use of a priority queue normally we get first the shortest adjacent edge to the starting point. In our very basic example we’ll get first the edge with the length of 3 -&gt; (S, A).</p>
<p>However when it comes to negative edges we can&#8217;t use any more priority queues, so we need a different, yet working solution.<span id="more-3417"></span></p>
<h2>Overview</h2>
<p>The solution was published by <a title="Richard E. Bellman" href="http://en.wikipedia.org/wiki/Richard_Bellman" target="_blank">Richard E. Bellman</a> and <a title="Lester Ford, Jr." href="http://en.wikipedia.org/wiki/L._R._Ford,_Jr." target="_blank">Lester Ford, Jr.</a> in 1958 in their publication &#8220;On a Routing Problem&#8221; and it is quite simple to explain and understand. Since we can prioritize the edges by its lengths the only thing we should do is to calculate <span style="text-decoration: underline;">all</span> the paths. And to be sure that our algorithm will find all the paths correctly we repeat that N-1 times, where N is the number of vertices (|V| = N)!</p>
<figure id="attachment_3421" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/10/2.-Bellman-Ford-Approach.png"><img src="/wp-content/uploads/2012/10/2.-Bellman-Ford-Approach.png" alt="Bellman-Ford Approach" title="Bellman-Ford Approach" width="620" height="399" class="size-full wp-image-3421" srcset="/wp-content/uploads/2012/10/2.-Bellman-Ford-Approach.png 620w, /wp-content/uploads/2012/10/2.-Bellman-Ford-Approach-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">The algorithm of Bellman-Ford doesn&#8217;t use priority queues! Indeed they are useless since the closest node in the queue can have shorter path passing through another node!</figcaption></figure>
<p>In this very basic image we can see how Bellman-Ford solves the problem. First we get the distances from S to A and B, which are respectively 3 and 4, but there is a shorter path to A, which passes through B and it is (S, B) + (B, A) = 4 – 2 = 2.</p>
<h2>Code</h2>
<p>Here’s the code on <a href="/category/php/" title="PHP on Stoimen.com">PHP</a>. Note that this time we use an adjacency matrix and an additional array of distances. It’s important (for directed graphs, and our graph this time is directed) to put the positive value of A[j][i] if A[i][j] is negative. Note the case for A[1][2]!</p>
<pre lang="PHP">
define('INFINITY', 10000000);

$matrix = array(
    0 => array( 0,  3,  4),
    1 => array( 0,  0,  2),
    2 => array( 0,  -2, 0),
);

$len = count($matrix);

$dist = array();

function BellmanFord(&$matrix, &$dist, $start)
{
    global $len;
    
    foreach (array_keys($matrix) as $vertex) {
        $dist[$vertex] = INFINITY;
        if ($vertex == $start) {
            $dist[$vertex] = 0;
        }
    }
    
    for ($k = 0; $k < $len - 1; $k++) {
        for ($i = 0; $i < $len; $i++) {
            for ($j = 0; $j < $len; $j++) {
                if ($dist[$i] > $dist[$j] + $matrix[$j][$i]) {
                    $dist[$i] = $dist[$j] + $matrix[$j][$i];
                }
            }
        }
    }
}

BellmanFord($matrix, $dist, 0);

// [0, 2, 4]
print_r($dist);
</pre>
<h3>Complexity</h3>
<p>The complexity is clearly O(n<sup>3</sup>) which follows directly from the code above.</p>
<h2>Application</h2>
<p>Actually this algorithm is very useful and it not only works with negative weights, but also can help us find negative cycles in the graph.</p>
<figure id="attachment_3422" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/10/3.-Negative-Cycles.png"><img src="/wp-content/uploads/2012/10/3.-Negative-Cycles.png" alt="Negative Cycles" title="Negative Cycles" width="620" height="399" class="size-full wp-image-3422" srcset="/wp-content/uploads/2012/10/3.-Negative-Cycles.png 620w, /wp-content/uploads/2012/10/3.-Negative-Cycles-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">A negative cycle can be found with Bellman-Ford&#8217;s algorithm!</figcaption></figure>
<p>This is done with the simple check after the main loop.</p>
<pre lang="PHP">
    for ($i = 0; $i < $len; $i++) {
        for ($j = 0; $j < $len; $j++) {
            if ($dist[$i] > $dist[$j] + $matrix[$j][$i]) {
                echo 'The graph contains a negative cycle!';
            }
        }
    }
</pre>
<p>And here&#8217;s the full code.</p>
<pre lang="PHP">
$matrix = array(
    0 => array( 0,  3,  4),
    1 => array( 0,  0,  2),
    2 => array( 0,  -2, 0),
);

$len = count($matrix);

$dist = array();

function BellmanFord(&$matrix, &$dist, $start)
{
    global $len;
    
    foreach (array_keys($matrix) as $vertex) {
        $dist[$vertex] = INFINITY;
        if ($vertex == $start) {
            $dist[$vertex] = 0;
        }
    }
    
    for ($k = 0; $k < $len - 1; $k++) {
        for ($i = 0; $i < $len; $i++) {
            for ($j = 0; $j < $len; $j++) {
                if ($dist[$i] > $dist[$j] + $matrix[$j][$i]) {
                    $dist[$i] = $dist[$j] + $matrix[$j][$i];
                }
            }
        }
    }
    
    for ($i = 0; $i < $len; $i++) {
        for ($j = 0; $j < $len; $j++) {
            if ($dist[$i] > $dist[$j] + $matrix[$j][$i]) {
                echo 'The graph contains a negative cycle!';
            }
        }
    }
}

BellmanFord($matrix, $dist, 0);

// [0, 2, 4]
print_r($dist);
</pre>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<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/15/computer-algorithms-dijkstra-shortest-path-in-a-graph/" rel="bookmark" title="Computer Algorithms: Dijkstra Shortest Path in a Graph">Computer Algorithms: Dijkstra Shortest Path in a Graph </a></li>
<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/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/22/computer-algorithms-bellman-ford-shortest-path-in-a-graph/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<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>
		<item>
		<title>Computer Algorithms: Graph Breadth First Search</title>
		<link>/2012/09/10/computer-algorithms-graph-breadth-first-search/</link>
		<comments>/2012/09/10/computer-algorithms-graph-breadth-first-search/#comments</comments>
		<pubDate>Sun, 09 Sep 2012 21:52:49 +0000</pubDate>
		<dc:creator><![CDATA[Stoimen]]></dc:creator>
				<category><![CDATA[algorithms]]></category>
		<category><![CDATA[data structures]]></category>
		<category><![CDATA[Breadth-first search]]></category>
		<category><![CDATA[Connected component]]></category>
		<category><![CDATA[Depth-first search]]></category>
		<category><![CDATA[Dijkstra's algorithm]]></category>
		<category><![CDATA[Graph]]></category>
		<category><![CDATA[graph algorithms]]></category>
		<category><![CDATA[Graph theory]]></category>
		<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[search algorithms]]></category>
		<category><![CDATA[search start]]></category>
		<category><![CDATA[search walks]]></category>
		<category><![CDATA[Theoretical computer science]]></category>

		<guid isPermaLink="false">/?p=3338</guid>
		<description><![CDATA[Introduction Since we already know how to represent graphs, we can go further for some very simple approaches of walking through them. Passing by all the vertices of a graph is a fundamental technique for most of the graph algorithms, such as finding shortest/longest paths, etc. First thing to note is that graphs are not &#8230; <a href="/2012/09/10/computer-algorithms-graph-breadth-first-search/" class="more-link">Continue reading <span class="screen-reader-text">Computer Algorithms: Graph Breadth First Search</span> <span class="meta-nav">&#8594;</span></a><div class='yarpp-related-rss'>

Related posts:<ol>
<li><a href="/2012/09/17/computer-algorithms-graph-depth-first-search/" rel="bookmark" title="Computer Algorithms: Graph Depth-First Search">Computer Algorithms: Graph Depth-First Search </a></li>
<li><a href="/2012/09/24/computer-algorithms-graph-best-first-search/" rel="bookmark" title="Computer Algorithms: Graph Best-First Search">Computer Algorithms: Graph Best-First Search </a></li>
<li><a href="/2012/10/15/computer-algorithms-dijkstra-shortest-path-in-a-graph/" rel="bookmark" title="Computer Algorithms: Dijkstra Shortest Path in a Graph">Computer Algorithms: Dijkstra Shortest Path in a Graph </a></li>
<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>
</ol>
</div>
]]></description>
				<content:encoded><![CDATA[<h2>Introduction</h2>
<p>Since we already know <a href="/2012/08/31/computer-algorithms-graphs-and-their-representation/" title="Computer Algorithms: Graphs and their Representation">how to represent graphs</a>, we can go further for some very simple approaches of walking through them. Passing by all the vertices of a graph is a fundamental technique for most of the graph algorithms, such as finding shortest/longest paths, etc.</p>
<p>First thing to note is that graphs are not trees, in most of the cases, so walking through them can&#8217;t start from a root, as we do with trees. What we must do first is to decide from where to start – in other words &#8211; choosing a starting vertex. </p>
<figure id="attachment_3343" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/09/1.-BFS-Choosing-a-Starting-Point.png"><img src="/wp-content/uploads/2012/09/1.-BFS-Choosing-a-Starting-Point.png" alt="BFS Choosing a Starting Point" title="BFS Choosing a Starting Point" width="620" height="399" class="size-full wp-image-3343" srcset="/wp-content/uploads/2012/09/1.-BFS-Choosing-a-Starting-Point.png 620w, /wp-content/uploads/2012/09/1.-BFS-Choosing-a-Starting-Point-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">It&#8217;s clear that depending on the starting point we can get different passes through the graph. Thus choosing a starting point can be very important for our algorithm!</figcaption></figure>
<p>After that we need to know how to proceed. There are two approaches mostly known as “breadth first” and “depth first” search. While depth first search start from a vertex and goes as far as possible, then walks back and passes through vertices that haven’t been visited yet, breath first search is an approach of passing through all the neighbors of the node first, and then go to the next level.<br />
<span id="more-3338"></span></p>
<h2>Overview</h2>
<p>We can thing of breadth first search as a “wave” walk through the graph. In other words we go level by level, as shown on the picture below.</p>
<figure id="attachment_3344" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/09/2.-BFS-Wave.png"><img src="/wp-content/uploads/2012/09/2.-BFS-Wave.png" alt="BFS Wave" title="BFS Wave" width="620" height="399" class="size-full wp-image-3344" srcset="/wp-content/uploads/2012/09/2.-BFS-Wave.png 620w, /wp-content/uploads/2012/09/2.-BFS-Wave-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">For this very specific graph on the picture we can see how breadth first search walks through the graph level by level!</figcaption></figure>
<p>Initially we mark all vertices as unvisited. A common approach is to create an empty queue where we put the vertices level by level, starting with the initial vertex.</p>
<figure id="attachment_3342" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/09/3.-BFS-Using-a-Queue.png"><img src="/wp-content/uploads/2012/09/3.-BFS-Using-a-Queue.png" alt="BFS Using a Queue" title="BFS Using a Queue" width="620" height="399" class="size-full wp-image-3342" srcset="/wp-content/uploads/2012/09/3.-BFS-Using-a-Queue.png 620w, /wp-content/uploads/2012/09/3.-BFS-Using-a-Queue-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">Using a queue is a typical approach for breadth first search! However this requires more space!</figcaption></figure>
<h2>Code</h2>
<p>This simple approach is fairly easy to implement. Here’s the <a href="/category/php/" title="PHP on Stoimen.com">PHP</a> implementation in few lines of code.</p>
<pre lang="PHP">
<?php

$g = array(
    0 => array(0, 1, 1, 0, 0, 0),
    1 => array(1, 0, 0, 1, 0, 0),
    2 => array(1, 0, 0, 1, 0, 0),
    3 => array(0, 1, 1, 0, 1, 0),
    4 => array(0, 0, 0, 1, 0, 1),
    5 => array(0, 0, 0, 0, 1, 0),
);

function init(&$visited, &$graph) 
{
    foreach ($graph as $key => $vertex) {
        $visited[$key] = 0;
    }
}

function breadth_first(&$graph, $start, $visited)
{
    // create an empty queue
    $q = array();
    
    // initially enqueue only the starting vertex
    array_push($q, $start);
    $visited[$start] = 1;
    echo $start . "\n";
    
    while (count($q)) {
        $t = array_shift($q);
        
        foreach ($graph[$t] as $key => $vertex) {
            if (!$visited[$key] && $vertex == 1) {
                $visited[$key] = 1;
                array_push($q, $key);
                echo $key . "\t";
            }
        }
        echo "\n";
    }
}

$visited = array();
init($visited, $g);
breadth_first($g, 2, $visited);
</pre>
<h2>Complexity</h2>
<p>The complexity of this algorithm clearly is O(n<sup>2</sup>).</p>
<h2>Application</h2>
<p>As I said breadth first and depth first searches are used in many practical cases, as finding shortest/minimal paths etc. That is why understanding these basic principles of walking through a graph is crucial for other, more complex, graph algorithms.</p>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<li><a href="/2012/09/17/computer-algorithms-graph-depth-first-search/" rel="bookmark" title="Computer Algorithms: Graph Depth-First Search">Computer Algorithms: Graph Depth-First Search </a></li>
<li><a href="/2012/09/24/computer-algorithms-graph-best-first-search/" rel="bookmark" title="Computer Algorithms: Graph Best-First Search">Computer Algorithms: Graph Best-First Search </a></li>
<li><a href="/2012/10/15/computer-algorithms-dijkstra-shortest-path-in-a-graph/" rel="bookmark" title="Computer Algorithms: Dijkstra Shortest Path in a Graph">Computer Algorithms: Dijkstra Shortest Path in a Graph </a></li>
<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>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>/2012/09/10/computer-algorithms-graph-breadth-first-search/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
