Chapter6
GRAPHS
6.1 The graph abstract data type
1. introduction
Koenigsberg bridge problem
starting at some land area, is it possible to return to our staring
location after walking across each of the bridge exactly once ?
C
g
d
c
C
g
A
c
e
D
d
e
A
a
a
B
b
f
b
D
f
B
start B ----> (a)---> A ---> (e )---> D ---> (g) --->
C ---> (d) ---> A ---> (b) ---> B ---> (f ) ---> D [no
solution]
Eulerian walk
There is a walk starting at any vertex, going through each
edge exactly once, and terminating at the starting vertex iff the
degree of each vertex is even.
graph applications:
analysis of electrical circuits,
finding shortest routes,
project planning,
identification of chemical compounds.
GRAPH (G) --- consists of two sets, a finite, nonempty set of
vertices ( V(G) ), and a finite, possibly empty set of edges
( E(G) ), G= ( V, E ).
undirected graph ---- the pair of vertices representing any
edges is undirected. (v0, v1) = (v1, v0)
directed graph ----- the pair of vertices representing any
edges is directed. < v0, v1 > ( v0 -- tail, v1 - head )
0
1
2
1
3
1
2
4
3
5
6
2
G3
G2
G1
V(G1) = {0, 1, 2, 3}
V(G2) = {0, 1, 2, 3, 4, 5, 6}
V(G3) = {0, 1, 2}
G2 is a tree
0
0
---- >
E(G1) = { (0,1), (0,2), (0,3), (1,2),
(1,3), (2,3) }
E(G2) = { (0,1), (0,2), (1,3), (1,4),
(2,5), (2,6) }
E(G3) = { < 0, 1 >, < 1, 0 >,<1,2> }
trees is a special case of graphs
The restrictions on graph:
1. A graph may not have an edge from a vertex , i, back to
itself (self loops)
2. A graph may not have multiple occurrences of the same
edge ( multigraph )
0
2
0
1
1
complete graph
3
2
----- is a graph that has the maximum
number
of edges
undirected graph (n vertices)
----n (n-1) / 2
directed graph (n vertices)
----n (n-1)
(v0, v1)
---> vertices v0 and v1 are adjacent
---> edge (v0, v1) is incident on v0 and v1
<v0, v1>
---> vertex v0 is adjacent to vertex v1
vertex v1 is adjacent from vertex v0
---> edge <v0, v1> is incident on v0 and v1
subgraph of G (G') ----- V(G') V(G) and E(G') E(G)
125
0
0
1
1
2
0
2
1
3
2
3
(a) some of subgraphs of G1
0
0
3
0
2
1
1
6
2
(b) some of subgraphs of G3
path from vp to vq ----- a sequence of vertices vp , vi1 , vi2 , … ,
vin , vq such that ( vp , vi1 ), ( vi1 , vi2 ),…,
( vin , vq ) are edges in an undirected graph.
in directed graph, the path consists of
< vp , vi1 >, < vi1 , vi2 >,…, < vin , vq >
length of a path ---- the number of edges on the graph
simple path ----- a path in which all vertices, except possibly
the first and the last are distinct.
simple directed path
cycle ---- a simple path in which the first and the last vertices
are the same.
directed cycle
v0 and v1 are connected ----- there is a path from v0 to v1
an undirected graph are connected -----if , for every pair of distinct vertices vi , vj ,
there is a path from vi to vj in G.
H1
H2
0
2
1
4
5
6
3
7
G4
connected component of an undirected graph -----
a maximal connected subgraph. ( a tree is
graph
126
that is connected and acycle)
strongly connected ( directed graph ) -----a
if , for every pair of vertices vi , vj in G, there is
path from vi to vj, and also from vj to vi.
strongly connected component ----a maximal subgraph that is strongly connected.
0
2
1
degree of vi ---- the number of edges incident to that vertex.
in-degree ---- the number of edges that have v as the head.
out-degree ----- the number of edges that have v as the tail.
the number of edges :
Abstract data type
n1
e (di ) / 2
0
structure Graph is
object: a nonempty set of vertices and a set of undirected
edges, where each edge is a pair of vertices.
function: for all graph Graph, v, v1, and v2
Vertices
Graph Create()
::= return an empty graph.
Graph InsertVertex( graph,v ) ::= return a graph with
v inserted. v has no incident
edges.
Graph Insertedge( graph, v1 , v2 )::= return a graph
with a new edge between v1
and v2 .
Graph DeleteVertex( graph,v ) ::= return a graph in
which v and all edges incident
to it are removed.
Graph DeleteEdge(graph, v1 , v2)::= return a graph
in which the edge (v1 , v2) is
removed. Leave the incident
nodes in the graph.
Boolean IsEmpty( graph ) ::= if ( graph == empty
graph) return TRUE else return
FALSE.
127
List Adjacent( graph, v )
2. representations
::= return a list of all
vertices hat are adjacent to v.
⑴ adjacency matrix
0
1
2
3
0
0
1
1
1
1
1
0
1
1
2
1
1
0
1
3
1
1
1
0
0
1
2
0
0
1
0
1
1
0
0
0
1
2
3
4
5
6
7
2
0
1
0
G3
G1
0
0
1
1
0
0
0
0
0
1
1
0
0
1
0
0
0
0
2
1
0
0
1
0
0
0
0
3
0
1
1
0
0
0
0
0
4
0
0
0
0
0
1
0
0
5
0
0
0
0
1
0
1
0
6
0
0
0
0
0
1
0
1
7
0
0
0
0
0
0
1
0
G4
n1
adj _ mat [ i ][ j ]
the degree of any vertex, i :
j 0
How many edges are there
in G or, Is G connected ?
( n2 )
sparse graphs --graphs that have a small number of edges
( e n ) e n2 / 2
⑵ Adjacency list
headnodes
vertex link
0
1
2
3
null
0
1
2
null
1
0
2
3
null
1
0
3
null
2
0
1
3
null
2
0
3
null
3
0
1
2
null
3
1
2
null
4
5
5
4
6
null
6
5
7
null
7
6
G1
0
1
1
0
2
null
2
null
G3
null
null
null
G4
128
#define MAX_VETICES 50 /* maximum number of vertices */
typedef struct node *node_pointer;
typedef struct node { int vertex;
struct node *link;
};
node_pointer graph[MAX_VERTICES];
int n= 0 ; /* vertices currently in use */
In undirected graph (n vertices, e edges):
n head nodes, 2e list nodes
node [ i ] --- the starting point of the list for vertex i, 0 <= i < n
and node [ n ] is set to n + 2e + 1
The vertices adjacent from vertex i are stored in node[i],…,
node[i+1] -1, 0 <= i < n.
the
[0]
[1]
[2]
[3]
[4]
sequential representation for G4:
9
[5]
[20]
11
[6] 20
[21] 7
13
[7] 22
[22] 6
15
[8] 23
17
[9]
1
18
[10]
2
[15]
5
[11]
0
[16]
2
[12]
3
[17]
5
[13]
[14]
0
3
[18]
[19]
4
6
1
the degree of any vertex ---- the number of nodes in the its
adjacency list
the total number of edges in G ---- ( n e )
In undurected graph (n vertices, e edges):
out - degree ---the number of nodes in its adjacency list
in - degree ?
inverse adjacency lists
129
0
1
null
1
0
null
2
1
null
inverse adjacency list for g3
Alternate node structure for adjacency list :
tail head column link for haed row link for tail
headnodes
(shown twice)
0
1
0
0 1
1
2
1 0
2
null
1 2
null
null
G3
null
note: we arranged the nodes in each of the lists so that the
vertices were in ascending order, it is not necessary in fact.
headnodes
vertex link
0
3
1
2
null
1
2
0
3
null
2
3
0
1
null
3
2
1
0
null
G1
⑶ Adjacency multilists
marked
vertex1
vertex2
path2
path1
typedef struct edge *edge_pointer;
typedef struct edge {
short int marked;
int vertex1;
int vertex2;
edge_pointer path1;
edge_pointer path2;
130
};
edge_pointer graph [MAX_VERTICES];
headnode
0
M1
0
1
M2
M4
edge(0,1)
M2
0
2
M3
M4
edge(0,2)
M3
0 3
null
M5
edge(0,3)
M4
1
2
M5
M6
edge(1,2)
M5
1
3
null
M6
edge(1,3)
M6
2
3
null
null
edge(0,1)
1
2
3
The lists are: vertex 0: M1-> M2 -> M3
vertex 1: M1-> M4 -> M5
vertex 2: M2-> M4 -> M6
vertex 3: M3-> M5 -> M6
⑷ Weighted edges
( network )
weight --- the distance from one vertex to another or the cost
of going from one vertex to an adjacent vertex
6.2 Elementary graph operations
⑴ depth first search
#define FALSE 0
#define TRUE 1
short int visited [MAX_VERTICES];
void dfs(int v)
{
/* depth first search of a graph beginning with vertex v */
node_pointer w;
visited[v] = TRUE;
printf ("%5d",v);
for (w = graph[v]; w; w = w->link)
131
if ( !visited [ w->vertex ])
dfs( w->vertex );
}
〖example〗
1
2
1
0
3
4
null
2
0
5
6
null
3
1
7
null
4
1
7
null
5
2
7
null
6
2
7
null
7
3
4
0
null
v0
v2
v1
v3
v5
v4
v6
v7
5
6
null
complexity
for adjacency list , O (e)
for adjacency matrix , O
2
(n )
⑵ Breadth first search
typedef struct queue *queue_pointer;
typedef struct queue { int vertex; queue_pointer; };
void addq (queue_pointer *, queue_pointer *, int);
int deleteq ( queue_pointer *);
void bfs(int v)
{/* breadth first traversal of a graph,starting with node v
the global array visited is initialized to 0, the queue
operations are similar to those described in chapter 4. */
node_pointer w;
queue_pointer front,rear;
front = rear = NULL;
/* initialize queue */
printf ("%5d", v);
visited[v] = TRUE;
addq (&front,&rear,v);
while (front) { v = deleteq (&front);
for (w = graph[v]; w; w = w->link)
if ( !visited [w->vertex])
{
printf ("%5d",w->vertex);
addq (&front, &rear, w->vertex);
visited [w->vertex]=TRUE;
132
}
}
}
complexity
for adjacency list ,
O (e)
2
for adjacency matrix , O ( n )
⑶ Connected components
void connected(void)
{
/* determine the connected components of a graph */
int i;
for ( i=0; i < n; i++)
if ( !visited [ i ] ) {
dfs ( i );
printf ( "\n" );
}
}
complexity
for adjacency list ,
O(n+e)
2
for adjacency matrix , O ( n )
⑷ Spanning trees
spanning tree is any tree that consists solely of edge in G
and that includes all the vertices in G.
depth first spanning tree (a)
breadth first spanning tree (b)
133
v0
v0
v3
v5
v4
v2
v0
v2
v0
v6
v3
v5
v4
0
0
v7
(a) dfs(0) spanning tree
v6
v7
(b) bfs(0) spanning tree
property1 :
If a nontree edge, (v,w) is added into any spanning tree, T, the
result is a cycle that consists of the edge (v,w) and all the
edge on the path from w to v in T.
[ use: obtain an independent set of circuit equation for an
electrical network ]
property2 :
A spanning tree is a minimal subgraph, G', of G such that
V(G') = V(G) is connect.
minimal subgraph -- subgraph with the fewest number of
edges.
any connected graph with n vertices must have at least n-1
edges, and all connected graphs with n-1 edges are trees.
therefore a spanning tree has n-1 edges.
[use: design of communication networks , some time we
assign weights to the edges for representing the cost of
constructing the communication link or the length of
the
link]
⑸ Biconnected components and articulation points
134
articulation points --- a vertex v of G such that the deletion of
v, together with all edges incident on v, produces a graph, G',
that has at lest two connected components.
Biconnected
graph ---
a connected graph that has no
articulation points.
Biconnected components of a connected undirected graph
is a maximal biconnected subgraph, H, of G.
□maximal means that G contains no other subgraph that
is both biconnected and properly contains H.
□two biconnected components of the same graph have no
more than one vertex in common.
8
0
1
7
3
2
9
0
8
1
7
1
7
5
3
2
4
3
6
4
(a) connected graph
5
9
7
5
6
(b) biconnected components
the depth first number, or dfn, of the vertex:
the sequence in which the vertices are visited during the depth
first search
□ if u and v are both vertices, and u is an ancestor of v in the
depth first spanning tree, then dfn(u) < dfn (v)
135
0
4
9
0
3 1
2
7
0
9
7
5
4
5
2
6
6
3 1
7
7
2
5
4
3
1
8
5
3
2
8
6
1
9
6
4
8
0
9
8
(b)
(a) connected graph
□ a nontree edge ( u, v ) is a back edge
iff either u is an ancestor of v or v is an ancestor of u.
* all nontree edges are back edges.
□ the root of a depth spanning tree is an articulation point
iff it has at least two children.
□ any other vertex u is an articulation point
iff it has at least one child w such that we cannot reach
an
ancestor of u using a path that consists of only w,
descendants of w, and a single back edge.
definition: low
for each vertex of G such that low(u) is the lowest depth first
number that we can reach from u using a path of
descendants followed by at most one back edge:
low(u) = min { dfn(u), min { low(u) | w is a child of u }
min { dfn(w) | (u,w)
is a back edge}}
□u is an articulation point
iff u is either the root of the spanning tree and has two or
more children, or u is not the root and u has a child w such
that low(w) >= dfn(u).
vertex 0
dfn
4
1
3
2
2
3
0
4
1
5
5
6
6
7
7
8
9
9
8
136
low
4
3
0
0
0
5
5
7
9
8
void dfnlow(int u,int v)
{
/* compute dfn and low while performing a dfs search
beginning at vertex u,v is the parent of u (if any) */
node_pointer ptr;
int w;
dfn[u] = low[u] = num++;
for (ptr =graph[u]; ptr; ptr= ptr->link ) {
w = ptr->vertex;
if (dfn [w] < 0) {
/* w is an unvisited vertex */
dfnlow (w,u);
low[u] = MIN2 ( low[u], low[w] );
}
else if ( w != v)
low [u] = MIN2 ( low[u], low[w]);
}
}
void init (void)
{
int i;
for ( i = 0; i < n; i++ ){
visited [ i] = FALSE;
dfn[ i ] = low[ i ] = -1;
}
num = 0;
}
global declarations:
#define MIN2 (x, y) ((x ) < ( y ) ? (x) : (y))
short int dfn [MAX_VERTICES ];
short int low [MAX_VERTICES ];
int num;
137
void bicon( int u, int v)
O(n + e )
{
/* compute dfn and low,and output the edges of G by their
biconnected component, v is the parent (if any) of the u
{if any) in the resulting spanning tree.It is assumed that
all entries of dfn[] have been initialized to -1,num has
been initialized to 0,and the stack has been set to empty
*/
node_pointer ptr;
int w,x,y;
dfn[u] = low[u] = num++;
for (ptr = graph[u]; ptr; ptr = ptr->link){
w = ptr->vertex;
if(v!= w && dfn[w] < dfn[u])
add (&top, u, w);
/* add edge to
stack */
if ( dfn [ w ] m< 0) {
/* w has not been
visited * /
bicon(w,u);
low[u] = MIN2(low[u],low[w]);
if (low[w] >= dfn[u]{
printf ("New biconnected component:");
do { /* delete edge from stack */
delete (&top, &x, &y);
printf (" <&d,&d>",x,y);
} while ( !((x == u) && ( y == w)));
printf ("\n");
}
}
else if (w != v) low[u] = MIN2(low[u], low[w]);
}
}
6.3 Minimum cost spanning trees
cost of a spanning tree of a weighted undirected graph is the
sum of the costs (weights) of the edges in the spanning tree.
a minimum cost spanning tree is a spanning tree of least cost.
138
greedy method ( design strategy ):
Kruskal's
Prim's
sollin
algorithms
solution must satisfy the following constraints :
(1) we must use only edges within the graph
(2) we must use exactly n - 1 edges
(3) we may not use edges that would produce a cycle
Kruskal's algorithms
method --- adding edges to T one at a time.
1. select the edges for inclusion in T in nondecreasing order
of their cost.
2. an edge is added to T if it does not form a cycle with
the
edges that are already in T.
( since G is connected and has n > 0 vertices, exactly n
-1
edges be selected for inclusion in T )
Kruskal's algorithm
T={ };
while (T contains less than n-1 edges && E is not empty ){
choose a least cost edge (v,w) from E;
delete (v,w) from E;
if ((v,w) does not create a cycle in T)
add (v,w) into T;
else
discard (v,w);
}
if (T contains fewer than n-1 edges)
printf ("No spanning tree\n");
〖example〗
139
0
10
5
24
25
14
1
6
18
5
12
6
5
1
5
6
3
(c)
0
(b)
0
10
1
6
14
2
12
4
5
10
1
6
14
5
2
12
3
(f)
(e)
0
0
10
14
5
16
2
4
3
3
1
6
12
4
(d)
2
4
3
(a)
0
10
2
4
3
22
10
1
16
2
4
0
0
28
1
6
10
14
16
5
2
1
6
16
2
25
22
3
22
3
(h)
(g)
Edge
---(0,5)
(2,3)
(1,6)
(1,2)
(3,6)
(3,4)
(4,6)
(4,5)
(0,1)
12
4
12
4
weight
---10
12
14
16
18
22
24
25
28
result
initial
added to tree
added
added
added
discarded
added
discarded
added
no considered
figure
fig.(b)
fig.(c)
fig.(d)
fig.(e)
fig.(f )
fig.(g)
fig.(h)
140
〖theorem 6.1〗let G be an undirected connected graph.
Kruskal's algorithm generates a minimum cost spanning tree.
proof :
(a) Kruskal's method produces a spanning tree whenever
a
spanning tree exist
(b) the spanning tree generated is of minimum cost
Prim's algorithm
T={ };
TV = { 0 };
/* start with vertex 0 and no edges */
while (T contains fewer than n-1 edges) {
let (u,v) be a least cost edge such that u TV and
v TV;
if (there is no such edges)
break;
add v into T;
add (u, v) into T;
}
if (T contains fewer than n-1 edges)
printf("No spanning tree\n");
141
0
10
10
1
5
0
0
6
2
10
1
5
6
5
2
3
3
(a)
(b)
0
0
10
1
6
5
2
12
4
(c)
0
1
6
10
14
16
5
2
6
16
2
12
4
12
22
22
3
3
(f)
(e)
(d)
1
25
4
3
22
3
22
25
25
2
4
4
5
6
25
25
4
10
1
Sollin's algorithm
1. initialize the set of selected edges as empty set.
2. select edges (minimum cost) for each of the vertices.
(eliminating the duplicate edges)
3. add these edges to the set of selected edges, producing
the forest.
4. when there is only one tree at the end of a stage or no
edges remain for selection.
0
10
14
5
0
10
1
6
14
2
12
4
22
(a)
3
5
1
6
16
2
25
12
4
22
3
(b)
142
6.4 Shortest path and transitive closure
※ Is there a path from A to B ?
※ If there is more than one path from A to B,
which path is the shortest ?
⑴ Single source all destinations
problem : given a directed graph, G = (V, E), a weighting
function, w(e), w(e) > 0, for the edges of G, and a source vertex
v0, determine shortest path from v0 to each of the remaining
vertices of G.
greedy method:
1.Let S denote the set of vertices, including v0, whose
shortest paths have been found
2. For w in not in S, let distance[w] be the length of the
shortest path starting from v0, going through vertices
only
in S, and ending in w.
□If the next shortest path is to vertex u, then the path from v0
to u goes through only those vertices that are in S.
□Vertex u is chosen so that it has the minimum distance,
distance[u], among all the vertices not in S.
□ Once we have selected u and generated the shortest path
from v0 to u, u becomes a member of S. (w is not currently
in S) the shortest path = distance [ u ] + length (<u, w> )
45
50
v0
10
20
v2
15
15
v1
20
v3
10
35
3
v4
30
v5
path
1) v0
2) v0
3) v0
4) v0
lenght
v2
10
v2 v3
25
v2 v3 v1 45
v4
45
143
#define MAX_VERTICES 6
/* maximum number of vertices */
int cost[ ][MAX_VERTICES} =
{{ 0, 50, 10,1000, 45,1000},
{1000, 0, 15,1000, 10,1000},
{ 20,1000, 0, 15,1000,1000},
{1000, 20,1000,
0, 35,1000},
{1000,1000, 30,1000, 0,1000},
{1000,1000,1000,
3,1000, 0}};
int distance[MAX_VERTICES];
short int found[MAX_VERTICES];
int n = MAX_VERTICES;
program
Single source shortest paths
( n2 )
void shortestpath (int v,int cost[ ][MAX_VERTICES],
int distance[ ],int n,short int found[ ])
{
/* distance[i] represents the shortest path from vertex v
to i,found[i] holds a 0 if the shortest path from vertex i
has not been found and a 1 if it has ,cost is the
adjacency matrix */
int i,u,w;
for (i = 0; i < n; i++){
found[ i ] = FALSE;
distance [ i] = cost [v] [ i ];
}
found [v]= TRUE;
distance[v] = 0;
for (i=0; i<n-2; i++){
u=choose(distance,n,found);
found[ u ] = TRUE;
for (w=0; w<n; w++)
if ( !found[w])
if (distance[u] +cost[u][w] <distance[w])
distance[w] = distance[u]+cost[u][w];
}
}
Choosing the least cost edge :
int choose(int distance[ ], int n, short int found[ ])
{
144
/* find the smallest distance not yet checked */
int i,min,minpos;
min = INT_MAX;
minpos = -1;
for (i=0; i<n; i++)
if (distance[i] < min && !found [i]){
min =distance[i];
minpos = i;
}
return minpos;
}
〖example〗
1500
4 Boston
Chicago
San
francisco
800
1
300
1200
Denver
1000
2
1400
900
1700
7
Los Angeles
1000
6
Miami
3
4
5
0
1500
1000
0
250
0
New Orleans
0
1
2
0 0
1 300 0
2 1000 800
3
4
5
6
7 1700
itera
tion
initial --
s
0
1200
vertex
sele.
---
5
Mew york
1000
0
250
3
LA
[0]
SF
[1] DEN CHI
[2]
[3]
1500
6
7
900
0
1400
1000
0
BOST
[4]
NY MIA
[5]
0
250
NO
[7]
[6]
145
{4}
5
1250
0
250
1150
1650
{4,5}
6
1250
0
250
1150
1650
{4,5,6}
3
2450
1250
0
250
1150
1650
{4,5,6,3}
7
3350
2450
1250
0
250
1150
1650
{4,5,6,3,7}
2
3350
3250
2450
1250
0
250
1150
1650
{4,5,6,3,7,2}
1
3350
3250
2450
1250
0
250
1150
1650
3350
3250
2450
1250
0
250
1150
1650
1
2
3
4
5
6
{4,5,6,3,7,2,1}
⑵ All pairs shortest paths
Using the above shortestpath algorithm , find the shortest
path between all pairs of vertices , Vi , V j , i j .
complexity =
G
n * ( n2 ) ( n3 )
~ cost adjacency matrix
k
A [ i ][ j ] ~ the cost of the shortest path from i to j, using only
these intermediate vertices with an index k .
An1[ i ][ j ] ~ the cost of the shortest path from i to j
A1[ i ][ j ] = cost [i ] [j ]
k1
Ak [ i ][ j ]
Rules for A [ i ][ j ] ----->
(1) the shortest path from i to j going through no vertices with
index greater than k does not go through the vertex with
k1
index k and so its cost is A [ i ][ j ].
(2) the shortest such path does go through vertex k,
path i to j = path i to k + path k to j ( indices <= k-1)
Ak [ i ][ j ] min{ Ak 1[ i ][ j ], Ak 1[ i ][ k ] Ak 1[ k ][ j ]}, k 0
A1[ i ][ j ] = cost [i ] [j ]
146
〖example〗
0 1
2 0
-2
0
A1
A1
[0][2]
[0][2]
=
1
1
A1
min{
2
1
[0][2],
A0
1 A
1
A0 [1][2] } = 2
…, 0, 1, 2 )
[0][1] +
( path 0,1,0,1, 0,1,
( n3 )
All pairs,shortest paths function
int distance [ MAX_VERTICES ][ MAX_VERTICES ]
void allcosts(int cost[ ][MAX_VERTICES],
int distance[ ][MAX_VERTICES],int n)
{
/* determine the distances from each vertex to every other
vertex,cost is the adjacency matrix,distance is the matrix of
distances */
int i, j, k;
for (i = 0; i <n; i++)
for (j = 0; j < n; j++)
distance[i][j] = cost[i][j];
for (k = 0; k<n; k++)
for (i =0; i<n; i++)
for (j = 0; j<n; j++)
if (distance[i][k] + distance[k][j] < distance[i][j])
distance[i][j] = distance[i][k] +
distance[k][j];
}
〖example〗
V0
V1
V2
G
0
1
2
0
0
6
3
1
4
0
2
11
2
0
cost adjacence matrix gor G
147
-1
A
0
1
2
0
0
6
3
1
4
0
2
1
0
A
0
1
2
2
11
2
0
0
0
6
3
1
4
0
7
A
0
1
2
2
11
2
0
0
0
6
3
1
4
0
7
A
0
1
2
2
6
2
0
0
0
5
3
1
4
0
7
2
6
2
0
⑶ transitive closure
【definition】 The transitive closure matrix , denoted A , of a
directed graph, G, is a matrix such that A [i][j] = 1 if there is
a path of length > 0 from i to j : otherwise, A [i][j] = 0.
【definition】 The reflexive closure matrix , denoted A*, of a
directed graph, G, is a matrix such that A* [i][j] = 1 if there is
a path of length >= 0 from i to j : otherwise, A* [i][j] = 0.
0
0
1
2
3
4
0
0
0
0
0
1
0
0
0
0
0
1
0
0
1
0
0
1
0
0
1
0
1
2
3
4
0
0
0
1
0
A
2
0
0
0
0
0
1
0
0
0
0
1
1
1
1
1
+
A
3
1
1
1
1
1
1
1
1
1
1
4
0
1
2
3
4
1
0
0
0
0
1
1
0
0
0
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
A*
A --> A*
( n3 )
2
simplify the algorithm : ( n ) (for undirected graph)
distanve[ i ][ j ] =
distanve[ i ][ j ] || distanve[ i ][ k ] && distanve[ k ][ j ]
by using allcosts
-->
6.5 Activity networks
⑴ Activity on vertex (AOV) networks
【definition】An activity on vertex, or AOV, network is a
directed graph G in which the vertices represent tasks or
activities and the edges represent precedence relations
between tasks
【definition】Vertex i in an AOV network G is a predecessor of
vertex j iff there is a directed path from vertex i to vertex j.
Vertex i is an immediate predecessor of vertex j iff < i, j > is an
edge in G. If i is a predecessor of j . then j is a successor of i. If i
is an immediate predecessor of j, then j Is an immediate
successor of i.
148
course
c1
c2
c3
c4
c5
c6
c7
c8
c9
c10
c11
c12
c13
c14
c15
course name
programming 1
discrete mathematics
data structure
calculus I
calculus II
linear algebra
analysis of algorithm
assembly language
operating system
programming language
compiler design
artificial intelligence
computational theory
parallel algorithms
numerical analysis
prerequisites
none
none
c1,c2
none
c4
c5
c3,c6
c3
c7,c8
c7
c10
c7
c7
c13
c5
C9
C8
C1
C3
C5
C11
C12
C14
C7
C2
C4
C10
C6
C13
C15
【definition】A relation · is transitive iff for all i, j, k. i·j and
j·k => i·k. A relation ·is irreflexive on a set S if i·i is false
for all elements, in S. A partial order is a precedence relation
that is both transitive and irreflexive.
【definition】A topological order is a linear ordering of the
vertices of a graph such that for any two vertices, i, j, if i is a
predecessor of j in the network then i precedes j in the linear
ordering.
several possible topological order:
149
C1,C2,C4,C5,C3,C6,C8,C7,C10,C13,C12,C14,C15,C11,C9 and
C4,C5,C2,C1,C6,C3,C8,C15,C7,C9,C10,C11,C12,C13,C14
algorithm
1. list out a vertex in the network that has no predecessor
2. delete this vertex, and all edges leading out from it, from
the network.
3. repeat 1, 2, until either all the vertices have been listed, or
all remaining vertices have predecessors and so we
cannot
remove any of them.
program topological sort
for (i = 0; i < n; i++){
if every vertex has a predecessor {
fprintf(stderr,"Network has a cycle .\n");
exit(1);
}
pick a vertex v that has no predecessors;
output v;
delete v and all edges leading out of v
from the network;
}
V1
V0
V2
V4
V2
V4
V3
V5
V3
V5
(a)initial
(b)V0
V1
V1
V1
V2
(c)V3
V4
V1
V4
V4
V5
V5
(d)V2
V4
(e)V5
(f)V1 (g)V4
Topological order generated V0,V3,V2,V5,V1,V4
150
typedef struct node *node_pointer;
typedef struct node { int vertex;
node_pointer link;
};
typedef struct { int count;
node_pointer link;
} hdnodes;
hdnodes graph[ MAX_VERTICES ]
void topsort(hdnodes graph[ ],int n)
{
int i,j,k,top;
node_pointer ptr;
/* create a stack of vertices with no predecessors*/
top = -1;
for (i = 0; i < n; i++)
if (!graph[i].count){
graph[i].count = top;
top = i;
}
for (i = 0; i < n; i++)
if (top = -1){
fprintf(stderr,"\Network has a cycle. Sort
terminated.\n");
exit(1);
}
else{
j = top; /* unstack a vertex */
top = graph[top].count;
printf("v%d",j);
for (ptr = graph[j].link; ptr; ptr = ptr->link){
/*decrease the count of the successor vertices
of j */
k = ptr->vertex;
graph[k].count--;
if ( !graph[k].count){ /* add vertex k to the
stack */
graph[k].count = top;
top = k;
}
}
151
}
}
2
3
V0
0
1
V1
1
4
V2
1
4
5
null
V3
1
5
4
null
V4
3
null
V5
2
null
null
null
n1
(( d i ) n) ( e n)
complexity
i 0
⑵ activity on edge (AOE) network
AOE ( an activity on edge) closely related to the AOV
directed edges ~ tasks or activities to be performed on a
project
vertices ~ events which signal the completion of certain
activities
v6
a9=2
v1 a3=1
a0=6
start
v4
v0 a1=4
a2=5
a6=9
v8
v2 a4=1 a7=7 v7 a10=4
v5
v3
a5=2
a8=4
finish
event interpretation
v0 start of project
v1 completion of activity a0
v4 completion of activity a3 & a4
v7 completion of activity a7 & a8
v8 completion of project
techniques for evaluating network:
PERT ( performance evaluation and review technique)
CPM
( critical path method )
RAMPS ( resource allocation and multiproject scheduling )
critical path --- a path that has the longest length
earliest time (an event ,vi, can occur) --- the length of the
longest path from the start vertex v0 to vertex vi.
latest time, late(i), of activity, ai ---- the latest time the
152
activity may start without increasing the project duration
calculation of earliest times
if activity ai is represented by edge <k,l > :
early( i ) = earliest [ k ]
late ( i ) = latest [ l ] - duration of activity ai
earliest [ 0 ] = 0
earliest [ j ] =
max
i P ( j )
{ earliest [ i ] + duration of < i, j > }
P(j) is the set of immediate predecessors of j
calculation of latest times
latest [ n -1 ] = earliest [ n - 1 ] ( start)
latest [ j ] =
min
i S ( j )
{ latest [ i ] - duration of < i, j > }
S(j) is the set of vertices adjacent from vertex j,
S(j) is the set of immediate successors of j
V0
0
1 6
2 4
V1
1
4 1 null
V2
1
4 1 null
V3
1
5 2 null
V4
2
6 9
V5
1
7 4
null
V6
1
8 2
null
V7
2
8 4
null
V8
2
7 7
3 5 null
null
null
153
earliest
initial
output v0
output v3
output v5
output v2
output v1
output v4
output v7
output v6
output v8
[0] [1]
0 0
0 6
0
0
6
0
0
0
6
0
11
0
6
0
11
0
6
0
11
0
6
16 14
0
6
16 14
0
6
16 14
[2] [3] [4] [5] [6] [7] [8] stack
0
0 0 0
0 0 0 [0]
4
5 0 0
0 0
[3,2,1]
[5,2,1]
4
5
0
7
[2,1]
0
[1]
4
5
0
7
[4]
0
[7,6]
4
5
5
7
[6]
0
[8]
4
5
7
7
0
4
5
7
7
0
4
5
7
7
16
4
5
7
7
18
154
earliest
initial
output v8
output v7
output v5
output v3
output v6
output v4
output v2
output v1
V0
3
V1
1
0
6
null
V2
1
0
4
null
V3
1
0
5
null
V4
2
1
1
V5
1
3 2
null
V6
1
4 9
null
V7
1
4 7
5
4
null
V8
0
6 2
7 4
null
null
[0] [1] [2] [3]
[8]
18 18 18 18
18
18 18 18 18
18
18 18 18 18
14
18
18 18 18 18
14
18
3 18 18
16 14
18
3 18 18
16 14
18
3
6
6
10 16 14
2
6
6
10 16 14
0
6
6
10 16 14
2 1 null
[4] [5]
[6] [7]
stack
18
18 [8]
[7,6]
18 18 16 14 [5,6]
[3,6]
7
10 16
[6]
[4]
7
10 16
[2,1]
[1]
8
7
10
[0]
8
18
18
18
18 18
7
10
8
7
8
7
8
7
latest [ 8 ] = earliest [ 8 ] = 18
latest [ 6 ] = min { earliest [ 8 ] - 2 } = 16
latest [ 7 ] = min { earliest [ 8 ] - 4 } = 14
latest [ 4 ] = min { earliest [ 6 ] - 9 , earliest [ 7 ] - 7} = 7
latest [ 1 ] = min { earliest [ 4 ] - 1 } = 6
155
latest [ 2 ] = min { earliest [ 4 ] - 1 } = 6
latest [ 5 ] = min { earliest [ 7 ] - 4 } = 10
latest [ 3 ] = min { earliest [ 5 ] - 2 } = 8
latest [ 0 ]
= min { earliest [ 1 ] - 6,earliest [ 2 ] - 4,earliest [ 3 ] - 5 } = 0
156
© Copyright 2025 Paperzz