<?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>Adjacency matrix &#8211; stoimen&#039;s web log</title>
	<atom:link href="/tag/adjacency-matrix/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: 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: Graph Best-First Search</title>
		<link>/2012/09/24/computer-algorithms-graph-best-first-search/</link>
		<comments>/2012/09/24/computer-algorithms-graph-best-first-search/#comments</comments>
		<pubDate>Mon, 24 Sep 2012 10:44:53 +0000</pubDate>
		<dc:creator><![CDATA[Stoimen]]></dc:creator>
				<category><![CDATA[algorithms]]></category>
		<category><![CDATA[data structures]]></category>
		<category><![CDATA[Adjacency matrix]]></category>
		<category><![CDATA[Algebraic graph theory]]></category>
		<category><![CDATA[Breadth-first search]]></category>
		<category><![CDATA[Depth-first search]]></category>
		<category><![CDATA[Graph]]></category>
		<category><![CDATA[Graph theory]]></category>
		<category><![CDATA[graph traversal algorithms]]></category>
		<category><![CDATA[Hopcroft–Karp algorithm]]></category>
		<category><![CDATA[Matching]]></category>
		<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[Path decomposition]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[possible solution]]></category>
		<category><![CDATA[search algorithms]]></category>
		<category><![CDATA[two algorithms]]></category>
		<category><![CDATA[typical greedy algorithm]]></category>
		<category><![CDATA[USD]]></category>

		<guid isPermaLink="false">/?p=3347</guid>
		<description><![CDATA[Introduction So far we know how to implement graph depth-first and breadth-first search. These two approaches are crucial in order to understand graph traversal algorithms. However they are just explaining how we can walk through in breadth or depth and sometimes this isn&#8217;t enough for an efficient solution of graph traversal. In the examples so &#8230; <a href="/2012/09/24/computer-algorithms-graph-best-first-search/" class="more-link">Continue reading <span class="screen-reader-text">Computer Algorithms: Graph Best-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/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/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>So far we know how to implement graph <a href="/2012/09/17/computer-algorithms-graph-depth-first-search/" title="Computer Algorithms: Graph Depth-First Search">depth-first</a> and <a href="/2012/09/10/computer-algorithms-graph-breadth-first-search/" title="Computer Algorithms: Graph Breadth First Search">breadth-first</a> search. These two approaches are crucial in order to understand graph traversal algorithms. However they are just explaining how we can walk through in breadth or depth and sometimes this isn&#8217;t enough for an efficient solution of graph traversal.</p>
<p>In the examples so far we had an undirected, unweighted graph and we were using adjacency matrices to represent the graphs. By <a href="/2012/08/31/computer-algorithms-graphs-and-their-representation/" title="Computer Algorithms: Graphs and their Representation">using adjacency matrices</a> we store <strong>1</strong> in the A[i][j] if there’s an edge between vertex i and vertex j. Otherwise we put a <strong>0</strong>. However the value of <strong>1</strong> gives us only the information that we have an edge between two vertices, which is not always enough when designing graphs.</p>
<p>Indeed graphs can be weighted. Sometimes the path between two vertices can have a value. Thinking of a road map we know that distances between cities are represented in miles or kilometers. Thus often representing a road map as a graph, we don’t put just 1 between city A and city B, to say that there is a path between them, but also we put some meaningful information – let’s say the distance in miles between A and B. </p>
<p>Note that this value can be the distance in miles, but it can be something else, like the time in hours we’ve to walk between those two cities. In general this value is a function of A and B. So if we keep the distance between A and B we can say this function is F(A, B) = X, or distance(A, B) = X miles.</p>
<p>Of course in this particular example F(A, B) = F(B, A), but this isn’t always true in practice. We can have a directed graph where F(A, B) != F(B, A).</p>
<p>Here I talk about distance between two cities and it is the edge that brings some additional information. However sometimes we have to store the value of the vertices. Let&#8217;s say I&#8217;m playing a game (like chess) and each move brings me some additional benefit. So each move (vertex) can be evaluated with some particular value. Thus sometimes we don&#8217;t have a function of and edge like F(A, B), but function of the vertices, like F(A) and F(B).</p>
<p>In breadth-first search and depth-first search we just pick up a vertex and we consecutively walk through all its successors that haven’t been visited yet.</p>
<figure id="attachment_3357" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/09/1.-Unweithed-Graph-Walkthrough.png"><img src="/wp-content/uploads/2012/09/1.-Unweithed-Graph-Walkthrough.png" alt="Walk Through an Unweithed Graph" title="Unweithed Graph Walkthrough" width="620" height="399" class="size-full wp-image-3357" srcset="/wp-content/uploads/2012/09/1.-Unweithed-Graph-Walkthrough.png 620w, /wp-content/uploads/2012/09/1.-Unweithed-Graph-Walkthrough-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">In order to walk through an unweithed graph using DFS, we chose consecutively each successor of node i!</figcaption></figure>
<p>So in DFS in particular we started from left to right in the array above. So the first node that has to be explored is vertex “1”.</p>
<pre lang="PHP">
0: [0, 1, 0, 0, 1, 1]
</pre>
<p>However sometimes, as I said above, we have weighted graphs, so the question is – is there any problem, regarding to the algorithm speed, if we go consecutively through all successors. The answer in general is yes, so we must modify a bit our code in order to continue not with the first but with the best matching successor. By best-matching we mean that the successor should match some criteria like – minimal or maximal value.<span id="more-3347"></span></p>
<h2>Overview</h2>
<p>In the following example we see that some of the successors of vertex 0 are very far from it, while others are closer. Thus 4 has the value of 5, while node 1’s value is 2 and 5 is 1.</p>
<figure id="attachment_3359" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/09/2.-BFS-and-Weighted-Graph.png"><img src="/wp-content/uploads/2012/09/2.-BFS-and-Weighted-Graph.png" alt="DFS and Weighted Graph" title="DFS and Weighted Graph" width="620" height="399" class="size-full wp-image-3359" srcset="/wp-content/uploads/2012/09/2.-BFS-and-Weighted-Graph.png 620w, /wp-content/uploads/2012/09/2.-BFS-and-Weighted-Graph-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">Weithed graph brings us more information about the successors of a given vertex. Thus we have to chose carefully which one to get first in our path exploration!</figcaption></figure>
<pre lang="PHP">
0: [0, 2, 0, 0, 5, 1]
</pre>
<p>In this case if we’re searching for the shortest path between 1 and 3, although 1 and 4 are the first two successors in the adjacency matrix of the &#8220;start&#8221; vertex, we don&#8217;t choose them since there’s a better solution – going through node 5.</p>
<figure id="attachment_3360" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/09/3.-Best-First-Search.png"><img src="/wp-content/uploads/2012/09/3.-Best-First-Search.png" alt="Best-First Search" title="Best-First Search" width="620" height="399" class="size-full wp-image-3360" srcset="/wp-content/uploads/2012/09/3.-Best-First-Search.png 620w, /wp-content/uploads/2012/09/3.-Best-First-Search-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">In best-first search we continue the path to the target through the best-matching successor!</figcaption></figure>
<h3>Problems</h3>
<p>The question is – are we sure that by choosing node 5, we’ll find the best path? Even more! Is there a path through node 5? As we see on the image below both cases are possible.</p>
<figure id="attachment_3361" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/09/4.-BFS-problems.png"><img src="/wp-content/uploads/2012/09/4.-BFS-problems.png" alt="BFS problems" title="BFS problems" width="620" height="399" class="size-full wp-image-3361" srcset="/wp-content/uploads/2012/09/4.-BFS-problems.png 620w, /wp-content/uploads/2012/09/4.-BFS-problems-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">Somtimes best-first search doesn&#8217;t find the &#8220;best&#8221; (shortest/longest/cheapest) path to the target!</figcaption></figure>
<p>Practically best-first search is identical with depth-first search, with the main difference that we choose the best-matching successor instead of choosing the first matching successor. So we’re sure that we’re going through all the successors but in some particular order, different from DFS. Thus we know that if there’s a path we’ll find it.</p>
<p>However even if we find the path between A and B, we can’t be sure that there is not a better path. We only know that this path is the best so far. </p>
<p>Another question is – how can we find the best matching successor effectively. Well if we’re looking for the minimal or maximal value one possible solution is to sort the array of successors.</p>
<figure id="attachment_3363" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/09/5.-Using-Priority-Queues.png"><img src="/wp-content/uploads/2012/09/5.-Using-Priority-Queues.png" alt="Using Priority Queues" title="Using Priority Queues" width="620" height="412" class="size-full wp-image-3363" srcset="/wp-content/uploads/2012/09/5.-Using-Priority-Queues.png 620w, /wp-content/uploads/2012/09/5.-Using-Priority-Queues-300x199.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">The difference between depth-first and best-first is that we change the order of chosing the next successor!</figcaption></figure>
<pre lang="PHP">
0: [0 => 0, 1 => 2, 2 => 0, 3 => 0, 4 => 5, 5 => 1]
// sorted by value
0: [5 => 1, 1 => 2, 4 => 5, 0 => 0, 2 => 0, 3 => 1]
</pre>
<p>Another good approach will be to use priority queues or heaps.</p>
<p>Thus on every step we’ll get the best matching successor.</p>
<h2>Code</h2>
<p>In general best-first search uses the ground of depth-first search, so its implementation isn&#8217;t more difficult! The following PHP code snippet shows the very small difference between these two algorithms.</p>
<pre lang="PHP">
class Graph 
{
    protected $_len = 0;
    protected $_g = array();
    protected $_visited = array();
    
    public function __construct()
    {
        $this->_g = array(
            array(0, 2, 0, 0, 5, 1),
            array(1, 0, 3, 0, 0, 0),
            array(0, 2, 0, 8, 0, 0),
            array(0, 0, 3, 0, 5, 0),
            array(1, 0, 0, 8, 0, 1),
            array(1, 0, 0, 0, 5, 0),
        );
        
        $this->_len = count($this->_g);
        
        $this->_initVisited();
    }
    
    protected function _initVisited()
    {
        for ($i = 0; $i < $this->_len; $i++) {
            $this->_visited[$i] = 0;
        }
    }
    
    public function bestFirst($vertex)
    {
        $this->_visited[$vertex] = 1;
    
        echo $vertex . "\n";
        
        asort($this->_g[$vertex]);
        
        foreach ($this->_g[$vertex] as $key => $v) {
            if ($v > 0 && !$this->_visited[$key]) {
                $this->bestFirst($key);
            }
        }
    }
}

$g = new Graph();
// 2 1 0 5 4 3
$g->bestFirst(2);
</pre>
<h2>Application</h2>
<p>Best-first search is a typical greedy algorithm. In its principles lies the main greedy approach of chosing the best possible solution so far. It is important to note that depth-first search and breadth-first search are the very basic graph walk through approaches, but they can be also widely extended in order to solve more complex problems.</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/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/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/24/computer-algorithms-graph-best-first-search/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Computer Algorithms: Graphs and their Representation</title>
		<link>/2012/08/31/computer-algorithms-graphs-and-their-representation/</link>
		<comments>/2012/08/31/computer-algorithms-graphs-and-their-representation/#comments</comments>
		<pubDate>Fri, 31 Aug 2012 20:42:25 +0000</pubDate>
		<dc:creator><![CDATA[Stoimen]]></dc:creator>
				<category><![CDATA[algorithms]]></category>
		<category><![CDATA[data structures]]></category>
		<category><![CDATA[Adjacency list]]></category>
		<category><![CDATA[Adjacency matrix]]></category>
		<category><![CDATA[Algebraic graph theory]]></category>
		<category><![CDATA[France]]></category>
		<category><![CDATA[Graph]]></category>
		<category><![CDATA[Graph theory]]></category>
		<category><![CDATA[Implicit graph]]></category>
		<category><![CDATA[Induced path]]></category>
		<category><![CDATA[Line graph]]></category>
		<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[Matrices]]></category>
		<category><![CDATA[Network theory]]></category>
		<category><![CDATA[Shortest path problem]]></category>
		<category><![CDATA[United Kingdom]]></category>

		<guid isPermaLink="false">/?p=3322</guid>
		<description><![CDATA[Introduction Although this post is supposed to be about algorithms I’ll cover more on graphs and their computer representation. I consider this very important, because there are lots of problems solved by using graphs and it is important to understand different types of representation. First of all let’s try to explain what is a graph? &#8230; <a href="/2012/08/31/computer-algorithms-graphs-and-their-representation/" class="more-link">Continue reading <span class="screen-reader-text">Computer Algorithms: Graphs and their Representation</span> <span class="meta-nav">&#8594;</span></a><div class='yarpp-related-rss'>

Related posts:<ol>
<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/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/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>
</ol>
</div>
]]></description>
				<content:encoded><![CDATA[<h2>Introduction</h2>
<p>Although this post is supposed to be about algorithms I’ll cover more on graphs and their computer representation. I consider this very important, because there are lots of problems solved by using graphs and it is important to understand different types of representation.</p>
<p>First of all let’s try to explain what is a graph?</p>
<p>A graph is a specific data structure known in the computer science, that is often used to give a model of different kind of problems where a set of objects relate to each other in some way . For instance, trees are mainly used in order to represent a well-structured hierarchy, but that isn’t enough when modeling objects of the same type. Their relation isn’t always hierarchical! A typical example of graph is a geo map, where we have cities and the roads connecting them. In fact most of the problems solved with graphs relate to finding the shortest or longest path.</p>
<p>Although this is one very typical example actually a huge set of problems is can be solved by using graphs.</p>
<figure id="attachment_3332" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/08/1.-Graph-Tree.png"><img class="size-full wp-image-3332" title="Graph &amp; Tree" src="/wp-content/uploads/2012/08/1.-Graph-Tree.png" alt="Graph &amp; Tree" width="620" height="399" srcset="/wp-content/uploads/2012/08/1.-Graph-Tree.png 620w, /wp-content/uploads/2012/08/1.-Graph-Tree-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text"> </figcaption></figure>
<p><span id="more-3322"></span></p>
<p>As shown on the image above the graph is a “more complex” data structure than the ordinary tree. Thus a graph supports cycles, while the tree doesn’t. In the other hand the nodes of a tree are defined by their parents and children, while in a graph that isn’t true.</p>
<p>In this case each graph is defined by its edges and its vertices. In most of the cases, in order to model and solve our problem, we can assume that the vertices are consecutive numbers starting from (1, or 0 in case of 0 based arrays, as we will see later).</p>
<p>As we see each tree is a graph, but not every graph is a tree.</p>
<p>In first place we must now that graphs can be divided in several categories.</p>
<p>They can be undirected and directed. An undirected graph means that in case there is an edge between the nodes i and j we shell assume that there is a path from i to j, as well as from j to i. In the case of directed graph, we’ll assume that if (i,j) exists there only path from node i to node j and there’s no path between j and i.</p>
<figure id="attachment_3331" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/08/2.-Directed-Graph.png"><img class="size-full wp-image-3331" title="Directed Graph" src="/wp-content/uploads/2012/08/2.-Directed-Graph.png" alt="Directed Graph" width="620" height="399" srcset="/wp-content/uploads/2012/08/2.-Directed-Graph.png 620w, /wp-content/uploads/2012/08/2.-Directed-Graph-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text"> </figcaption></figure>
<p>In this example we assume that all the edges are the same, which in practice isn’t always true. Taking a look back to the example of cities and roads, we know that the roads between different cities are different. In many cases their length in kilometers or miles are defining the algorithm (for instance longest/shortest path). To model this we can use weighted graphs, where each edge is associated with a weight. Note that, in the example below, the weight can be even a negative number. Of course in the example of cities and road that can’t be true, because we can’t have negative distance, but in some cases (let’s say where the path saves us some money) we can have negative values.</p>
<figure id="attachment_3330" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/08/3.-Weithened-Graph.png"><img class="size-full wp-image-3330" title="Weithened Graph" src="/wp-content/uploads/2012/08/3.-Weithened-Graph.png" alt="Weithened Graph" width="620" height="399" srcset="/wp-content/uploads/2012/08/3.-Weithened-Graph.png 620w, /wp-content/uploads/2012/08/3.-Weithened-Graph-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text"> </figcaption></figure>
<p>To complete the whole image, let’s give another example which will make the difference between graphs and trees even bigger. Graphs can be connected and disconnected. This means that the graph is constructed out of two or more sub-graphs without a path between these components. You can think of a disconnected graph as for the roads of the UK and France, since they aren’t connected by land.</p>
<figure id="attachment_3329" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/08/4.-Connected-Graph.png"><img class="size-full wp-image-3329" title="Connected Graph" src="/wp-content/uploads/2012/08/4.-Connected-Graph.png" alt="Connected Graph" width="620" height="399" srcset="/wp-content/uploads/2012/08/4.-Connected-Graph.png 620w, /wp-content/uploads/2012/08/4.-Connected-Graph-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text"> </figcaption></figure>
<h2>Overview</h2>
<p>We know what a graph is in general. However we need an appropriate way to represent them in our programs.</p>
<p>There are many type of representation, which can be very useful in some cases and very useless in others. Two of the mostly used types of representation are the <strong>adjacency matrix</strong> and the <strong>adjacency list</strong>.</p>
<h3>Adjacency Matrix</h3>
<p>In the first case we store a matrix (two-dimensional array) with size NxN, where N is the number of vertices. This means that for each edge between the vertices i and j we have the value of 1 (A[i][j] = 1), and 0 otherwise.</p>
<figure id="attachment_3328" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/08/5.-Undirected-Graph-Adjacency-Matrix.png"><img class="size-full wp-image-3328" title="Undirected Graph &amp; Adjacency Matrix" src="/wp-content/uploads/2012/08/5.-Undirected-Graph-Adjacency-Matrix.png" alt="Undirected Graph &amp; Adjacency Matrix" width="620" height="399" srcset="/wp-content/uploads/2012/08/5.-Undirected-Graph-Adjacency-Matrix.png 620w, /wp-content/uploads/2012/08/5.-Undirected-Graph-Adjacency-Matrix-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text"> </figcaption></figure>
<p>In case of directed graph, we can use 1 for the edge (i,j) and -1 for (j,i) in case the edge is directed from i to j.</p>
<figure id="attachment_3327" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/08/6.-Directed-Graph-Adjacency-Matrix.png"><img class="size-full wp-image-3327" title="Directed Graph &amp; Adjacency Matrix" src="/wp-content/uploads/2012/08/6.-Directed-Graph-Adjacency-Matrix.png" alt="Directed Graph &amp; Adjacency Matrix" width="620" height="399" srcset="/wp-content/uploads/2012/08/6.-Directed-Graph-Adjacency-Matrix.png 620w, /wp-content/uploads/2012/08/6.-Directed-Graph-Adjacency-Matrix-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text"> </figcaption></figure>
<p>For a weighted directed graph we can put the weights instead of 1s.</p>
<figure id="attachment_3326" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/08/7.-Weighted-Graph-Adjacency-Matrix.png"><img class="size-full wp-image-3326" title="Weighted Graph &amp; Adjacency Matrix" src="/wp-content/uploads/2012/08/7.-Weighted-Graph-Adjacency-Matrix.png" alt="Weighted Graph &amp; Adjacency Matrix" width="620" height="399" srcset="/wp-content/uploads/2012/08/7.-Weighted-Graph-Adjacency-Matrix.png 620w, /wp-content/uploads/2012/08/7.-Weighted-Graph-Adjacency-Matrix-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text"> </figcaption></figure>
<h3>Adjacency Lists</h3>
<p>Another useful representation of graphs are the adjacency lists. In this case for each vertex we store a linked lists consisting of all of his successors.</p>
<figure id="attachment_3325" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/08/8.-Directed-Graph-Adjacency-List.png"><img class="size-full wp-image-3325" title="Directed Graph &amp; Adjacency List" src="/wp-content/uploads/2012/08/8.-Directed-Graph-Adjacency-List.png" alt="Directed Graph &amp; Adjacency List" width="620" height="399" srcset="/wp-content/uploads/2012/08/8.-Directed-Graph-Adjacency-List.png 620w, /wp-content/uploads/2012/08/8.-Directed-Graph-Adjacency-List-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text"> </figcaption></figure>
<p>Although these two ways are the mostly used, there are also some other type of representations. Such a useful representation is storing only the connectivity between two vertices i and j only if there’s a path between them. Of course this can help us answer the question “is there a path between i and j” in O(1), but unfortunately we lose the information about the graph and we can&#8217;t build it again out of this representation.</p>
<h2>Complexity</h2>
<p>Most of the basic operations in a graph are:</p>
<ol>
<li>Adding an edge;</li>
<li>Deleting an edge;</li>
<li>Answering the question “is there an edge between i and j&#8221;;</li>
<li>Finding the successors of a given vertex;</li>
<li>Finding (if exists) a path between two vertices;</li>
</ol>
<p>Thus depending on the representation these operations can have different complexities. In case that we’re using <strong>adjacency matrix</strong> we have:</p>
<ol>
<li>Adding an edge &#8211; O(1);</li>
<li>Deleting an edge &#8211; O(1);</li>
<li>Answering the question “is there an edge between i and j” &#8211; O(1);</li>
<li>Finding the successors of a given vertex &#8211; O(n);</li>
<li>Finding (if exists) a path between two vertices – O(n<sup>2</sup>);</li>
</ol>
<p>While for an <strong>adjacency list</strong> we can have:</p>
<ol>
<li>Adding an edge – O(log(n));</li>
<li>Deleting an edge – O(log(n));</li>
<li>Answering the question “is there an edge between i and j” – O(log(n));</li>
<li>Finding the successors of a given vertex – O(k), where &#8220;k&#8221; is the length of the lists containing the successors of i;</li>
<li>Finding (if exists) a path between two vertices – O(n+m) – where m &lt;= n;</li>
</ol>
<p>We now see that depending of the representation of the graph we can have different complexities for the same operations. This is very important while trying to solve a problem and can be crucial while chosing the algorithm.</p>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<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/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/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>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>/2012/08/31/computer-algorithms-graphs-and-their-representation/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>
