>
as the comparison operator)
A graph represents relationships, specifically between pairs of objects. Graphs are probaby the desired structure for a problem decribed in terms of "network", "circuit", "web", or "relationship". For example:
In formal terms: a graph is a set of vertices and a set of edges
(vertex pairs)
G = (V, E)
. The number of vertices is denoted by
N = |V|
,
(i.e. the number of elements in the vertex set) and the number of
edges is denoted by
M = |E|
.
We've already seen diagrams of linked lists and trees. So far, each node (vertex) is a bubble, with O(1) arrows (edges) emerging from a node:
A graph may be directed or undirected. Edges in a directed graph are usually denoted with an arrowhead.
A multigraph may have multiple ("parallel") edges between any vertex pair.
A vertex in a
simple
graph (i.e. not a multigraph) can have at most
N - 1
edges. Total number of edges can be
M = O(N2)
.
A graph is connected if there is a path from any vertex to every other vertex. Determining whether a graph is connected can be done simply by starting at any vertex and performing a breadth-first or depth-first traversal. At the end of the traversal, if there are any unvisited nodes, the graph is not connected.
A complete graph has an edge between every pair of vertices.
Planar graphs can be drawn on a (planar) surface without any crossing edges.
We can associate properties with edges or vertices, such as:
Breadth-first traversal acts like a flame front.
Graphs may be represented via:
Generally, an edge list is more efficient. Finding successors in
an adjacency matrix is O(|V|)
.
A vertex is an class, e.g.
class Vertex {
public:
//...
private:
//...
std::vector<Edge> edges;
};
An edge may simply be a reference to a vertex:
or it may be a
typedef Vertex* Edge;
std::pair
:
or it may be a class:
typedef std::pair<Vertex*, Vertex*> Edge;
class Edge {
public:
//...
private:
//...
Vertex* from;
Vertex* to;
};
A graph may be k-colored if every node is marked with 1 of k values ("colors") such that for any pair of vertices v1 and v2, if there is an edge between them, then they have different colors.
TODO: example
Graph coloring is an example of class of problems considered "hard" (NP-Complete). The best solutions currently known require exponential time.
Compiler code generation uses graph-coloring to allocate registers. Each variable (including compiler-generated expression temporaries) is a node; there is an edge between two nodes if both variables are in use at the same time. An attempt is made to k-color the graph, where k is the number of registers. Since this is a hard problem, heuristic/approximate approaches must be used. If the graph is not k-colorable, "register spilling" is performed to modify the graph until it is k-colorable.
A 2-color graph is also known as a bipartite graph. Bipartite graphs are used to model situations where there are two kinds of nodes. (TODO: add diagram)
Decorating arbitrary nodes with a color attribute is not the same thing as a graph coloring.