To analyze graphs mathematically and computationally, we require robust algebraic representations. While visual diagrams are intuitive for human understanding, computers process graphs using structured matrix formats that allow us to leverage linear algebra to discover graph properties.
Algebraic Graph Theory is a branch of mathematics that uses algebraic methods, specifically matrix theory and linear algebra, to study the structural properties of graphs. Representing graphs as matrices allows us to:
The adjacency matrix (also referred to as a bit matrix or Boolean matrix) is the most common matrix representation of a graph.
Let be a graph with vertices, where the vertices are ordered as . The adjacency matrix of is an matrix defined by:
For weighted graphs, the value is replaced by the edge weight , and non-existent edges are typically represented by or depending on the application.
Consider the following directed graph with 4 vertices:
(1) ------> (2)
^ / |
| / |
| / |
| v v
(4) <------ (3)The matching adjacency matrix for this graph is:
A powerful property of the adjacency matrix is its relationship to paths and walks of varying lengths.
Let be the adjacency matrix of a graph . The entry in row and column of the matrix (using standard matrix multiplication) is equal to the number of distinct walks of length from vertex to vertex .
Base Case (): For , . By definition, is if there is an edge (walk of length 1) from to , and otherwise. The theorem holds.
Inductive Step: Assume the theorem holds for walks of length . That is, represents the number of walks of length from to .
We want to find the number of walks of length from to . Any walk of length from to consists of a walk of length from to some intermediate vertex , followed by a single edge (walk of length 1) from to .
Using the multiplication rule, the number of such walks through is:
To find the total number of walks of length over all possible intermediate vertices , we sum this product over all :
This expression is precisely the definition of the entry in row and column of the matrix product . Thus:
By mathematical induction, the theorem is proved.
Let us compute for the graph defined in Section 2:
Looking at entry , we see there is exactly 1 walk of length 2 from vertex 1 to vertex 3 (which is ).
While the powers of the adjacency matrix provide exact path counts, we often only want to know whether at least one path exists between two vertices. This is captured by the Path Matrix (or Reachability Matrix).
The path matrix is an Boolean matrix where:
Since any simple path in a graph of vertices can have a maximum length of edges (or for cycles), we can calculate reachability by checking all walks up to length .
We define the sum matrix :
The path matrix is the Booleanization of . That is, we apply a logical OR operation:
where denotes the Boolean power of the adjacency matrix, computed using Boolean arithmetic ( for multiplication, for addition).
The incidence matrix represents a graph by focusing on the relationship between its vertices and its edges.
Let be an undirected graph with vertices () and edges (). The incidence matrix is an matrix defined by:
Consider this undirected graph:
(1) -------- e1 -------- (2)
| |
| |
e2 e3
| |
| |
(4) -------- e4 -------- (3)The incidence matrix () is:
In computer science, representing graphs using a 2D array (Adjacency Matrix) is not always ideal. We often compare it with the Adjacency List format.
| Property | Adjacency Matrix | Adjacency List | | :--- | :--- | :--- | | Space Complexity | | | | Edge Lookup () | | | | | (requires resizing) | | | | | | | | | | | | () | () |
Below is a complete, production-grade Python script demonstrating how to define an adjacency matrix, compute its powers to calculate walk counts, and construct the path matrix using standard scientific computing tools.
import numpy as np
class GraphRepresentations:
def __init__(self, num_vertices: int):
self.V = num_vertices
# Initialize an empty adjacency matrix with zeros
self.adj_matrix = np.zeros((self.V, self.V), dtype=int)
def add_directed_edge(self, u: int, v: int):
"""Adds a directed edge from u to v (0-indexed)."""
if 0 <= u < self.V and 0 <= v < self.V:
self.adj_matrix[u][v] = 1
else:
raise IndexError("Vertex index out of bounds."
A square matrix of size V x V where each entry represents the existence (and potentially weight) of an edge between two vertices.
The element at index (i, j) of the k-th power of an adjacency matrix yields the exact number of walks of length k between those vertices.
A Boolean matrix showing whether a path of any length exists between two nodes, which can be computed via Boolean sum operations.
A V x E matrix representing the relationships between vertices and edges, showing which edges are incident to which vertices.
The selection between adjacency matrices (ideal for dense graphs) and adjacency lists (ideal for sparse graphs) based on space complexity and lookup efficiency.
Test your understanding with 5 questions
If A is the adjacency matrix of a simple undirected graph, what does the element (A^k)_{ij} represent?
For a simple undirected graph with V vertices and E edges, what is the sum of all elements in its adjacency matrix A?
Let A be the adjacency matrix of a directed graph (digraph). The sum of the elements in the i-th row of A is equal to which of the following?
Which of the following is the correct dimension of the incidence matrix M for a graph with V vertices and E edges?
In which scenario is an Adjacency Matrix computationally superior to an Adjacency List?
6 Modules
6 Modules