7.2. Directed Graphs#

In a graph, we only care about whether vertices are connected or not; an edge is a set \(\\) , indicated that the vertices \(u\) and \(v\) are adjacent.

If we want the connection to be ordered, then we arrive at directed graphs or digraphs. The only difference from simple graphs is that edges are now ordered pairs \((u,v)\) .

Definition (directed graph)

A directed graph is a pair \((V,E)\) consisting of a non-empty set of vertices \(V\) and a set of directed edges \(E\) with \(E \subseteq V \times V\) .

All of our previous definitions and terminologies extend natrually to the directed case. The only difference now is that edges are tuples of size \(2\) rather than sets of size \(2\) (or \(1\) for loops).

The in-degree of a vertex \(v\) in a directed graph is the number of edges which terminate at \(v\) . It is denoted \(deg^-(v)\) .

The out-degree of a vertex \(v\) in a directed graph is the number of edges which start at \(v\) . It is denoted \(deg^+(v)\) .

In Fig. 7.52 , vertex \(6\) has in-degree \(2\) , and out-degree \(0\) . Vertex \(1\) has in-degree \(0\) and out-degree \(2\) . Vertex \(7\) has in-degree \(1\) and out-degree \(2\) . That is, a loop contributes one to both in-degree and out-degree.

Similar to the Handshake Theorem of undirected graphs, we have a theorem related in- and out-degree with the number of edges.

Let \(G = (V,E)\) be a directed graph. Then:

\[ |E| = \sum_ deg^-(v) = \sum_ deg^+(v) \]

Proof: Every edge in the graph has an initial vertex and a terminating vertex. Therefore, the total number of incoming edges in the graph is equal to the sum of the in-degrees of all vertices. The total number of outgoing edges is also equal to the sum of the out-degrees of all vertices. \(\blacksquare\)

7.2.1. Directed Connectivity#

From undirected graphs, we say two vertices \(u\) and \(v\) are connected if the edge \(\\) exists in the graph. And a graph is connected when a path exists from every vertex to every other vertex.

For directed graphs, we have two notions of connectivity, since a vertex connected to an edge may be the initial vertex or the terminal vertex. In particular, the notion of a path changes.

Definition (directed path)

A directed path (or simply path) of a directed graph \(G = (V,E)\) is a sequence of vertices \((v_n)\) where \((v_i, v_) \in E\) for for \(1 \leq i < n\) .

In a directed graph you must “follow the arrows”. Edges can only be traversed from its initial vertex to its terminal vertex. We thus have the first kind of connectivity for a directed graph, which is the same definition (although different meaning) for a directed graph.

Definition (strongly connected)

A directed graph is strongly connected if there is a directed path from every vertex to every other vertex.

Therefore, our previous directed graph in Fig. 7.52 is not strongly connected. For example, there is no directed path which starts at vertex \(6\) .

In particular, as a corollary of this definition, a strongly connected directed graph cannot have any sink vertices or any source vertices. This is a natural consequence of the definitions. The proof is left to the reader.

The graph shown above is strongly connected since a path exists from every vertex to every other vertex. It may be a rather complex path, a path exists nonetheless. For example, the path \((3,4,2,1)\) connects \(3\) to \(1\) , the path \((1, 2, 3)\) connects \(1\) to \(3\) , etc.

To existence of strong connectivity suggests the existence of weak connected. For that, we need one more definition first: the underlying graph.

Definition (underlying graph)

Given a directed graph \(G = (V,E)\) , its underlying graph is the undirected graph obtained by replacing every directed edge with an undirected edge.

Definition (weakly connected)

A directed graph is weakly connected if its underlying graph is connected.

By this definition, Fig. 7.54 is not weakly connected. Indeed, we can see in its underlying graph that there are two separate connected components: \(\\) and \(\\) .

Speaking of connected components, these two definitions of connectivity yield two definitions of a connected component.

Definition (strongly connected component)

An induced subgraph \(H = (W,F)\) of a directed graph \(G = (V,E)\) is a strongly connected component if \(H\) is a strongly connected directed graph and adding any other vertex \(v \in V \setminus W\) would make \(H\) not strongly connected.

Definition (weakly connected component)

A weakly connected component of a directed graph is the directed subgraph induced by a connected component of its underlying graph.

Therefore, Fig. 7.54 has two weakly connected components but no strongly connected components.

Checkpoint

Finding Connected Components

Find all the weakly and strongly connected components of the above graph

Finding Connected Components

7.2.2. Binary Relations as Graphs#

Recall Relations . Let \(\mathcal\) be a binary relation on a set \(A\) . We know that \(\mathcal\) is a subset of \(A \times A\) .

We also saw in the previous section that directed graphs have the set of edges \(E\) be a subset of \(V \times V\) , for the vertex set \(V\) . Thus, the set of edges in a directed graph actually indues a binary relation on the set of vertices.

If you can describe the edges of a directed graph as pairs of vertices, then you can describe the binary relation induced on the vertex set.

Consider the following graph on the vertex set \(\\) . What is the binary relation that it encodes?

Let’s try the opposite direction now.

Checkpoint

The Graph of a Binary Relation

Consider the binary relation \(\mathcal\) on \(A = \<1,2,3,\ldots,8\>\) defined as:

Can you draw the corresponding graph?

Finding Connected Components

When drawing a graph representing a binary relation on a large or infinite set, it is fine to only draw the vertices directly part of the relation. You do not need “floating” vertices connected to nothing.

Drawing graphs representing binary relations may feel reminiscent of Hasse Diagram . And it’s not that much different. Hasse diagrams are just graphs with some additional conditions:

  1. The vertex representing \(a\) is drawn above any other element \(b \in A\) such that \(a \preceq b\) .
  2. “Transitive” edges are omitted.

For \(A = \\) , consider the binary relation induced on \(\mathcal(A)\) and the subset partial ordering \(\subseteq\) . We have seen its Hasse diagram in Hasse Diagram . It is repeated below. Now, can you draw the graph which would explicitly encode the binary relation?

Yeah… this is incredibly ugly. That’s why Hasse diagrams are so much better!

7.2.3. Directed Acyclic Graphs#

A very important class of directed graphs is directed acyclic graphs. As the name suggests, they are directed graphs with no loops!

Definition (directed acyclic graph)

A directed acyclic graph (DAG) is a directed graph with no directed cycles.

So far, every directed graph we have seen (except the hidden solution of Fig. 7.58 ) have not been DAGs. Go back and check. Can you find cycles in all of those directed graphs?

Indeed, DAGs have certain properties as a simple consequence of having no cycles:

DAGs are incredibly important for describing scheduling problems, program structure, data processing, machine learning, version control, and much more.

The most useful property of DAGs, and why they are so useful in practice, is that they can always be topologically ordered. That is, they can be drawn in such a way that all edges point in the same direction. Consider the below DAG. It is a mess of edges.

A topological ordering of this DAG has all edges oriented in the same direction. Not necessarily parallel lines or anything, but more or less “flowing” in the same direction. Typically, left to right, or top to bottom. Below is Fig. 7.60 topologically ordered.

Control-Flow Graphs#

(This section isn’t testable. It’s just for fun.)

So why are DAGs so useful in practice? Consider what the topological ordering of the DAG above suggests. It gives an explicit “prerequisite structure”:

This has natural applications to scheduling and data processing.

DAGs are also very good at representing the control flow of programs. In particular, they can be used to represent control-flow graphs. Control-flow graphs are essential to compiler theory and program optimization.

In general, control-flow graphs can have cycles, and are thus described best by directed graphs. However, loop management is particularly challenging. So let’s consider only acyclic control-flow graphs. Thus, DAGs.

from random import randint x = randint(0,10) if (x  5) : print("Foo"); else: print("Bar"); print("Done");