Graph Discrete Mathematics and Its Applications Baojian Hua [email protected].
-
date post
22-Dec-2015 -
Category
Documents
-
view
252 -
download
3
Transcript of Graph Discrete Mathematics and Its Applications Baojian Hua [email protected].
Why Study Graphs?
Interesting & broadly used abstraction not only in computer science
challenge branch in discrete math Ex: the 4-color problem
hundreds of known algorithms with more to study
numerous applications
Broad Applications
Graph Vertices Edges
communication
telephone cables
software functions calls
internet web page hyper-links
social relationship
people friendship
transportation
cities roads
… … …
Graph Terminology
1
4
2
65
3
vertex
edge:
directed vs
undirectedA sample graph taken from chapter 22 of Introduction to Algorithms.
Graph ADT A graph is a tuple (V, E)
V is a set of vertices v1, v2, … E is a set of vertex tuple <vi, vj>
Typical operations: graph creation search a vertex (or an edge) traverse all vertexes …
Example
G = (V, E)
V = {1, 2, 3,
4, 5, 6}
E = {(1, 2),
(2, 5), (3, 5), (3, 6), (4, 1), (4, 2), (5, 4), (6, 6)}
1
4
2
65
3
Representation Two popular strategies:
array-based (adjacency matrix) Keep an extensible two-dimensional array M i
nternally M[i][j] holds the edge info’ of <vi, vj>, if ther
e exists one linear list-based (adjacency list)
for every vertex vi, maintain a linear list list<vi>
list<vi> stores vi’s out-going edges
Adjacency Matrix
0
0
1
2
51 2 3
1
4
2
65
3
#
#
# #
# #
#
#
3
4
5
4
Note the hash function:hash (n) = n-1
“graph” ADT in C: Interface// We assume, in this slides, all graphs directed, // Undirected ones are similar and easier.// In file “graph.h”#ifndef GRAPH_H#define GRAPH_H
typedef struct graphStruct *graph;
graph newGraph ();void insertVertex (graph g, poly data);void insertEdge (graph g, poly from, poly to);
// more to come later…#endif
Graph Implementation #1: Adjacency Matrix// adjacency matrix-based implementation
#include “matrix.h”
#include “hash.h”
#include “graph.h”
struct graphStruct
{
matrix m;
// remember the index
hash h;
};
# # #0
1
2
3
0 1 2 3
Matrix Interface// file “matrix.h”
#ifndef MATRIX_H
#define MATRIX_H
typedef struct matrixStruct *matrix;
matrix newMatrix ();
void matrixInsert (matrix m, int i, int j);
int matrixExtend (matrix m);
#endif
// Implementation could make use of a two-
// dimensional extensible array, leave to you.
Adjacency Matrix-based: Graph Creationgraph newGraph ()
{
graph g = malloc (sizeof (*g));
g->m = newMatrix (); // an empty matrix
g->h = newHash ();
return g;
}
Adjacency Matrix-based: Inserting Verticesvoid insertVertex (graph g, poly data)
{
int i = matrixExtend (g->matrix);
hashInsert (g->hash, data, i);
return;
}
# # #0
1
2
3
0 1 2 3 0
1
2
3
0 1 2 3
# # #
4
4
Graph Implementation #1: Inserting Edgesvoid insertEdge (graph g, poly from, poly to)
{
int f = hashLookup (g->hash, from);
int t = hashLookup (g->hash, to);
matrixInsert (g->matrix, f, t);
return;
}
# # #0
1
2
3
0 1 2 3 0
1
2
3
0 1 2 3
# # # #
4
4
Client Code
graph g = newGraph ();
insertVertex (g, 1);
insertVertex (g, 2);
…
insertVertex (g, 6);
insertEdge (g, 1, 2);
insertEdge (g, 2, 5);
…
insertEdge (g, 6, 6);
1
4
2
65
3
Graph Representation #2: Adjacency List#include “linkedList.h”#include “graph.h”typedef struct graphStruct *graph;typedef struct vertexStruct *vertex;typedef struct edgeStruct *edge;struct graphStruct { linkedList vertices;};struct vertexStruct { poly data; linkedList edges;};struct edgeStruct { vertex from; vertex to;}
Graph Representation #2: Adjacency List#include “linkedList.h”#include “graph.h”typedef struct vertexStruct *vertex;typedef struct edgeStruct *edge;struct graphStruct { linkedList vertices;};
struct vertexStruct { poly data; linkedList edges;};struct edgeStruct { vertex from; vertex to;}
0
1
2
3
0->1 0->2 0->3
Adjacency List-based: Graph Creation// I’ll make use of this convention for colors:// graph, linkedList, data, vertex, edgegraph newGraph (){ graph g = malloc (sizeof (*g)); g->vertices = newLinkedList ();
return g;}
verticesg
/\
Adjacency List-based:Creating New Vertex// I’ll make use of this convention for colors:// graph, linkedList, data, vertex, edgevertex newVertex (poly data){ vertex v = malloc (sizeof (*v)); v->data = data; v->edges = newLinkedList ();
return v;} data
v
/\
edges
data
Adjacency List-based:Creating New Edge// I’ll make use of this convention for colors:// graph, linkedList, data, vertex, edge edge newEdge (vertex from, vertex to){ edge e = malloc (sizeof (*e)); e->from = from; e->to = to; return e;} from
e
to
from
to
Adjacency List-based:Inserting New Vertexvoid insertVertex (graph g, poly data)
{
vertex v = newVertex (data);
linkedListInsertTail (g->vertices, v);
return;
} 0
1
2
3
0->1 0->2 0->3
4
Adjacency List-based:Inserting New Vertexvoid insertVertex (graph g, poly data)
{
vertex v = newVertex (data);
linkedListInsertTail (g->vertices, v);
return;
} 0
1
2
3
0->1 0->2 0->3
4
Adjacency List-based:Inserting New Vertexvoid insertVertex (graph g, poly data)
{
vertex v = newVertex (data);
linkedListInsertTail (g->vertices, v);
return;
} 0
1
2
3
0->1 0->2 0->3
4
Adjacency List-based:Inserting New Edgevoid insertEdge (graph g, poly from, poly to)
{
vertex vf = lookupVertex (g, from);
vertex vt = lookupVertex (g, to);
edge e = newEdge (vf, vt);
linkedListInsertTail (vf->edges, e);
return;
}
// insert 0->4
0
1
2
3
0->1 0->2 0->3
4
Adjacency List-based:Inserting New Edgevoid insertEdge (graph g, poly from, poly to)
{
vertex vf = lookupVertex (g, from);
vertex vt = lookupVertex (g, to);
edge e = newEdge (vf, vt);
linkedListInsertTail (vf->edges, e);
return;
}
0
1
2
3
0->1 0->2 0->3
4
Adjacency List-based:Inserting New Edgevoid insertEdge (graph g, poly from, poly to)
{
vertex vf = lookupVertex (g, from);
vertex vt = lookupVertex (g, to);
edge e = newEdge (vf, vt);
linkedListInsertTail (vf->edges, e);
return;
}
0
1
2
3
0->1 0->2 0->3
4
Adjacency List-based:Inserting New Edgevoid insertEdge (graph g, poly from, poly to)
{
vertex vf = lookupVertex (g, from);
vertex vt = lookupVertex (g, to);
edge e = newEdge (vf, vt);
linkedListInsertTail (vf->edges, e);
return;
}
0
1
2
3
0->1 0->2 0->3
4
0->4
Adjacency List-based:Inserting New Edgevoid insertEdge (graph g, poly from, poly to)
{
vertex vf = lookupVertex (g, from);
vertex vt = lookupVertex (g, to);
edge e = newEdge (vf, vt);
linkedListInsertTail (vf->edges, e);
return;
}
0
1
2
3
0->1 0->2 0->3
4
0->4
Client Code for This Example:Step #1: Cook Datagraph graph = newGraph ();
nat n1 = newNat (1);
nat n2 = newNat (2);
nat n3 = newNat (3);
nat n4 = newNat (4);
nat n5 = newNat (5);
nat n6 = newNat (6);1
4
2
65
3
Client Code Continued:Step #2: Insert VerticesgraphInsertVertex (graph, n1);
graphInsertVertex (graph, n2);
graphInsertVertex (graph, n3);
graphInsertVertex (graph, n4);
graphInsertVertex (graph, n5);
graphInsertVertex (graph, n6);
1
4
2
65
3
Client Code Continued:Step #3: Insert EdgesgraphInsertEdge (graph, n1, n2);
graphInsertEdge (graph, n2, n5);
graphInsertEdge (graph, n3, n5);
graphInsertEdge (graph, n3, n6);
graphInsertEdge (graph, n4, n1);
graphInsertEdge (graph, n4, n2);
graphInsertEdge (graph, n5, n4);
graphInsertEdge (graph, n6, n6);
// Done! :-)1
4
2
65
3
Example In Picture:An Empty Graph// I’ll make use of this convention for colors:
// graph, linkedList, data, vertex, edge
nextdata
g
Example In Picture:After Inserting all Vertices// I’ll make use of this convention for colors:
// graph, linkedList, data, vertex, edge
nextdata
g
/\
data
next /\ /\ /\ /\ /\
1 2 3 64 5
Example In Picture:After Inserting all Edges (Part)// I’ll make use of this convention for colors:
// graph, linkedList, data, vertex, edge
nextdata
g
/\
data
next /\ /\ /\ /\
1 2 3 64 5
/\ /\
fromto
fromto
Searching The systematic way to traverse all vertex
in a graph Two general methods:
breath first searching (BFS) start from one vertex, first visit all the adjacency
vertices depth first searching (DFS)
eager method
These slides assume the adjacency list representation
“graph” ADT in C: Interface// in file “graph.h”#ifndef GRAPH_H#define GRAPH_H
typedef struct graphStruct *graph;typedef void (*tyVisit)(poly);
graph newGraph ();void insertVertex (graph g, poly data);void insertEdge (graph g, poly from, poly to);void dfs (graph g, poly start, tyVisit visit);void bfs (graph g, poly start, tyVisit visit);// we’d see more later…#endif
Sample Graph BFS
1
4
2
65
3bfs (g, 1, natOutput);
print 1;
// a choice
print 2;
print 4;
print 5;
// a choice
print 3;
Sample Graph BFS
1
4
2
65
3bfs (g, 1, natOutput);
print 1;
// a choice
print 2;
print 4;
print 5;
// a choice
print 3;
print 6;
BFS Algorithmbfs (vertex start, tyVisit visit){ queue q = newQueue ();
enQueue (q, start); while (q not empty) { vertex current = deQueue (q); visit (current); for (each adjacent vertex u of “current”){ if (not visited u) enQueue (q, u); } }}
BFS Algorithmvoid bfsMain (graph g, poly start, tyVisit visit){ vertex startV = searchVertex (g, start); bfs (startV, visit);
for (each vertex u in graph g) if (not visited u) bfs (q, u);}
Sample Graph BFS
1
4
2
65
3bfs (g, 1, natOutput);
print 1;
// a choice
print 2;
Queue: 2, 4
Queue: 1
Queue: 4, 5
Sample Graph BFS
1
4
2
65
3bfs (g, 1, natOutput);
print 1;
// a choice
print 2;
print 4;
Queue: 5
Queue: 2, 4
Queue: 1
Queue: 4, 5
Sample Graph BFS
1
4
2
65
3bfs (g, 1, natOutput);
print 1;
// a choice
print 2;
print 4;
print 5;
Queue:
Queue: 5
Queue: 2, 4
Queue: 1
Queue: 4, 5
Queue: 3
Sample Graph BFS
1
4
2
65
3bfs (g, 1, natOutput);
print 1;
// a choice
print 2;
print 4;
print 5;
// a choice
print 3;
Queue:
Queue: 5
Queue: 2, 4
Queue: 1
Queue: 4, 5
Queue: 3
Queue: 6
Sample Graph BFS
1
4
2
65
3bfs (g, 1, natOutput);
print 1;
// a choice
print 2;
print 4;
print 5;
// a choice
print 3;
print 6;Queue:
Queue: 5
Queue: 2, 4
Queue: 1
Queue: 4, 5
Queue: 3
Queue: 6
Queue:
Moral
BFS is very much like the level-order traversal on trees
Maintain internally a queue to control the visit order
Obtain a BFS forest when finished
Sample Graph DFS
1
4
2
65
3dfs (g, 1, natOutput);
print 1;
// a choice
print 2;
print 5;
print 4;
// a choice
print 3;
Sample Graph DFS
1
4
2
65
3dfs (g, 1, natOutput);
print 1;
// a choice
print 2;
print 5;
print 4;
// a choice
print 3;
print 6;
DFS Algorithmdfs (vertex start, tyVisit visit){ visit (start);
for (each adjacent vertex u of “start”) if (not visited u) dfs (u, visit);}
DFS Algorithmvoid dfsMain (graph g, poly start, tyVisit visit){ vertex startV = searchVertex (g, start); dfs (startV, visit);
for (each vertex u in graph g) if (not visited u) dfs (u, visit);}
Sample Graph DFS
1
4
2
65
3dfs (g, 1, natOutput);
print 1;
// a choice
print 2;
print 5;
dfs(1) => dfs(2) => dfs(5)
Sample Graph DFS
1
4
2
65
3dfs (g, 1, natOutput);
print 1;
// a choice
print 2;
print 5;
print 4;dfs(1) => dfs(2) => dfs(5) => dfs(4)
Sample Graph DFS
1
4
2
65
3dfs (g, 1, natOutput);
print 1;
// a choice
print 2;
print 5;
print 4;dfs(1) => dfs(2) => dfs(5) => dfs(4) => dfs(2)???
Sample Graph DFS
1
4
2
65
3dfs (g, 1, natOutput);
print 1;
// a choice
print 2;
print 5;
print 4;dfs(1) => dfs(2) => dfs(5)
Sample Graph DFS
1
4
2
65
3dfs (g, 1, natOutput);
print 1;
// a choice
print 2;
print 5;
print 4;dfs(1) => dfs(2)
Sample Graph DFS
1
4
2
65
3dfs (g, 1, natOutput);
print 1;
// a choice
print 2;
print 5;
print 4;dfs(1)
Sample Graph DFS
1
4
2
65
3dfs (g, 1, natOutput);
print 1;
// a choice
print 2;
print 5;
print 4;dfs(1) =>dfs(4)???
Sample Graph DFS
1
4
2
65
3dfs (g, 1, natOutput);
print 1;
// a choice
print 2;
print 5;
print 4;dfs(1)
Sample Graph DFS
1
4
2
65
3dfs (g, 1, natOutput);
print 1;
// a choice
print 2;
print 5;
print 4;empty!
Sample Graph DFS
1
4
2
65
3dfs (g, 1, natOutput);
print 1;
// a choice
print 2;
print 5;
print 4;
// a choice
print 3;
dfs(3)
Sample Graph DFS
1
4
2
65
3dfs (g, 1, natOutput);
print 1;
// a choice
print 2;
print 5;
print 4;
// a choice
print 3;
print 6;
dfs(3) =>dfs(6)
Sample Graph DFS
1
4
2
65
3dfs (g, 1, natOutput);
print 1;
// a choice
print 2;
print 5;
print 4;
// a choice
print 3;
print 6;
dfs(3) =>dfs(6) =>dfs(6)???
Sample Graph DFS
1
4
2
65
3dfs (g, 1, natOutput);
print 1;
// a choice
print 2;
print 5;
print 4;
// a choice
print 3;
print 6;
dfs(3) =>dfs(6)
Sample Graph DFS
1
4
2
65
3dfs (g, 1, natOutput);
print 1;
// a choice
print 2;
print 5;
print 4;
// a choice
print 3;
print 6;
dfs(3)
Sample Graph DFS
1
4
2
65
3dfs (g, 1, natOutput);
print 1;
// a choice
print 2;
print 5;
print 4;
// a choice
print 3;
print 6;
dfs(3) =>dfs(5)???
Sample Graph DFS
1
4
2
65
3dfs (g, 1, natOutput);
print 1;
// a choice
print 2;
print 5;
print 4;
// a choice
print 3;
print 6;
dfs(3)
Sample Graph DFS
1
4
2
65
3dfs (g, 1, natOutput);
print 1;
// a choice
print 2;
print 5;
print 4;
// a choice
print 3;
print 6;
empty!
Moral
DFS is very much like the pre-order traversal on trees
Maintain internally a stack to control the visit order for recursion function, machine
maintain an implicit stack Obtain a DFS forest when finished
Edge Classification
Once we obtain the DFS (or BFS) spanning trees (forests), the graph edges could be classified according to the trees: tree edges: edges in the trees forward edges: ancestors to descants back edges: descants to ancestors cross edges: others