Chapter 28
Graphs and Applications
Part1. Non-weighted Graphs
CIS265/506 Cleveland State University – Prof. Victor Matos Adapted from: Introduction to Java Programming: Comprehensive Version, Eighth Edition by Y. Daniel Liang
Modeling Using Graphs
Seattle
San Francisco
Los Angeles
Denver
Chicago
Kansas City
Houston
Boston
New York
Atlanta
Miami
Dallas
2
Weighted Graph Animation
3
www.cs.armstrong.edu/liang/animation/GraphLearningTool.html
Seven Bridges of Königsberg
4
Island 1 Island 2
B
A
C D
A
C
B
D
The city, islands, and bridge could be
abstracted as a graph holding vertices and
edges (bridges).
The problem was to find a walk through
the graph that would begin and end at the
same vertex crossing each edge exactly once.
The city of Konigsberg is
connected to two islands
through seven bridges.
Seven Bridges of Königsberg
5
A, 3
C, 5
B, 3
D, 3
No solution!!
Def. A path that traverses all bridges
once and also has the same starting and
ending is called an Eulerian circuit.
Such a circuit exists if, and only if, the
graph is connected, and there are no nodes
of odd degree at all.
A node degree is the count of edges
adjacent to the node.
Leonhard Euler, 1707
Basic Graph Terminology
6
1. What is a graph?
2. Directed vs. undirected graphs
3. Weighted vs. non-weighted graphs
4. Adjacent vertices
5. Incident
6. Degree
7. Neighbor
8. loop
Leonhard Euler, 1707-1785
Basic Graph Terminology
7
1. What is a graph?
A graph G(V, E) is a representation
of a set of vertices V and edges E.
Two vertices v1 and v2 in V are related
iff there is and edge e12 in E connecting
v1 and v2. Leonhard Euler, 1707-1785
Seattle
San Francisco
Los Angeles
Denver
Chicago
Kansas City
Houston
Boston
New York
Atlanta
Miami
Dallas
Basic Graph Terminology
8
1. What is
a graph?
Basic Graph Terminology
9
2. Node, vertice, vertex
3. Parallel edge
4. Loops
5. Complete graph
6. Simple graph
(connected, undirected,
no loops, no parallel
weighted)
Basic Graph Terminology
10
7. Spanning tree T of a connected, undirected graph G is a tree
composed of all the vertices and some (or perhaps all) of the
edges of G.
A graph may have several
Spanning trees !
Java: Representing Graphs
11
Representing
Vertices
Representing Edges:
Edge Array
Edge Objects (POJO)
Adjacency Matrices
Adjacency Lists
Representing Vertices
12
String[ ] vertices = {“Seattle“, “San Francisco“, … };
City[ ] vertices = {city0, city1, … };
public class City {
private String cityName;
private int population; ...
}
List<String> vertices;
Seattle
San Francisco
Los Angeles
Denver
Chicago
Kansas City
Houston
Boston
New York
Atlanta
Miami
Dallas A vertex could be an object of any type.
Representing Edges: Edge Array
13
int[][] edges = {{0, 1}, {0, 3} {0, 5}, {1, 0}, {1, 2}, … };
There is an edge
between city0 and city1
Representing Edges: Edge Object
public class Edge {
int v1, v2;
public Edge(int v1, int v2) {
this.v1 = v1;
this.v 2 = v2;
}
List<Edge> list = new ArrayList<Edge>();
list.add( new Edge(0, 1) );
list.add( new Edge(0, 3) ); …
Representing Edges: Adjacency Matrix
15
int[][] adjacencyMatrix = { {0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0}, // Seattle {1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}, // San Francisco {0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0}, // Los Angeles {1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0}, // Denver {0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0}, // Kansas City {1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0}, // Chicago {0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0}, // Boston {0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0}, // New York {0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1}, // Atlanta {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1}, // Miami {0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1}, // Dallas {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0} // Houston };
Entry adjacencyMatrix[i][j] is 1 if there is an edge connecting
city-i and city-j
Representing Edges: Adjacency List
16
neighbors[0]
neighbors[1]
neighbors[2]
neighbors[3]
neighbors[4]
neighbors[5]
neighbors[6]
neighbors[7]
neighbors[8]
neighbors[9]
neighbors[10]
neighbors[11]
Seattle
San Francisco
Los Angeles
Denver
Kansas City
Chicago
Boston
New York
Atlanta
Miami
Dallas
Houston
1 3 5
0 2 3
0 1 2 4 5
1 3 4 10
2 3 5 7 8 10
0 3 4 7 11
5 7
4 5 6 8
4 7 9 10 11
8 11
2 4 8 11
10 8 9
List<Integer>[ ] neighbors = new LinkedList<Integer>[12];
Graph
WeightedGraph
AbstractGraph
UnweightedGraph
Interface Abstract Class Concrete Classes
Modeling Graphs
17
In a style similar to the Java Collection Framework we will define
1. an interface named Graph that contains all common operations
of graphs and
2. an abstract class named AbstractGraph that partially
implements the Graph interface.
3. Many concrete graphs may be added to the design. For example,
we will define such graphs named UnweightedGraph and
WeightedGraph.
Graph Traversals - Trees
20
Depth-first search (DFS) and breadth-first search (BFS)
Both traversals result in a spanning tree, which can be modeled using a class.
Depth-First Search (DFS)
21
1. In the case of a tree, DFS search starts from the root (similar
to pre-order navigation).
2. In a graph, the search can start from any vertex.
dfs(vertex v) {
visit v;
for each neighbor w of v
if (w has not been visited) {
dfs(w);
}
}
Seattle
San Francisco
Los Angeles
Denver
Chicago
Kansas City
Houston
Boston
New York
Atlanta
Miami
Dallas
DFS Depth-First Search Example
23
Applications of the DFS
24
1. Detecting whether a graph is connected. Search the graph
starting from any vertex. If the number of vertices searched is the same
as the number of vertices in the graph, the graph is connected.
Otherwise, the graph is not connected
2. Detecting / finding a path between two vertices.
3. Finding all connected components. A connected component is a
maximal connected subgraph in which every pair of vertices are
connected by a path.
4. Detecting / Finding a cycle in a graph.
Breadth-First Search (BFS)
25
With breadth-first traversal of a tree, the nodes are visited level
by level.
1. First the root is visited,
2. then all the children of the root,
3. then the grandchildren of the root from left to right,
4. and so on.
BFS Breadth-First Search Algorithm
26
bfs(vertex v) {
create an empty queue for storing vertices to be visited;
add v into the queue;
mark v visited;
while the queue is not empty {
dequeue a vertex, say u, from the queue
process u;
for each neighbor w of u
if w has not been visited {
add w into the queue;
mark w visited;
}
}
}
BFS Breadth-First Search Example
27
0 1
2
3 4
0 1
2
3 4
0 1
2
3 4
Queue: 0
Queue: 1 2 3
Queue: 2 3 4
isVisited[0] = true
isVisited[1] = true
isVisited[2] = true
isVisited[3] = true
isVisited[4] = true
BFS Breadth-First Search Example
Seattle
San Francisco
Los Angeles
Denver
Chicago
Kansas City
Houston
Boston
New York
Atlanta
Miami
Dallas
28
Applications of the BFS
29
1. Detecting whether a graph is connected. A graph is connected if there is a path
between any two vertices in the graph.
2. Detecting whether there is a path between two vertices.
3. Finding a shortest path between two vertices. You can prove that the path
between the root and any node in the BFS tree is the shortest path between the
root and the node
4. Finding all connected components. A connected component is a maximal
connected subgraph in which every pair of vertices are connected by a path.
5. Detecting /Finding whether there is a cycle in the graph.
6. Testing whether a graph is bipartite. A graph is bipartite if the vertices of the
graph can be divided into two disjoint sets such that no edges exist between
vertices in the same set.
BFS & DFS Programming Exercise
31
public static void main(String[] args) { Graph<String> graph = new Graph<String>(); graph.addVertice("V0"); graph.addVertice("V1"); graph.addVertice("V2"); graph.addVertice("V3"); graph.addVertice("V4"); graph.addVertice("V5"); graph.addEdge(0,1); graph.addEdge(1,2); graph.addEdge(1,3); graph.addEdge(1,4); graph.addEdge(4,5); graph.addEdge(2,5); graph.addEdge(3,5); graph.showData(); System.out.println("\nDFS >>> "); graph.clearVisitedMarkers(); graph.dfs(0); System.out.println("\nBFS >>> "); graph.clearVisitedMarkers(); graph.bfs(0);
}
BFS & DFS Programming Exercise
32
public class Graph <E> { private ArrayList<E> vertices; private ArrayList< ArrayList<Integer> > neighbors; private ArrayList<Boolean> visitedMarkers; public Graph() { vertices = new ArrayList<E>(); neighbors = new ArrayList < ArrayList<Integer> >(); visitedMarkers = new ArrayList<Boolean>(); } public void addVertice(E newVertice){ vertices.add(newVertice); visitedMarkers.add(false); neighbors.add(new ArrayList<Integer>() ); } public void addEdge( int v1, int v2){ ArrayList<Integer> adjacent1 = neighbors.get(v1); if (!adjacent1.contains(v2)) neighbors.get(v1).add(v2); ArrayList<Integer> adjacent2 = neighbors.get(v2); if (!adjacent2.contains(v1)) neighbors.get(v2).add(v1); }
BFS & DFS Programming Exercise
33
public void markVerticeAsVisited(int v){ visitedMarkers.set(v, true); } public void clearVisitedMarkers(){ for(int i=0; i<vertices.size(); i++){ visitedMarkers.set(i, false); } } public void showData() { for (int i=0; i<vertices.size(); i++){ System.out.printf("\nVertice[%d]= %s", i, vertices.get(i)); } for (int i=0; i < vertices.size(); i++){ System.out.printf("\nneighbors[%d]: ", i); ArrayList<Integer> adjacent = neighbors.get(i); for (int j=0; j<adjacent.size(); j++){ System.out.printf(" %d,", adjacent.get(j) ); } } }//showData
34
public void dfs(int v) { visitedMarkers.set(v, true); for(int n : neighbors.get(v)){ if (!visitedMarkers.get(n)){ System.out.printf("[v%d-v%d] ", v, n); dfs(n); } } }//dfs
BFS & DFS Programming Exercise
BFS & DFS Programming Excersice
35
public void bfs(int v){ ArrayList<Integer> queue = new ArrayList<Integer>(); clearVisitedMarkers(); visitedMarkers.set(v, true); System.out.printf("BFS >>> starting at: v%d \n", v); queue.add(v); while(queue.size() > 0){ int currentDequeuedVertice = queue.remove(0); ArrayList<Integer> adjacents = neighbors.get(currentDequeuedVertice); for(int i=0; i<adjacents.size(); i++){ int adjacentNode = adjacents.get(i); if (!visitedMarkers.get(adjacentNode)){ System.out.printf("[v%d-v%d] ", currentDequeuedVertice, adjacentNode); queue.add(adjacentNode); visitedMarkers.set(adjacentNode, true); }//if }//for }//while }//bfs }
Case: The Nine Tail Problem
36
1. Nine coins are placed in a three by three matrix with some face up and some face down.
2. A legal move is to take any coin that is face up and reverse it, together with the coins adjacent to it (this does not include coins that are diagonally adjacent).
3. Your task is to find the minimum number of the moves that lead to all coins face down.
H
T
T
T
H
H
H
H
H
H
T
H
T
H
H
T
T
T
T
T
T
T
T
T
T
T
T
Finding Eulerian Paths
38
An Eulerian path traverses each edge of a connected graph G exactly once.
It exists only if there are no more than two odd nodes.
1. Pick an odd vertex to start.
2. From that vertex move to a node using an “unvisited” edge.
3. Mark that edge as “visited” (see note)
4. Try to repeat 2-4 until all edges have been traversed
Note: DFS algorithm marks nodes as visited.
1
2 4
3
2
2
3
3
1
2 4
3
2
3
3
3
2
1
More than two odd nodes ⟶ no Euler Path
The Hamiltonian Path Problem
39
Def. A Hamiltonian path in a graph is a path that visits each vertex in the graph exactly once.
Def. A Hamiltonian cycle is a cycle that visits each vertex in the graph exactly once and returns to the starting vertex.
Notes:
Problem is NP-Complete
Many applications such as: Scheduling the Traveling Salesman Itinerary.
Top Related