Module 23. Graphs (Graph Theory)
Learning Objectives
- Understand the fundamental principles of graph modeling, implementation, and practical applications using Python libraries.
- Define the key terms; participants should recognize that a graph comprises nodes (or vertices) connected by edges, forming structures that can represent various real-world scenarios.
- Explain the different types of graphs such as directed, undirected, and weighted graphs is crucial for understanding how to model various relationships.
- Implement graphs in Python effectively. Python does not have a built-in graph data type, so student need to familiarize themselves with alternative representations, such as using dictionaries or custom classes. This includes creating, modifying, and accessing graph structures through practical coding exercises, which strengthens programming skills alongside theoretical knowledge.
1. Introduction
A "graph" in mathematics and computer science consists of "nodes", also known as "vertices". Nodes may or may not be connected with one another. In our illustration, Figure 1, - which is a pictorial representation of a graph,
Figure 1. Graphs and its components.
- The node "a" is connected with the node "c", but "a" is not connected with "b". The connecting line between two nodes is called an edge. If the edges between the nodes are undirected, the graph is called an undirected graph. If an edge is directed from one vertex (node) to another, a graph is called a directed graph. An directed edge is called an arc. Though graphs may look very theoretical, many practical problems can be represented by graphs. They are often used to model problems or situations in physics, biology, psychology and above all in computer science. In computer science, graphs are used to represent networks of communication, data organization, computational devices, the flow of computation, In the latter case, the are used to represent the data organization, like the file system of an operating system, or communication networks. The link structure of websites can be seen as a graph as well, i.e. a directed graph, because a link is a directed edge or an arc. Python has no built-in data type or class for graphs, but it is easy to implement them in Python. One data type is ideal for representing graphs in Python, i.e. dictionaries. The graph in our illustration can be implemented in the following way:
graph = { "a" : {"c"}, |
The keys of the dictionary above are the nodes of our graph. The corresponding values are sets with the nodes, which are connected by an edge. A set is better than a list or a tuple, because this way, we can have only one edge between two nodes. There is no simpler and more elegant way to represent a graph.
An edge can also be ideally implemented as a set with two elements, i.e. the end nodes. This is ideal for undirected graphs. For directed graphs we would prefer lists or tuples to implement edges.
Function to generate the list of all edges:
Output:
As we can see, there is no edge containing the node "f". "f" is an isolated node of our graph. The following Python function calculates the isolated nodes of a given graph:
Output:
2. Graphs as a Python Class
Before we go on with writing functions for graphs, we have a first go at a Python graph class implementation.
If you look at the following listing of our class, you can see in the init-method that we use a dictionary "self._graph_dict" for storing the vertices and their corresponding adjacent vertices.
Output:
Let's calculate the list of all the vertices and the list of all the edges of our graph:
Output:
We add a vertex and and edge to the graph:
Output:
Output:
3. Paths in Graphs
Adjacent vertices:
Two vertices are adjacent when they are both incident to a common edge.
Path in an undirected Graph:
A path in an undirected graph is a sequence of vertices such that is adjacent to for 1 ≤ i < n. Such a path P is called a path of length n from to .
Simple Path:
A path with no repeated vertices is called a simple path.
Example:
(a, c, e) is a simple path in our graph, as well as (a,c,e,b). (a,c,e,b,c,d) is a path but not a simple path, because the node c appears twice.
We add a method find_path to our class Graph. It tries to find a path from a start vertex to an end vertex. We also add a method find_all_paths, which finds all the paths from a start vertex to an end vertex:
We check in the following the way of working of our find_path and find_all_paths methods.
4. Degree and Degree Sequence
The degree of a vertex is defined as the number of edges connected to it. The degree sequence of a graph is a list of vertex degrees sorted in non-increasing order. This information is crucial for many graph-theoretic algorithms, including those related to network connectivity and flow.
- Graph Class: Contains methods to add vertices and edges and to compute the degrees.
- add_vertex(vertex): Adds a new vertex to the graph if it does not already exist.
- add_edge(vertex1, vertex2): Creates an undirected edge by adding both vertices to each other's adjacency list.
- degree(vertex): Calculates the degree by returning the length of the adjacency list for the specified vertex.
- degree_sequence(): Compiles the degree of all vertices, sorts them in non-increasing order, and returns the degree sequence.
Output: show the degree sequence of the constructed graph based on the vertices and edges added.