Graphs: As a mathematics branch Map of Königsberg 1 2 3 4 Leonhard Paul Euler 1707-1783 Can we cross every bridge exactly once and return to the same place? (There is no other way but through the bridges to cross the rivers) Euler’s solution is considered as the first Graph theorem in history. 12/3/2018 IT 279
Eulerian Graph 1 Map of Königsberg 2 3 4 Starting from a vertex, can we travel every edges exactly once and return to the same vertex? Leonhard Paul Euler 1707-1783 No! If we can, such a path is called an Eulerian Circuit Theorem [Euler 1737]: A graph has an Eulerian Circuit iff the degree of every vertex is even. The first Graph theorem in history. 12/3/2018 IT 279
Graphs: Algorithmic approach Many problems are unsolvable (usually are associated to infinite graphs) ; Many problems are intractable (NPC problems), And yet, many applicative problems are manageable; (in terms of |V| and |E|) G = (V, E) V: a set of vertices E: a set of edges, E V V 1 Example, V: = {1,2,3,4,5,6} E: = {(1,2), (1,5), (2,3), (2,5), (3,4), (4,5), (4,6)} 2 5 6 3 4 12/3/2018 IT 279
Undirected Graphs G= (V,E) is an undirected graph, if (v, w) E (w, v) E Example, V: = {1,2,3,4,5,6} E: = {(1,2), (1,5), (2,3), (2,5), (3,4), (4,5), (4,6) (2,1), (5,1), (3,2), (5,2), (4,3), (5,4), (6,4) } 1 V: = {1,2,3,4,5,6} E: = { {1,2}, {1,5}, {2,3}, {2,5}, {3,4}, {4,5}, {4,6} } 2 5 6 3 4 12/3/2018 IT 279
Weighted Graphs Every edge in E has a value associated to it. Example, 1 Example, 2.3 3 V: = {1,2,3,4,5,6} E: = {(1,2,3), (1,5,2.3), (2,3,4.5), (2,5,2/3), (3,4,7.1), (4,5,10), (4,6,12)} 2 2/3 5 6 4.5 10 12 3 7.1 4 Weighted graph: G= (V,E), where E V V Q rational numbers 12/3/2018 IT 279
A walk on a graph (v1, v2,.... vn) Vn , such that (vi , vi+1) E, for 1 i < n, is called a walk of G= (V,E) Example: (1,2,4,7,9,8,5,4,7,6,5,2,3) a walk 2 4 7 9 1 3 5 8 6 12/3/2018 IT 279
More Terminologies (v1, v2,.... vn) Vn , such that (vi , vi+1) E, for 1 i < n, is called a walk of G= (V,E) A path is a walk such that no vertex in the walk is repeated. A trail is a walk such that no edge in the walk is repeated. (Any path is a trial) A circuit is a closed trial, i.e, v1 = vn. A cycle is a circuit such that v1 = vn is only repeated vertex. A spanning is a walk such that every vertex is included A Eulerian circuit is a circuit that contains every edge. A Hamiltonian cycle is a spanning cycle. 12/3/2018 IT 279
A Walk: 1,2,4,7,9,8,5,4,7,6,5,2,3 (not a trial) 2 4 7 9 1 3 5 8 6 12/3/2018 IT 279
A Circuit: 1,2,4,7,9,8,5,4,7,6,5,2,3,1 (not a cycle) A Trial: 1,2,4,7,9,8,5,4,0,7,6,5,2,3 (not a path) A Circuit: 1,2,4,7,9,8,5,4,7,6,5,2,3,1 (not a cycle) 2 4 7 9 1 3 5 8 6 12/3/2018 IT 279
A Path: 1,2,4,0,7,6,5,3 A Cycle: 1,2,4,0,7,6,5,3,1 There are many other cycles in this graph 2 4 7 9 1 3 5 8 6 12/3/2018 IT 279
A graph without any cycle in it is called acyclic 2 4 7 9 1 3 5 8 6 An acyclic Graph 12/3/2018 IT 279
Representation of Graphs. (Data Structures) Adjacency Matrix Good for dense graph. 1 2 3 4 5 6 7 8 9 2 4 7 9 1 3 5 8 6 12/3/2018 IT 279
Representation of Graphs. Adjacency Matrix for a Weighted Graph 1 2 3 4 5 2.3 4.5 2/3 7.1 10 12 2.3 3 1 2/3 4 5 4.5 10 12 2 7.1 3 12/3/2018 IT 279
Representation of Graphs. (Data Structures) Adjacency List A commonly used representation 2 4 7 1 3 5 6 9 8 2 4 7 9 1 3 5 8 6 12/3/2018 IT 279
Representation of Graphs. Adjacency List for a Weighted Graph (1, 3) (4, 2.3) 1 (2, 4.5) (4, 2/3) 2 (3, 7.1) 3 (4, 10) (5, 12) 4 5 2.3 3 1 2/3 4 5 4.5 10 12 2 7.1 3 How to implement? 12/3/2018 IT 279
Representation of Graphs. (Data Structures) Adjacency List Should be easy to insert/delete vertices and edges Should be easy to retrieve. Should not use to much memory. 2 4 7 1 2 3 4 5 6 7 8 9 1 3 4 5 1 7 3 4 6 1 6 9 5 9 array (dynamic) linked lists 12/3/2018 IT 279
STL: C++ Standard Template Library Read: Weiss Ch. 4.8 of Weiss and Chapter 19 of Savitch #include <vector> #include <deque> #include <stack> #include <set> #include <map> 12/3/2018 IT 279
<deque> (Double Ended Queue) student 2 student 1 #include <iostream> #include <deque> .............. deque<student> IT279; while (....) { ...... IT279.push_front(s); IT279.push_back(s); } for (int i=0;i<ITK.size();i++) { cout << "\nName:" << ITK[i].name << " "; cout << "SSN:" << ITK[i].ssn; ITK IT279[0] IT279[1] IT279[2] IT279[3] 12/3/2018 IT 279
pop back and pop front on a deque student 1 student 2 student 3 student 4 student 5 x#@%.. student 1 student 2 student 3 student 4 student 5 x#@%.. IT279 IT279 IT279[0] IT279[0] IT279[1] IT279[0] IT279[2] .... IT279.pop_front(); IT279.pop_back(); IT279[1] IT279[3] IT279[2] IT279[4] IT279[4] 12/3/2018 IT 279
<set> Red-Black Tree 10 6 12 3 8 15 5 9 #include <iostream> #include <set> .............. set<int> S; while (....) { int e; // an element of S S.insert(e); } set<int>::iterator itr; itr = S.begin(); S.erase(itr); for (itr= S.begin(); itr != S.end(); itr++) cout << *itr; 6 12 3 8 15 5 9 12/3/2018 IT 279
<map> Red-Black Tree key, associated value in, double 10, 1.2 Red-Black Tree #include <iostream> #include <map> .............. map<int, double> M; int i; double w; while (....) { // e is an element of M pair e = make_pair(i,w); M.insert(e); } map<int, double>::iterator itr; itr = M.begin(); M.erase(itr); for (itr= M.begin(); itr != M.end(); itr++) cout << “\n(“ << itr->first << “,” << itr->second << “)”; 6, 3.4 12, 1.2 3, 3.4 8, 5.6 15, 0.3 5, 2.8 9, 0.1 key, associated value in, double 12/3/2018 IT 279
Using STL to implement Graphs typedef map<int, double> AdjacencyList; typedef map<int, AdjacencyList> Graph; 3 2.3 Graph G; 0.6 3, 1 4 5 4.5 6.3 10 12 1, 4, G[4] 2 3 7.1 G[5] 0, 2, 5, (1, 3) (4, 2.3) 1 (2, 4.5) (4, 0.6) 2 (3, 7.1) 3 (1, 6.3) (4, 10) (5, 12) 4 5 G[0] G[3] G[1] G[2] 4, 2.3 4, 10 2, 4.5 3, 7.1 1, 3.0 1, 6.3 5, 12 4, 0.6 (G[3])[5] = 12 (G[1])[4] = 0.6 12/3/2018 IT 279
Create Random Graphs typedef map<int, double> AdjacencyList; typedef map<int, AdjacencyList> Graph; // Create a graph of n vertices, d is the maximum out degree Graph create_graph(int n, int d, bool weighted=true) { Graph g; for (int i=0;i<n;i++) { // Prepare vertex i int outdegree = rand()%d; AdjacencyList aj; // Prepare the Adjacency List for vertex i for (int j=0; j<outdegree; j++) { int v = rand()%n; if (i==v) continue; aj[v]=(weighted ? (double)(rand()%100): 1.0; } g[i]=aj; return g; 12/3/2018 IT 279
Some basic graph operations class graph { public: static void add_v(Graph & g, int v, AdjacencyList aj); static void remove_v(Graph & g, int v); static void display(Graph & g); ..... }; void graph::add_v(Graph & g, int v, AdjacencyList aj) { g[v]=aj; } void graph::display(Graph & G) { Graph::iterator p; AdjacencyList::iterator q; for (p=G.begin();p!=G.end();p++) { cout << p->first << ":: "; for (q=p->second.begin();q!=p->second.end();q++) cout << p->first << "-->" << q->first << " [" << q->second << "], "; cout << " *\n"; } 12/3/2018 IT 279
Remove a vertex void graph::remove_v(Graph & g, int v) { g.erase(v); Graph::iterator p; for (p=g.begin();p!=g.end();p++) p->second.erase(v); } 2 4 7 1 2 3 4 5 6 7 8 9 1 3 4 5 remove 7 1 7 3 4 6 1 6 9 5 9 12/3/2018 IT 279
Given a graph, determine is the graph is acyclic 2 4 7 9 1 3 5 8 Not An acyclic Graph 6 12/3/2018 IT 279
Given a graph, determine is the graph is acyclic 2 4 7 9 1 3 5 8 Not An acyclic Graph 6 No vertex in this cycle has in-degree 0 12/3/2018 IT 279
Procedure to determine if a given graph is acyclic Repeatedly remove vertices with in-degree 0; 2 4 7 9 1 3 5 8 If we can’t remove all vertices, then the graph is not acyclic 6 12/3/2018 IT 279
Procedure to determine if a given graph is acyclic Repeatedly remove vertices with in-degree 0; 2 4 7 9 1 3 5 8 If all vertices can be removed, then the given graph is acyclic 6 12/3/2018 IT 279
C++ program to determined if a given graph is acyclic bool graph::acyclic(Graph & G) { Graph tempG = G; while (tempG.size() >= 2) { int v = findVertexwithZeroIn(tempG); if (v == -1) return false; remove_v(tempG, v); } return true; // -1 mean no zero indegree vertex. int graph::findVertexwithZeroIn(Graph & g){ for (Graph::iterator p=g.begin();p!=g.end();p++) { if (!someTo(g, p->first)) return p->first; } return -1; bool graph::someTo(Graph & g, int v) { for (Graph::iterator p=g.begin();p!=g.end();p++) if (p->second.find(v) != p->second.end()) return true; return false; } 12/3/2018 IT 279