Graph Theory Basics. What you need to know as graph theory... | by Miguel Saldana | Towards Data Science

In programming and mathematical terms, graph theory is really nothing new, but the implementation and usage of it in code has grown in advances in Machine Learning and AI. One big reason for this is that advances in computing power to power large-scale models allow for complex models to be developed that can represent relationships between anything. One of the most famous and early implementations in tech of Graph Theory is Google’s Page Rank algorithm. The Page Rank algorithm was the initial version of Google’s searching algorithm and is rooted in graph theory and is based on an efficient way to measure how the internet web pages are connected via links and user clicks/traffic and from that which ones are the most popular. Additionally, in more recent times graph theory has been applied to knowledge graphs to help understand the interconnected relationship of variables within a system (for example, a factory and all the pieces of machinery and factors that are within it and how they affect each other). Also, graph theory has been applied to economic models to understand how the stock market behaves as well as the inner workings of blockchains are supported by graph theory. So the widespread ability to compute and create extremely complex models through graphical means is only going to continue to grow and the need to learn and understand the basics is vital to apply it to additional use cases.
In mathematics, graph theory is the study of graphs, which are mathematical structures used to model pairwise relations between objects. A graph in this contec is made up vertices (also called nodes or points) which are connected by edges (also called links or lines). — Wikipedia
A quick Wikipedia search will give you this definition of graph theory and below we will start to breakdown what it is and how it works
Vertices/Nodes — These are the objects that will usually have properties about themselves and then connections to other objects in a graph. A simple example of a property that an object could have is weight or a value, in more complex objects this could also include things like cost, descriptive properties (color, size, weight), power, probabilities, etc... it will all depend on how the graph network is built and what it is trying to accomplish
Edges/Links — The edges are essentially the relationship between objects or the road that connects them together. Objects that have edges between themselves have a relation, while those that are not connected don’t.
Directed/Undirected Graphs — The easiest way to understand the difference between a directed graph and an undirected graph is to think of the edge between an object as either a two-way road or a one-way road. A directed graph shows a relation from one object that passes whatever is in the relation to another object and that is not reciprocated back. An undirected graph is a connection between two objects but information about its relationship can flow both ways between them. It is a key point to point out that in directed graphs you can have two edges between a pair of nodes that simulate “an undirected” nature between the pairs.
Cyclical/Acyclical Graph — A cyclical graph is one that has a set of nodes that are connected in a closed-loop, acyclical do not have the closed-loop property.
The two most common themes in graphical representations for computers are adjacency matrix (sometimes referred to as incidence matrix) or adjacency lists.
Adjacency Matrix — In this method, a graph is converted into a matrix representation of a graph. The matrix will be an n x n shaped matrix where n represents the number of nodes and the values in the matrix represents the edges between the nodes as shown below. It is important to note that the matrix representation of an undirected graph will be a mirror of itself along the diagonal.
Adjacency List — This version of a graph is represented as the name implies a list. It is an unordered list that describes the neighbors of a vertex (or edge) in a graph.
Putting the graphs into these two kinds of forms allows us to computational program the graphs in a way that we can then set rules, relationships, properties, and changes to the graphs.
With these basic terms and concepts, we can explore a few examples of the basic problems that graph theory is used to solve and hopefully use them as examples of the building blocks for more complex systems.
One of the most basic things you may want to know about a graph network is the distance between paths and what is the optimal or shortest path between them. Some examples of where this might be useful are looking at an electricity grid or finding degrees of separation in a social network (a la Kevin Bacon).
In almost all learning platforms the first two algorithms introduced with graph theory will be DFS and BFS. They are both algorithms that look to traverse a graph. In essence, both DFS and BFS are trying to accomplish the same goal but go about in slightly different manners.
Starting off with BFS, the principle behind this algorithm is to investigate all neighboring nodes from a starting place before moving to the following node. A queue is used to help denote which nodes have been visited and once that path has been completed, it will go to the next unvisited node and begin traversing the graph just as it did before, marking all visited nodes. This cycle will repeat for the entire graph until all nodes have been visited. In the queue, it is then possible to determine the shortest path from the starting point to the targeted endpoint. Below is an example of the pseudocode for the BFS search algorithm.
 1  procedure BFS(G, root) is 2      let Q be a queue 3      label root as discovered 4      Q.enqueue(root) 5      while Q is not empty do 6          v := Q.dequeue() 7          if v is the goal then 8              return v 9          for all edges from v to w in G.adjacentEdges(v) do10              if w is not labeled as discovered then11                  label w as discovered12                  Q.enqueue(w)
DFS or Depth-First Search is a very similar algorithm to BFS, but it behaves slightly differently. When traversing through the graph, once a dead-end is reached in DFS, the algorithm will backtrack to a previous node that is connected to an unvisited node and continue in that path. It will then only go to a random node if it is unconnected from the original network of the graph. Both of these methods are some of the first methods taught to traverse along a graph and find the shortest path. Potential applications would be to apply it to a graph of a social network to determine potential suggestions of people with similar backgrounds, friends, or hobbies. Below is an example of a DFS Pseudocode.
1 procedure DFS_iterative(G, v) is2    let S be a stack3    S.push(v)4     while S is not empty do5        v = S.pop()6         if v is not labeled as discovered then7             label v as discovered8             for all edges from v to w in G.adjacentEdges(v) do9                 S.push(w)
There are more advanced graph-traversing methods such as the Bellman-Ford, Djikstra, and Kruskal for example. Each tries and tackles additional problems that could be encountered that the methods employed in BFS or DFS wouldn’t be able to tackle, for example, edges with negative weights/lengths, cyclical graphs, etc...
Enumeration — In other words is evaluating and counting graphs that meet specific conditions or in other words solving combinatorics problems.
Subgraphs — Looking at graphs to determine if components of a graph are subcomponents of another graph or looking at “hereditary” traits between graphs
Graph Coloring — Similar to enumeration, but applying coloring to the problem of a graph so that you will never have similar colors touching each other along coloring vertices in a graph
Unification — Evaluating graphs that are more constrained (or have more information) and how they roll up into graphs or models that less constrained (or more generalized)
Network Flow — An example of this type of problem would be like evaluating an energy grid to determine the flow of energy across a system
Visibility Problems — Trying to solve a problem similar to the museum guard problem such that you figure out the minimum number of security guards to see an entire museum gallery.
Decomposition — Looking at breaking down graphs with certain conditions.
Route Problems — The shortest path example is one such problem, another would be the traveling salesman problem or the Seven Bridges of Konigsberg problem.
As mentioned before, graph theory is slowly becoming a more efficient way to represent real-world problems. The computing power to solve extremely complex relationships and details about any system can be now be done through programmatic methods. This article is intended to really serve as a primer of graph theory and to encourage you to continue learning about different methods of evaluating and implementing graphs to solve real-world problems.
One of my personal favorite subjects that I’m currently researching heavily is blockchains and you think of a blockchain in terms of graph theory to some extent.
If you have any questions or comments about this article, please leave a comment.