\( \newcommand{\this}{\textit{this}} \newcommand{\true}{\textit{true}} \newcommand{\Graph}{\textit{graph}} \newcommand{\Digraph}{\textit{digraph}} \newcommand{\Flograph}{\textit{flograph}} \newcommand{\ListPair}{\textit{list pair}} \newcommand{\ListSet}{\textit{list set}} \newcommand{\edges}{\textit{edges}} \newcommand{\toString}{\textit{toString}} \newcommand{\fromString}{\textit{fromString}} \newcommand{\equals}{\textit{equals}} \newcommand{\edgeRange}{\textit{edgeRange}} \newcommand{\constructor}{\textit{constructor}} \newcommand{\n}{\textit{n}} \newcommand{\m}{\textit{m}} \newcommand{\clear}{\textit{clear}} \newcommand{\validVertex}{\textit{validVertex}} \newcommand{\validEdge}{\textit{validEdge}} \newcommand{\left}{\textit{left}} \newcommand{\right}{\textit{right}} \newcommand{\head}{\textit{head}} \newcommand{\tail}{\textit{tail}} \newcommand{\first}{\textit{first}} \newcommand{\next}{\textit{next}} \newcommand{\firstAt}{\textit{firstAt}} \newcommand{\nextAt}{\textit{nextAt}} \newcommand{\mate}{\textit{mate}} \newcommand{\join}{\textit{join}} \newcommand{\delete}{\textit{delete}} \newcommand{\degree}{\textit{degree}} \newcommand{\maxDegree}{\textit{maxDegree}} \newcommand{\weight}{\textit{weight}} \newcommand{\length}{\textit{length}} \newcommand{\cost}{\textit{cost}} \newcommand{\firstInto}{\textit{firstInto}} \newcommand{\firstOutof}{\textit{firstOutof}\,} \newcommand{\nextInto}{\textit{nextInto}} \newcommand{\nextOutof}{\textit{nextOutof}\,} \newcommand{\inDegree}{\textit{inDegree}} \newcommand{\outDegree}{\textit{outDegree}} \newcommand{\source}{\textit{source}} \newcommand{\sink}{\textit{sink}} \newcommand{\res}{\textit{res}} \newcommand{\f}{\textit{f}\,} \newcommand{\flow}{\textit{flow}} \newcommand{\cap}{\textit{cap}} \newcommand{\setCapacity}{\textit{setCapacity}} \newcommand{\addFlow}{\textit{addFlow}} \newcommand{\clearFlow}{\textit{clearFlow}} \newcommand{\totalFlow}{\textit{totalFlow}} \newcommand{\totalCost}{\textit{totalCost}} \newcommand{\floor}{\textit{floor}} \newcommand{\hasFloors}{\textit{hasFloors}} \newcommand{\hasWeights}{\textit{hasWeights}} \newcommand{\hasLengths}{\textit{hasLengths}} \newcommand{\hasCosts}{\textit{hasCosts}} \newcommand{\randomGraph}{\textit{randomGraph}} \newcommand{\randomTree}{\textit{randomTree}} \newcommand{\randomConnectedGraph}{\textit{randomConnectedGraph}} \newcommand{\randomRegularGraph}{\textit{randomRegularGraph}} \newcommand{\randomBigraph}{\textit{randomBigraph}} \newcommand{\randomRegularBigraph}{\textit{randomRegularBigraph}} \newcommand{\randomDigraph}{\textit{randomDigraph}} \newcommand{\randomFlograph}{\textit{randomFlograph}} \newcommand{\randomWeights}{\textit{randomWeights}} \newcommand{\randomLengths}{\textit{randomLengths}} \newcommand{\randomCosts}{\textit{randomCosts}} \newcommand{\randomCapacities}{\textit{randomCapacities}} \newcommand{\randomFloors}{\textit{randomFloors}} \newcommand{\Random}{\textit{Random}} \newcommand{\RandomGraph}{\textit{RandomGraph}} \newcommand{\randomFraction}{\textit{randomFraction}} \newcommand{\randomInteger}{\textit{randomInteger}} \newcommand{\randomPareto}{\textit{randomPareto}} \newcommand{\randomExp}{\textit{randomExp}} \newcommand{\scale}{\textit{scale}} \newcommand{\bipartite}{\textit{bipartite}} \newcommand{\bipartition}{\textit{bipartition}} \newcommand{\setBipartition}{\textit{setBipartition}} \)

Graph Data Structures©

This section describes the data structures used to represent three different types of graphs: an undirected graph, implemented by the $\Graph$ class, a directed graph, implemented by the $\Digraph$ class, and a flow graph, implemented by the $\Flograph$ class. These form a class hierarchy, with $\Digraph$ extending $\Graph$ and $\Flograph$ extending $\Digraph$. It also includes a section describing several methods for generating random graphs.

Undirected Graphs

The implementation of the $\Graph$ class is illustrated below.


Vertices are identified by integers in a bounded range $1\ldots n$, where $n$ is number of vertices. For small examples like this, lower-case letters are used to identify vertices, in place of integer values. Edges are also identified by integer values in a bounded range. The edges array lists the pair of vertices joined by each edge, assigning them arbitrary designations of left and right. A $\ListSet$ object is used to represent the edges incident to each vertex. More precisely, it represents lists of edge endpoints, where the endpoints of edge $e$ are defined to be $2e$ and $2e+1$. For example, edge 1 has its left endpoint (2) at vertex $a$ and its right endpoint (3) at vertex $b$, so the endpoint list at $a$ includes endpoint 2, while the list at $b$ includes 3. The first_endpoint array identifies the first endpoint in the endpoint list for each vertex.

This implementation supports efficient iteration through the entire edge set, or the edges incident to each vertex. Edges can be added using the $\join$ method. It's generally most efficient to pre-dimension the $\edges$ array to allow for the maximum number of edges expected. The implementation also includes a $\ListPair$ object that keeps track of which edge numbers are in use and which are available to be allocated. This allows edges to be easily deleted as well. The implementation does supports dynamic expansion of the allocated memory space, if that becomes necessary. The $\Graph$ class supports the following methods.

Properties $n$ and $m$ refer to the number of vertices and edges in the graph. Propertes $\length$ and $\cost$ are alternate names for $\weight$. The $\Graph$ class also supports the common methods, $\toString()$, $\fromString()$ and $\equals()$.

A $\Graph$ can also be extended to define a bipartition on the vertices (a division of the vertices into two subsets, where all edges join vertices in different subsets). In such a bipartite graph, the two vertex subsets are referred to as inputs and outputs, and all edges join an input to an output. Methods are provided to iterate over the vertices in each subset.

The core of the Javascript implementation is shown below. This version is purposely abridged to give a clearer picture of the most essential features. Consult the web app for the complete source.

The $\Graph$ data structure also supports methods for working with bipartite graphs, in which the vertices can be split into two subsets, with all edges joining vertices in different subsets. The subsets are referred to as inputs and outputs and the following methods are provided.

The latter two methods are useful in situations where multiple graphs share the same bipartition. There are also methods for testing if a vertex is an input or output, and several iteration methods.

Directed Graphs

The $\Digraph$ class extends the $\Graph$ class, adding the following methods. One can still use $\firstAt(u)$ and $\nextAt(u, e)$ to iterate through all edges at $u$. The core of the Javascript implementation is shown below. This implementation places incoming edges before outgoing edges in the adjacency list of each vertex.

Flow Graphs

The $\Flograph$ class extends the $\Digraph$ class, adding an array of edge capacities and an array of edge flows. It also defines two special vertices, the source vertex and the sink vertex. Finally, it adds the following methods. Properties $\source$ and $\sink$ identify the source and sink vertices. They can also be used to set the source and sink.

The basic data structure can be extended to include edge costs, which define a cost per unit of flow. By default, edge costs are zero. The data structure can also be extended to include floors on the edge flows. These define miniminum flows for each edge. By default, the floor values are all zero. The core of the Javascript implementation is shown below.

Random Graphs

The $\RandomGraph$ module provides a collection of methods for generating simple (no self-loops or parallel edges) random graphs of all three types. It provides the following methods. The above methods define random edges for graphs. Each graph class is also equipped with methods to assign random values to its edge properties (weights, lengths, costs, capacities, floors). These are summarized below. The $\Random$ module contains several random number generators that can be used in conjunction with the $\RandomGraph$ module.

© Jonathan Turner - 2022