Graphs

Published

2023-08-02

Introduction to graphs

Graphs are a very versatile data structure. They can be used to represent game states, positions on a map with routes, people in a social network, and so on. Here we will consider graphs that represent positions on a map with routes and that represent friendships in a social network.

Let’s start with maps. Consider a minimal example of two towns in Michigan, Ann Arbor and Ypsilanti.

Here, in the language of graphs, we have two vertices (a.k.a., nodes) representing the towns, Ann Arbor and Ypsilanti, and an edge connecting the vertices, indicating that a route exists between them. We can travel along this route from Ann Arbor to Ypsilanti, and from Ypsilanti to Ann Arbor. Notice the symmetry. This is because the edge between Ann Arbor and Ypsilanti is undirected, which is reasonable, since the highway that connects them allows traffic in both directions.1

We refer to vertices which share a common edge as neighbors. We also refer to vertices which share a common edge as adjacent. So in the example above, Ann Arbor and Ypsilanti are neighbors. Ann Arbor is adjacent to Ypsilanti, and Ypsilanti is adjacent to Ann Arbor.

Here’s a little more elaborate example:

In this example, Burlington is adjacent to St Albans, Montpelier and Middlebury. Rutland is adjacent to Middlebury and Bennington. (Yes, we’re leaving out a lot of detail for simplicity’s sake.)

So the question arises: how do we represent a graph in our code? There are several ways, but what we’ll demonstrate here is what’s called the adjacency list representation.

We’ll use a dictionary, with town names as keys and the values will be a list of all towns adjacent to the key.

For example, Montpelier is adjacent to St Johnsbury, White River Junction and Burlington, so the dictionary entry for Montpelier would look like this:

ROUTES = {'Montpelier': ['Burlington', 'White River Junction', 
                         'St Johnsbury']}

A complete representation of adjacencies, given the map above is:

ROUTES = {
    'Burlington': ['St Albans', 'Montpelier', 'Middlebury'],
    'Montpelier': ['Burlington', 'White River Junction', 
                   'St Johnsbury'],
    'White River Junction': ['Montpelier', 'Brattleboro', 
                             'St Johnsbury'],
    'Brattleboro': ['White River Junction'],
    'Newport': ['St Johnsbury'],
    'St Albans': ['Burlington', 'Swanton'],
    'St Johnsbury': ['Montpelier', 'Newport', 
                     'White River Junction'],
    'Swanton': ['St Albans'],
    'Middlebury': ['Burlington', 'Rutland'],
    'Rutland': ['Middlebury', 'Bennington'],
    'Bennington': ['Rutland']
}

Notice that Montpelier, St Johnsbury, and White River Junction are all neighbors with each other. This is called a cycle. If a graph doesn’t have any cycles, it is called an acyclic graph. Similarly, if a graph contains at least one cycle, then it is called a cyclic graph. So, this is a cyclic graph.

Footnotes

  1. There are what are called directed edges, like one-way streets, but we’ll only deal with undirected edges in this text.↩︎