Introduction to Graphs
In this chapter we will study graphs. Graphs are a more general structure than the trees we studied in the last chapter; in fact you can think of a tree as a special kind of graph. Graphs can be used to represent many interesting things about our world, including systems of roads, airline flights from city to city, how the Internet is connected, or even the sequence of classes you must take to complete a major in computer science. We will see in this chapter that once we have a good representation for a problem, we can use some standard graph algorithms to solve what otherwise might seem to be a very difficult problem.
Below we introduce some definitions that will allow us to talk precisely about graphs throughout the chapter.
Vertex
A vertex (also called a “node”) is a fundamental part of a graph. It can have a name, which we will call the “key.” A vertex may also have additional information, which we will call the “payload.”
Edge
An edge is another fundamental part of a graph. An edge connects two vertices to show that there is a relationship between them. Edges may be one-way or two-way. If the edges in a graph are all one-way, we say that the graph is a directed graph, or a digraph.
Weight
Edges may be weighted to show that there is a cost to go from one vertex to another. For example in a graph of roads that connect one city to another, the weight on the edge might represent the distance between the two cities.
With those definitions in hand we can formally define a graph. A graph can be represented by where . For the graph , is a set of vertices and is a set of edges. Each edge is a tuple where . We can add a third component to the edge tuple to represent a weight. A subgraph is a set of edges and vertices such that and .
The diagram below shows another example of a simple weighted digraph. Formally we can represent this graph as the set of six vertices:
The example above helps illustrate two other key graph terms:
Path
A path in a graph is a sequence of vertices that are connected by edges. Formally we would define a path as such that for all . The unweighted path length is the number of edges in the path, specifically . The weighted path length is the sum of the weights of all the edges in the path. For example in the above graph the path from to is the sequence of vertices . The edges are .
Cycle
A cycle in a directed graph is a path that starts and ends at the same vertex. For example, in the above graph the path is a cycle. A graph with no cycles is called an acyclic graph. A directed graph with no cycles is called a directed acyclic graph or a DAG. We will see that we can solve several important problems if the problem can be represented as a DAG.
The Graph Abstract Data Type
The graph abstract data type (ADT) is defined as follows:
Graph()
creates a new, empty graph.add_vertex(vertex)
adds an instance ofVertex
to the graph.add_edge(from_vertex, to_vertex)
Adds a new, directed edge to the graph that connects two vertices.add_edge(from_vertex, to_vertex, weight)
Adds a new, weighted, directed edge to the graph that connects two vertices.get_vertex(key)
finds the vertex in the graph namedkey
.get_vertices()
returns the list of all vertices in the graph.in
returnsTrue
for a statement of the formvertex in graph
, if the given vertex is in the graph,False
otherwise.
Beginning with the formal definition for a graph there are several ways we can implement the graph ADT in Python. We will see that there are trade-offs in using different representations to implement the ADT described above. There are two well-known implementations of a graph, the adjacency matrix and the adjacency list. We will explain both of these options, and then implement one as a Python class.