Graphs

advertisement
Graphs
General graphs differ from trees

need not have a root node

no implicit parent-child relationship

may be several (or no) paths from one vertex to another.
Directed graphs (direction associated with links) are useful in modeling

communication networks

networks in which signals, electrical pulses, etc. flow from one node to
another along various paths.
In networks where there may be no direction associated with the links,
=> model using undirected graphs, or simply graphs.
Directed Graphs
A directed graph, or digraph, consists of:

finite set of elements called vertices or nodes

a finite set of directed arcs or edges that connect pairs of vertices.
For example, a directed graph having
five vertices numbered 1, 2, 3, 4, 5 and
six arcs joining vertices 1 to 2, 1 to 3, 1 to 5, 2 to 3, 3 to 4, 4 to 3
can be pictured as
1
2
5
3
4
Graph Functionality
Basic Graph Operations include












Construct graph
Check if it is empty
Destroy a directed graph
Insert a new node
Insert directed edge between two nodes or from a node to itself
Delete a node and all directed edges to or from it
Delete a directed edge between two existing nodes
Search for a value in a node, starting from a given node
Traversal
Determining if node x is reachable from node y
Determining the number of paths from node x to node y
Determining the shortest path from node x to node y
Graph Representation
Adjacency matrix representation
for directed graph with vertices numbered 1, 2, . . . , n
is the n X n matrix adj,
in which the entry in row i and column j is
1 (or true) if vertex j is adjacent to vertex i
(that is, if there is a directed arc from vertex i to vertex j ),
and is 0 (or false) otherwise.
For example, the adjacency matrix for the previous example is
0
0
0
0
0
1
0
0
0
0
1
1
0
1
0
0
0
1
0
0
1
0
0
0
0
Graph Representation
For a weighted digraph
there is some “cost” or “weight” is associated with each arc
(e.g., in a digraph modeling a communication network),
the cost of the arc from vertex i to vertex j is used instead of 1 in the
adjacency matrix.
Clearly, some non-existent cost (such as 0, or –1) must then be used to
indicate when an edge does not exist.
A complete graph is a graph in which there is an edge between each pair of
vertices.
A digraph of n nodes has n*(n-1) arcs (edges).
Adjacency Matrix
The sum of 1’s (or trues) in row i of the adjacency matrix is yields the
out-degree of the ith vertex, i.e how many outgoing arcs emanate from i
Similarly, the sum of the entries in the ith column is its in-degree.
The matrix representation of a digraph is also useful for path counting.
For example, a path of length 2 from vertex i to vertex j in a digraph G
exists if there is some vertex k such that there is an arc from vertex i to
vertex k and an arc from vertex k to vertex j.
Hence both the i, k entry and the k, j entry of the adjacency matrix of G
must be 1.
Adjacency Matrix
The i, j entry of adj 2 is the sum of the products of the entries in the ith row
with those in the jth column.
Each vertex k that has an incoming arc from i and an outgoing arc to j
contributes 1 to the sum.
Thus, the i, j entry of adj 2 will be the number of paths of length 2 from
vertex i to vertex j.
In general, the i, j entry of the kth power of adj, adj k , indicates the number
of paths of length k from vertex i to vertex j.
Adjacency-List Representation
If a graph does not have many links, the adjacency matrix will be sparse
 such representation is a waste of space
 use an array of pointers to linked row-lists
 adjacency-list representation for digraphs.
The directed graph is represented by an array or vector v[1], v[2], . . . , v[n],
one element for each vertex in the digraph.
Each v[i] stores the data stored in vertex i together with a linked list of the
numbers of all vertices adjacent to vertex i.
Adjacency List
template <typename DataType>
class Digraph
{
public:
// Operations
. . .
private:
// Data Members
class VertexInfo
{
public:
DataType
data;
list<int>
adjacencyList;
};
vector<VertexInfo> v;
};
Searching a graph
In a tree, searches start from the root.
In general directed graph, there may not be a vertex from which every
other vertex can be reached
 may not be possible to traverse entire digraph,
regardless of the start vertex.
 determine which nodes are reachable from a given node.
Two standard methods of searching are
depth-first search
breadth-first search.
Depth-First Search
Start from a given vertex v.
Visit the first neighbor, w, of v.
Then visit the first neighbor of w that has not already been visited, etc.
The search continues until all nodes of the graph have been examined.
If a dead-end is reached, i.e. a node with no unexamined neighbors, then
backup to the last visited node and examine its remaining neighbors.
Starting from 1, DFS would visit 2, 3, 4 (dead-end). Backing all the way
up to 1, 5 would finally be visited.
1
2
5
3
4
Depth-First Search
DFS uses backtracking.
Backtracking used when necessary to return to some values that were
already processed or that were skipped over on an earlier pass
Usual implementation is to store the items in a stack as encountered.
When necessary to return to an earlier item, pop item from stack.
Recursion is also a natural technique for such problems,
a stack is automatically maintained to make backtracking possible.
DFS of a tree would be equivalent to a preorder traversal.
Depth-First Search
/* Algorithm to perform a depth-first search of a digraph
visit all vertices reachable from a given start vertex v.
Receive: A digraph and a vertex v
Return/Output: Depends on processing done when vertex is visited
-------------------------------------------------------------------------------------* /
1. Visit the start vertex v.
2. For each vertex w adjacent to v do:
If w has not been visited,
apply the depth-first search algorithm
with w as the start vertex.
/* Clearly a recursive algorithm */
Breadth-First Search
Start from a given vertex v.
Visit all neighbors of v.
Then visit all neighbors of first neighbor w of v.
Then visit all neighbors of second neighbor x of v, etc.
BFS visits nodes level by level.
From vertex 1, BFS would visit 2, 3, and 5, then finding no unexamined
neighbors of neighbor 2, it would visit 4 as a neighbor of 3.
1
2
5
3
4
Breadth-First Search
While visiting each node on a given level,
 store it
 so that, we can return to it after completing this level
 so that nodes adjacent to it can be visited.
Because the first node visited on a given level should be the first one to
which we return, a queue is an appropriate data structure for storing the
nodes.
Breadth-First Search
/* Algorithm to perform a breadth-first search of a digraph
visit all vertices reachable from a given start vertex v.
Receive: A digraph and a vertex v
Return/Output: Depends processing done when vertex is visited
-------------------------------------------------------------------------------------* /
1. Visit the start vertex.
2. Initialize a queue to contain only the start vertex.
3. While the queue is not empty do:
a. Remove a vertex v from the queue.
b. For all vertices w adjacent to v do:
If w has not been visited then:
i. Visit w.
ii. Add w to the queue.
Graph Traversal
/* Algorithm to traverse digraph, visiting each vertex exactly once.
BFS or DFS forms basis of the traversal.
Vertices need to be marked as visited
*/
1. Initialize an array or vector unvisited
unvisited[i] false for each vertex i.
2. While some element of unvisited is false, do:
a. Select an unvisited vertex v.
b. Use BFS or DFS to visit all vertices reachable from v.
Paths
routing problems: find an optimal path in a network—
a shortest path in a graph or a digraph,
a cheapest path in a weighted graph or digraph,
Consider a directed graph that models an airline network
vertices represent cities
directed arcs represent flights connecting these cities.
Find the most direct route between two cities, that is, the route with the
fewest intermediate stops.
Equivalent to finding the length of a shortest path, one composed of a
minimum number of arcs, from a start vertex to a destination vertex.
An algorithm for determining such a shortest path is an
easy modification of the breadth-first search algorithm.
Shortest Path
1. Visit start and label it with 0.
2. Initialize distance to 0.
3. Initialize a queue to contain only start.
4. While destination not visited and the queue not empty, do:
a. Remove a vertex v from the queue.
b. If the label of v > distance, increment distance by 1.
c. For each vertex w adjacent to v:
If w has not been visited, then
i. Visit w and label it with distance + 1.
ii. Add w to the queue.
5.
If destination has not been visited then
Display “Destination not reachable from start vertex.”
Else find vertices p[0], . . . , p[distance] on the shortest path as follows:
a. Initialize p[distance] to destination.
b. For each value of k ranging from distance - 1 down to 0:
Find a vertex p[k] adjacent to p[k + 1] with label k.
Undirected graphs
A graph, sometimes called an undirected graph, is like a digraph except
that no direction is associated with the edges.
Also, no loops joining a vertex to itself are allowed.
Such graphs are useful in modeling
 electrical circuits,
 structures of chemical compounds,
 communication systems
 other networks in which no direction associated with the links.
As ADTs, graphs and digraphs have basically the same operations.
Likewise, BFS and DFS apply equally well to undirected graphs.
Representation
Like digraphs, graphs can be represented by either adjacency matrices or
adjacency lists.
The adjacency matrix for an undirected graph is always symmetric because
for the undirected edge between node i and node j, there is an entry in the
(i,j) position of the matrix as well as in the (j,i) position.
Hence the entries on one side of the diagonal (from the upper-left corner
to the lower-right corner) are redundant.
Also, since undirected graphs have no loops, all entries on the diagonal of
the adjacency matrix are 0.
adjacency matrix is not an efficient representation of an undirected
graph
Edge Lists
Adjacency lists suffer from the same redundancy because the undirected
edge is represented twice.
A more efficient representation of a graph uses edge lists.
Edge lists consist of a linkage of edge nodes (one for each edge) to the two
vertices that serve as its endpoints.
This representation consists of an array or vector v of classes (or structs),
one for each vertex, with each class instance containing a data member and
a pointer to an edge node having that vertex as one of its endpoints.
Graph Algorithms
Depth-first search, breadth-first search, traversal, and other algorithms for
processing graphs are similar to those for digraphs.
DFS may be used to determine whether a graph is connected, that is,
whether there is a path from each vertex to every other vertex.
The member function Read() of class template Graph builds the edgelist representation of the graph from user input, and the member function
Connected() calls DepthFirstSearch() to do a depth-first search,
marking those vertices that are reachable from vertex 1.
Download