Sunteți pe pagina 1din 125

Graph Algorithms

Chapter 9

Graph Concepts
* A graph is a collection of vertices (nodes) and lines that connect pairs of vertices * Each node may have multiple predecessors and successors * A directed graph (digraph) has vertices that are connected through directional lines or arcs * An undirected graph has vertices connected through non-directional lines or edges

G = (V, E)
a vertex may have: 0 or more predecessors 0 or more successors

some problems that can be represented by a graph


* * * * * * * computer networks airline flights road map course prerequisite structure tasks for completing a job flow of control through a program many more

More Graph Concepts


* Two vertices are adjacent if an edge directly connects them * A path is a sequence of adjacent vertices * A cycle is a path that starts and ends with the same vertex * Two vertices are connected if there is a path between them

Even More Graph Concepts...


* A digraph is strongly connected if there is a path from each vertex to every other vertex * A digraph is weakly connected if at least two vertices are not connected * A graph is disjoint if it is not connected

* The degree is the number of lines entering or leaving the vertex in a digraph
* In-degree is the number of arcs entering the vertex * Out-degree is the number of arcs leaving the vertex

Graph Storage Structures


* Graph data is stored in two sets of data: * Arrays or linked lists may be used to store data * Two approaches to store graph data:
* Adjacency Matrix * Adjacency List

* Vertices (nodes) * Edges (lines) or Arcs

Adjacency Matrix
* Uses a vector (one-dimensional array for vertices, and a matrix (two-dimensional array) to store edges * Size of graph must be known before program starts * Only one edge can be stored between any two vertices

Adjacency List
* Uses a two-dimensional array to store edges
* Vertex list is a linked list of vertices in the list, and has a head pointer to a linked list of edges from the vertex * The edge (arc) list is a linked list of edges (arcs); each node in this list of arcs has a pointer to its destination vertex

* Suitable for sparse graphs

* A directed path is a sequence of vertices (v0, v1, . . . , vk) * A directed cycle is a directed path such that the first and last vertices are the same. * A directed graph is acyclic if it does not contain any directed cycles
* Such that (vi, vi+1) is an arc

Directed Graphs Usage


* Directed graphs are often used to represent orderdependent tasks
* That is we cannot start a task before another task finishes

* We can model this task dependent constraint using arcs * An arc (i,j) means task j cannot start until task i is finished
i j Task j cannot start until task i is finished

* Clearly, for the system not to hang, the graph must be acyclic

Topological Sort Algorithm


* Topological sort is an algorithm for a directed acyclic graph * Linearly order the vertices so that the linear order respects the ordering relations implied by the arcs

* Observations
* Algorithm
1. 2.

* *

Starting point must have zero indegree If it doesnt exist, the graph would not be acyclic

3.

A vertex with zero indegree is a task that can start right away. So we can output it first in the linear order If a vertex i is output, then its outgoing arcs (i, j) are no longer useful, since tasks j does not need to wait for i anymore- so remove all is outgoing arcs With vertex i removed, the new graph is still a directed acyclic graph. So, repeat step 1-2 until no vertex is left.

Topological Sort

Find all starting points

Reduce indegree(w)

Place new start vertices on the Q

Example
0 1 2
6 2 7 8 5 9 3 8 9 2 5 1 4

Indegree
0 1 2 3 4 5 0 1 2 1 1 2

start

3 8

3 4 5

0 1

6
7

6
7 8 9

1
1 2 2

5 4

8 9

Q={0}

OUTPUT:

Indegree
0 1
6 2 7 8 5 9 3 8 9 2 5 1 4

0 1 2

0 1 -1 2

3 8

3
4

3
4 5 6 7 8

1
1 -1 2 1 1 2

5 6

-1

5 4

7 8

Dequeue 0 Q = { } -> remove 0s arcs adjust indegrees of neighbors


OUTPUT:

Decrement 0s neighbors

Indegree
0 1
6 2 7 8 5 9 3 8 9 2 5 1 4

0 1 2

0 0 2

3 8

3
4

3
4 5 6 7 8

1
0 2 0 1 2

5 6

5 4

7 8

Q = { 6, 1, 4 } Enqueue all starting points


OUTPUT: 0

Enqueue all new start points

Indegree
0 1
6 2 7 8 5 9 3 8 9 2 5 1 4

0 1 2 3 4 5 6 7

0 0 2 -1 1 -1 0 2 0 1

3 8 2 7 9

2 3 4

5 6

5 4

8
9

8
9

2
2

Dequeue 6 Q = { 1, 4 } Remove arcs .. Adjust indegrees of neighbors


OUTPUT: 0 6

Adjust neighbors indegree

Indegree
0 1
6 2 7 8 5 9 3 8 9 2 5 1 4

0 1 2 3 4

0 0 1 0 0

3 8 2 7 9

2 3 4

5
6

5
6 7 8 9

2
0 1 2 2

5 4

7 8 9

Q = { 1, 4, 3 } Enqueue 3
OUTPUT: 0 6

Enqueue new start

Indegree
0 1
6 2 1 4

0 1

0 0 1

3 8 2 7 9

7
8 5 9

-1

3
4

3
4 5
2

0
0 2 0 1 2

5 6

3
8 9

6 7 8

7 8

Dequeue 1 Q = { 4, 3 } Adjust indegrees of neighbors OUTPUT: 0 6 1

Adjust neighbors of 1

Indegree
0 1
6 2 7 8 5 9 3 8 9 2 5 1 4

0 1

0 0

3 8 2 7 9

2
3 4 5 6

2
3 4 5 6 7

0
0 0 2 0 1

5 4

8
9

8
9

2
2

Dequeue 1 Q = { 4, 3, 2 } Enqueue 2

Enqueue new starting points

OUTPUT: 0 6 1

Indegree
0 1
6 2 7 8 5 9 3 8 9 2 5 1 4

0 1

0 0

3 8 2 7 9

2
3 4 5 6

2
3 4 5 6 7

0
0 0 2 0 1

-1

5 4

8
9

8
9

2
2

Dequeue 4 Q = { 3, 2 } Adjust indegrees of neighbors

Adjust 4s neighbors

OUTPUT: 0 6 1 4

Indegree
0 1
6 2 7 8 5 9 3 8 9 2 5 1 4

0 1 2 3 4 5 6 7

0 0 0 0 0 1 0 1

3 8 2 7 9

2 3 4 5 6

8
9

8
9

2
2

Dequeue 4 Q = { 3, 2 } No new start points found OUTPUT: 0 6 1 4

NO new start points

Indegree
0 1 2
6 2 7 8 5 9 3 8 9 2 5 1 4

0 1 2 3 4 5

0 0 0 0 0 1

3 8 2 7 9

3 4 5

6
7

6
7 8 9

0
1 2 2

8 9

-1

Dequeue 3 Q = { 2 } Adjust 3s neighbors

OUTPUT: 0 6 1 4 3

Indegree
0 1
6 2 7 8 5 9 3 8 9 2 5 1 4

0 1

0 0

2
3 4 5 6 7

0
0 0 1 0 1

8 2 7 9

3 4 5 6

8
9

8
9

1
2

Dequeue 3 Q = { 2 } No new start points found

OUTPUT: 0 6 1 4 3

Indegree
0 1 2
6 2 7 8 5 9 3 8 9 2 5 1 4

0 1 2

0 0 0

8 2 7 9

3
4 5 6

3
4 5 6 7 8

0
0 1 0 1 1

-1 -1

7 8

Dequeue 2 Q = { } Adjust 2s neighbors

OUTPUT: 0 6 1 4 3 2

Indegree
0 1 2
6 2 7 8 5 9 3 8 9 2 5 1 4

0 1 2

0 0 0

8 7 9

3
4 5 6

3
4 5 6 7 8

0
0 0 0 0 1

7 8

Dequeue 2 Q = { 5, 7 } Enqueue 5, 7

OUTPUT: 0 6 1 4 3 2

Indegree
0 1 2 3 4 5
6 2 7 8 5 9 3 8 9 2 5 1 4

0 1 2 3 4 5

0 0 0 0 0 0

8 7 9

6
7

6
7 8 9

0
0 1 2

8 9

-1

Dequeue 5 Q = { 7 } Adjust neighbors

OUTPUT: 0 6 1 4 3 2 5

Indegree
0 1 2 3 4 5
6 2 7 8 5 9 3 8 9 2 5 1 4

0 1 2 3 4 5

0 0 0 0 0 0

8 7 9

6
7 8 9

6
7 8 9

0
0 1 1

Dequeue 5 Q = { 7 } No new starts

OUTPUT: 0 6 1 4 3 2 5

Indegree
0 1 2 3 4 5
6 2 7 8 5 9 3 8 9 2 5 1 4

0 1 2 3 4 5

0 0 0 0 0 0

8 7 9

6
7 8 9

6
7 8 9

0
0 1 1

-1

Dequeue 7 Q = { } Adjust neighbors

OUTPUT: 0 6 1 4 3 2 5 7

Indegree
0 1 2 3 4 5
6 2 7 8 5 9 3 8 9 2 5 1 4

0 1 2 3 4 5

0 0 0 0 0 0

8 9

6
7 8 9

6
7 8 9

0
0 0 1

Dequeue 7 Q = { 8 } Enqueue 8

OUTPUT: 0 6 1 4 3 2 5 7

Indegree
0 1 2 3 4 5
6 2 7 8 5 9 3 8 9 2 5 1 4

0 1 2 3 4 5

0 0 0 0 0 0

8 9

6
7 8 9

6
7 8 9

0
0 0 1

-1

Dequeue 8 Q = { } Adjust indegrees of neighbors

OUTPUT: 0 6 1 4 3 2 5 7 8

Indegree
0 1
6 2 7 8 5 9 3 8 9 2 5 1 4

0 1

0 0

2
3 4

2
3 4 5 6 7

0
0 0 0 0 0

5 6 7

9 9 0 Dequeue 8 Q = { 9 } Enqueue 9 Dequeue 9 Q = { } STOP no neighbors OUTPUT: 0 6 1 4 3 2 5 7 8 9

3 8

0
1

OUTPUT: 0 6 1 4 3 2 5 7 8 9 Is output topologically correct?

Topological Sort: Complexity


We

never visited a vertex more than one time

For

each vertex, we had to examine all outgoing edges


outdegree(v) = m This is summed over all vertices, not per vertex

So,

our running time is exactly

O(n + m)

Weighted Graphs
* In many applications, each edge of a graph has an associated numerical value, called a weight. * Usually, the edge weights are nonnegative integers.

* Weighted graphs may be either directed or undirected


* If any edge has a negative weight then the shortest path between the vertices will be undefined and well get into the loop, this loop is known as negative cost loop

Graph Traversal
* Application example
* Given a graph representation and a vertex s in the graph * Find all paths from s to other vertices

* Two common graph traversal algorithms

Breadth-First Search (BFS) Find the shortest paths in an unweighted graph

Depth-First Search (DFS) Topological sort Find strongly connected components

Lets first look at BFS . . .

Breadth-First Search: Properties


BFS

calculates the shortest-path distance to the source node


Shortest-path distance (s,v) = minimum number of edges from s to v, or if v not reachable from s

BFS

builds breadth-first tree, in which paths to root represent shortest paths in G


Thus can use BFS to calculate shortest path from one vertex to another in O(V+E) time

BFS and Shortest Path Problem


Given any source vertex s, BFS visits the other vertices at increasing distances away from s. In doing so, BFS discovers paths from s to other vertices What do we mean by distance? The number of Example edges on a path from s. 0

8
2 1

Consider s=vertex 1
Nodes at distance 1? 2, 3, 7, 9 Nodes at distance 2? 8, 6, 5, 4 6
2

2 1 3

9 7
1

4
2

Nodes at distance 3? 0

BSF algorithm

Why use queue? Need FIFO

Example
0 8
source

Adjacency List

Visited Table (T/F)


0 1 2 3 4

F F F F F F

2
1 3 7

6
7 8

F
F F F

5
Initialize visited table (all False) Q= { }

Initialize Q to be empty

Example
0 8
source

Adjacency List

Visited Table (T/F)


0 1 2 3 4

F F T F F F

2
1 3 7

6
7 8

F
F F F

5
Flag that 2 has been visited. Q= { 2 } Place source 2 on the queue.

Example
0 8
source Neighbors

Adjacency List

Visited Table (T/F)


0 1 2 3 4

F T T F T F

2
1 3 7

6
7 8

F
F T F

5
Mark neighbors as visited. Q = {2} { 8, 1, 4 } Dequeue 2. Place all unvisited neighbors of 2 on the queue

Example
0 8
source

Adjacency List

Visited Table (T/F)


0 1 2 3 4

T T T F T F

2
1 3 7

6
7

F
F T T

Neighbors

8 9

5
Mark new visited Neighbors. Q = { 8, 1, 4 } { 1, 4, 0, 9 } Dequeue 8. -- Place all unvisited neighbors of 8 on the queue. -- Notice that 2 is not placed on the queue again, it has been visited!

Example
0 8
source Neighbors

Adjacency List

Visited Table (T/F)


0 1 2 3 4

T T T T T F

2
1 3 7

6
7 8

F
T T T

5
Mark new visited Neighbors. Q = { 1, 4, 0, 9 } { 4, 0, 9, 3, 7 } Dequeue 1. -- Place all unvisited neighbors of 1 on the queue. -- Only nodes 3 and 7 havent been visited yet.

Example
0 8
source

Adjacency List

Visited Table (T/F)


0 1 2 3 4

T T T T T F

2
1 3 7

Neighbors
5

6
7 8

F
T T T

Q = { 4, 0, 9, 3, 7 } { 0, 9, 3, 7 } Dequeue 4. -- 4 has no unvisited neighbors!

Example
Neighbors

Adjacency List

Visited Table (T/F)


0

T T T T T F

0 8
source

1 2 3 4

2
1 3 7

6
7 8

F
T T T

Q = { 0, 9, 3, 7 } { 9, 3, 7 } Dequeue 0. -- 0 has no unvisited neighbors!

Example
0 8
source

Adjacency List

Visited Table (T/F)


0 1 2 3 4

T T T T T F

2
1 3 7

6
7 8

F
T T T

6 Neighbors

Q = { 9, 3, 7 } { 3, 7 } Dequeue 9. -- 9 has no unvisited neighbors!

Example
0 8
source Neighbors

Adjacency List

Visited Table (T/F)


0 1 2 3 4

T T T T T T

2
1 3 7

6
7 8

F
T T T

5
Mark new visited Vertex 5. Q = { 3, 7 } { 7, 5 } Dequeue 3. -- place neighbor 5 on the queue.

Example
0 8
source

Adjacency List

Visited Table (T/F)


0 1 2 3 4

T T T T T T

2
1

9
Neighbors

6
7 8

T
T T T

3 4

7 6

5
Mark new visited Vertex 6. Q = { 7, 5 } { 5, 6 } Dequeue 7. -- place neighbor 6 on the queue.

Example
0 8
source

Adjacency List

Visited Table (T/F)


0 1 2 3 4

T T T T T T

2
1 3 7

Neighbors

6
7 8

T
T T T

Q = { 5, 6} { 6 } Dequeue 5. -- no unvisited neighbors of 5.

Example
0 8
source

Adjacency List

Visited Table (T/F)


0 1 2 3 4

T T T T T T T

2
1 3 7

9
Neighbors

5 6

T
T T

8 9

Q= {6}{ } Dequeue 6. -- no unvisited neighbors of 6.

Example
0 8
source

Adjacency List

Visited Table (T/F)


0 1 2 3 4

T T T T T T

2
1 3 7

6
7 8

T
T T T

Q= { }

STOP!!! Q is empty!!!

There exists a path from source vertex 2 to all vertices in the graph.

Shortest Path Recording

BFS we saw only tells us whether a path exists from source s, to other vertices v.

It doesnt tell us the path! We need to modify the algorithm to record the path.

How can we do that?


Note: we do not know which vertices lie on this path until we reach v! Efficient solution:
Use

an additional array pred[0..n-1] Pred[w] = v means that vertex w was visited from v

BFS + Path Finding

initialize all pred[v] to -1

Record where you came from

Example
0 8
source

Adjacency List

Visited Table (T/F)


0 1 2 3 4

F F F F F F

2
1 3 7

6
7 8

F
F F F

Pred Initialize visited table (all False)

Q= {

Initialize Pred to -1

Initialize Q to be empty

Example
0 8
source

Adjacency List

Visited Table (T/F)


0 1 2 3 4

F F T F F F

2
1 3 7

6
7 8

F
F F F

5
Flag that 2 has been visited. Q= { 2 } Place source 2 on the queue.

Pred

Example
0 8
source Neighbors

Adjacency List

Visited Table (T/F)


0 1 2 3 4

F T T F T F

2 2 -

2
1 3 7

6
7 8

F
F T F

2 -

Pred Mark neighbors as visited. Record in Pred that we came from 2.

Q = {2} { 8, 1, 4 } Dequeue 2. Place all unvisited neighbors of 2 on the queue

Example
0 8
source

Adjacency List

Visited Table (T/F)


0 1 2 3 4

T T T F T F

8 2 2 -

2
1 3 7

6
7

F
F T T

2 8

Neighbors

8 9

Pred Mark new visited Neighbors. Record in Pred that we came from 8.

Q = { 8, 1, 4 } { 1, 4, 0, 9 }

Dequeue 8. -- Place all unvisited neighbors of 8 on the queue. -- Notice that 2 is not placed on the queue again, it has been visited!

Example
0 8
source Neighbors

Adjacency List

Visited Table (T/F)


0 1 2 3 4

T T T T T F

2 1 2 -

2
1 3 7

6
7 8

F
T T T

1
2 8

Pred Mark new visited Neighbors. Record in Pred that we came from 1.

Q = { 1, 4, 0, 9 } { 4, 0, 9, 3, 7 } Dequeue 1. -- Place all unvisited neighbors of 1 on the queue. -- Only nodes 3 and 7 havent been visited yet.

Example
0 8
Neighbors source

Adjacency List

Visited Table (T/F)


0 1 2 3 4 5

T T T T T F

8 2 1 2 -

2
1 3 7

6
7 8

F
T T T

1 2 8

Pred

Q = { 4, 0, 9, 3, 7 } { 0, 9, 3, 7 } Dequeue 4. -- 4 has no unvisited neighbors!

Example
Neighbors

Adjacency List

Visited Table (T/F)


0

T T T T T F

8 2 1 2 -

0 8
source

1 2 3 4

2
1 3 7

6
7 8

F
T T T

1 2 8

Pred

Q = { 0, 9, 3, 7 } { 9, 3, 7 } Dequeue 0. -- 0 has no unvisited neighbors!

Example
0 8
source

Adjacency List

Visited Table (T/F)


0 1 2 3 4

T T T T T F

8 2 1 2 -

2
1 3 7

6
7 8

F
T T T

1 2 8

6 Neighbors

Pred

Q = { 9, 3, 7 } { 3, 7 } Dequeue 9. -- 9 has no unvisited neighbors!

Example
0 8
Neighbors source

Adjacency List

Visited Table (T/F)


0 1 2 3 4

T T T T T T

2
1 2 3 -

2
1 3 7

6
7 8

F
T T T

1
2 8

Pred Mark new visited Vertex 5. Record in Pred that we came from 3.

Q = { 3, 7 } { 7, 5 } Dequeue 3. -- place neighbor 5 on the queue.

Example
0 8
source

Adjacency List

Visited Table (T/F)


0 1 2 3 4

T T T T T T

8 2 1 2 3

2
1 3 7

9
Neighbors

6
7 8

T
T T T

7
1 2 8

Pred Mark new visited Vertex 6. Record in Pred that we came from 7.

Q = { 7, 5 } { 5, 6 } Dequeue 7. -- place neighbor 6 on the queue.

Example
0 8
source

Adjacency List

Visited Table (T/F)


0 1 2 3 4

T T T T T T

8 2 1 2 3

2
1 3 7

Neighbors

6
7 8

T
T T T

7
1 2 8

Pred

Q = { 5, 6} { 6 } Dequeue 5. -- no unvisited neighbors of 5.

Example
0 8
source

Adjacency List

Visited Table (T/F)


0 1 2 3 4

T T T T T T

8 2 1 2 3

2
1 3 7

9
Neighbors

6
7 8

T
T T T

7
1 2 8

Pred

Q= {6}{ } Dequeue 6. -- no unvisited neighbors of 6.

Example
0 8
source

Adjacency List

Visited Table (T/F)


0 1 2 3 4

T T T T T T

8 2 1 2 3

2
1 3 7

6
7 8

T
T T T

7
1 2 8

Pred

Q= { }

STOP!!! Q is empty!!!

Pred now can be traced backward to report the path!

How do we record the shortest distances?


d(v) = ; d(s) = 0;

d(w)=d(v)+1;

Application of BFS

One application concerns how to find connected components in a graph If a graph has more than one connected components, BFS builds a BFS-forest (not just BFS-tree)!

Each tree in the forest is a connected component.

Depth-First Search (DFS)

DFS is another popular graph search strategy

Idea is similar to pre-order traversal (visit children first)

DFS can provide certain information about the graph that BFS cannot

It can tell whether we have encountered a cycle or not

Depth-First Search
Depth-first

search is another strategy for exploring a

graph
Explore deeper in the graph whenever possible Edges are explored out of the most recently discovered vertex v that still has unexplored edges When all of vs edges have been explored, backtrack to the vertex from which v was discovered

DFS

will continue to visit neighbors in a recursive pattern


Whenever we visit v from u, we recursively visit all unvisited neighbors of v. Then we backtrack (return) to u.

DFS Algorithm
Flag all vertices as not visited

Flag yourself as visited For unvisited neighbors, call RDFS(w) recursively

We can also record the paths using pred[ ].

Example
Adjacency List Visited Table (T/F)
0

0 8
source

F F F F F F

1 2

3 4 5

1
3 4 5

7
6

6
7 8 9

F
F F F

Pred Initialize visited table (all False) Initialize Pred to -1

Example
Adjacency List 0 8
source

Visited Table (T/F)


0 1 2 3

F F T F F F

2 1 3 7

4 5

F
F F F

6 5

7 8 9

Pred Mark 2 as visited

RDFS( 2 ) Now visit RDFS(8)

Example
0
8
source

Adjacency List

Visited Table (T/F)


0 1 2

F F T F F F

3 4 5

1
3 4 5 7 6

6
7 8 9

F
F T F

2 -

Pred Mark 8 as visited


Recursive calls

RDFS( 2 ) RDFS(8) 2 is already visited, so visit RDFS(0)

mark Pred[8]

Example
0
8
source

Adjacency List

Visited Table (T/F)


0 1 2

T F T F F F

8 -

3 4 5

1
3 4 5 7 6

6
7 8 9

F
F T F

2 -

Pred Mark 0 as visited


Recursive calls

RDFS( 2 ) RDFS(8) RDFS(0) -> no unvisited neighbors, return to call RDFS(8)

Mark Pred[0]

Example
0
source

Back to 8 8

Adjacency List

Visited Table (T/F)


0 1 2

T F T F F F

8 -

3 4 5

1
3 4 5 7 6

6
7 8 9

F
F T F

2 -

Pred
Recursive calls

RDFS( 2 ) RDFS(8) Now visit 9 -> RDFS(9)

Example
0
8
source

Adjacency List

Visited Table (T/F)


0 1 2

T F T F F F

8 -

3 4 5

1
3 4 5 7 6

6
7 8 9

F
F T T

2 8

Pred Mark 9 as visited


Recursive calls

RDFS( 2 ) RDFS(8) RDFS(9) -> visit 1, RDFS(1)

Mark Pred[9]

Example
0
8
source

Adjacency List

Visited Table (T/F)


0 1 2

T T T F F F

8 9 -

3 4 5

1
3 4 5 7 6

6
7 8 9

F
F T T

2 8

Pred Mark 1 as visited


Recursive calls

RDFS( 2 ) RDFS(8) RDFS(9) RDFS(1) visit RDFS(3)

Mark Pred[1]

Example
0
8
source

Adjacency List

Visited Table (T/F)


0 1 2

T T T T F F

8 9 1 -

3 4 5

1
3 4 5 7 6

6
7 8 9

F
F T T

2 8

Pred Mark 3 as visited


Recursive calls

RDFS( 2 ) RDFS(8) RDFS(9) RDFS(1) RDFS(3) visit RDFS(4)

Mark Pred[3]

Example
0
8
source

Adjacency List

Visited Table (T/F)


0 1 2

T T T T T F

8 9 1 3 -

3 4 5

1
3 4 5 7 6

6
7 8 9

F
F T T

2 8

Pred
Recursive calls

RDFS( 2 ) Mark 4 as visited RDFS(8) RDFS(9) Mark Pred[4] RDFS(1) RDFS(3) RDFS(4) STOP all of 4s neighbors have been visited return back to call RDFS(3)

Example
0
8
source

Adjacency List

Visited Table (T/F)


0 1 2

T T T T T F

8 9 1 3 -

3 4 5

1
3 4 Back to 3 RDFS( 2 ) RDFS(8) RDFS(9) RDFS(1) RDFS(3) visit 5 -> RDFS(5) 5 7 6

6
7 8 9

F
F T T

2 8

Pred
Recursive calls

Example
0
8
source

Adjacency List

Visited Table (T/F)


0 1 2

T T T T T T

8 9 1 3 3

3 4 5

1
3 4 5 7 6

6
7 8 9

F
F T T

2 8

Pred
Recursive calls

RDFS( 2 ) RDFS(8) Mark 5 as visited RDFS(9) Mark Pred[5] RDFS(1) RDFS(3) RDFS(5) 3 is already visited, so visit 6 -> RDFS(6)

Example
0
8
source

Adjacency List

Visited Table (T/F)


0 1 2

T T T T T T

8 9 1 3 3

3 4 5

1
3 4 5 7 6

6
7 8 9

T
F T T

5
2 8

Recursive calls

RDFS( 2 ) RDFS(8) RDFS(9) RDFS(1) RDFS(3) RDFS(5) RDFS(6) visit 7 -> RDFS(7)

Pred

Mark 6 as visited
Mark Pred[6]

Example
0
8
source

Adjacency List

Visited Table (T/F)


0 1 2

T T T T T T

8 9 1 3 3

3 4 5

1
3 4 5 7 6

6
7 8 9

T
T T T

5
6 2 8

Recursive calls

Pred RDFS( 2 ) RDFS(8) Mark 7 as visited RDFS(9) RDFS(1) Mark Pred[7] RDFS(3) RDFS(5) RDFS(6) RDFS(7) -> Stop no more unvisited neighbors

Example
Adjacency List 0 Visited Table (T/F)
0

T T T T T T

8 9 1 3 3

8
source

1 2

2 1 3

4 5

7
6 5

6
7 8 9

T
T T T

5
6 2 8

Recursive calls

RDFS( 2 ) RDFS(8) RDFS(9) RDFS(1) RDFS(3) RDFS(5) RDFS(6) -> Stop

Pred

Example
Adjacency List 0 Visited Table (T/F)
0

T T T T T T

8 9 1 3 3

8
source

1 2

2 1 3

4 5

7
6 5

6
7 8 9

T
T T T

5
6 2 8

Recursive calls

RDFS( 2 ) RDFS(8) RDFS(9) RDFS(1) RDFS(3) RDFS(5) -> Stop

Pred

Example
Adjacency List 0 Visited Table (T/F)
0

T T T T T T

8 9 1 3 3

8
source

1 2

2 1 3

4 5

7
6 5

6
7 8 9

T
T T T

5
6 2 8

Recursive calls

RDFS( 2 ) RDFS(8) RDFS(9) RDFS(1) RDFS(3) -> Stop

Pred

Example
Adjacency List 0 Visited Table (T/F)
0

T T T T T T

8 9 1 3 3

8
source

1 2

2 1 3

4 5

7
6 5

6
7 8 9

T
T T T

5
6 2 8

Recursive calls

RDFS( 2 ) RDFS(8) RDFS(9) RDFS(1) -> Stop

Pred

Example
Adjacency List 0 Visited Table (T/F)
0

T T T T T T

8 9 1 3 3

8
source

1 2

2 1 3

4 5

7
6 5

6
7 8 9

T
T T T

5
6 2 8

Recursive calls

RDFS( 2 ) RDFS(8) RDFS(9) -> Stop

Pred

Example
Adjacency List 0 Visited Table (T/F)
0

T T T T T T

8 9 1 3 3

8
source

1 2

2 1 3

4 5

7
6 5

6
7 8 9

T
T T T

5
6 2 8

RDFS( 2 ) RDFS(8) -> Stop


Recursive calls

Pred

Example
Adjacency List 0 Visited Table (T/F)
0

T T T T T T

8 9 1 3 3

8
source

1 2

2 1 3

4 5

7
6 5

6
7 8 9

T
T T T

5
6 2 8

RDFS( 2 ) -> Stop


Recursive calls

Pred

Example
0 8
source

Adjacency List

Visited Table (T/F)


0 1

T T T T T T

8 9 1 3 3

2 1 3 7

2 3 4 5

6 5

6
7 8 9

T
T T T

5
6 2 8

Check our paths, does DFS find valid paths? Yes. Try some examples. Path(0) -> Path(6) -> Path(7) ->

Pred

Time Complexity of DFS


(Using adjacency list)

We never visited a vertex more than once We had to examine all edges of the vertices

We know vertex v degree(v) = 2m where m is the number of edges

So, the running time of DFS is proportional to the number of edges and number of vertices (same as BFS)

O(n + m)

You will also see this written as:

O(|v|+|e|)

|v| = number of vertices (n) |e| = number of edges (m)

Greedy Algorithms
Suppose your task is to optimize something, and you write an algorithm that proceeds in steps to solve this task. Each step you have a decision to make on how to proceed in the algorithm. A greedy algorithm is one where you make the decision that would appear to be the best for eventually optimizing the problem.

Example
For

the shortest-path graph problem, we actually used a greedy algorithm. This was Dijkstras algorithm. Greedy algorithms are common in graph problems. Greedy algorithms may not always work, because although the greedy approach might be best in the short term, it might not be best in the long term (when you finally reach the conclusion of the algorithm). For example, Dijkstras algorithm can fail if any edge cost is negative.

Network Flow Problems


Consider the graph G to be a network, and the costs on edges to be flow capacities. We have two special vertices: a source s and a sink t. At the other vertices the flow coming in must equal the flow going out. Maximum flow problem: find the maximum amount of flow that can pass from s to t.

Network Flow Applications


We

could be representing the amount of water than can flow through a network of pipes each pipe may have a different capacity. Or, this could be a network of streets and each street can handle a different number of vehicles.

Example
s s

3
a 1

2
b 2 4 2 c a

3 0

2 b

3
c 2

2
1 d 2 t

d 3

The left graph shows the capacity of the edges, while the right graph shows the maximum flow through this network. How do we obtain this? With a greedy algorithm!

Maximum Flow Algorithm


We

use three graphs, the original graph G, a flow graph Gf and a residual graph Gr = G Gf . We proceed in stages. Each stage we choose a path in Gr from s to t. The minimum edge on this path is the amount of flow that can be added to every edge on that path. An augmenting path is a directed path from the source to the sink in the residual network such that every arc on this path has positive residual capacity.
We

do this by adjusting Gf and recomputing Gr . We continue until there are no paths from s to t. We cant follow any edges that have capacity 0.

Example
s 3 a 3 c 2 t 3 2 0 b 2 4 0 c 0 t 0 a s 0 3 b 0 0 3 c 2 t 3 a s 2

b 2

The left graph shows the capacity of the edges, the middle graph shows the flow graph and the right graph is the residual graph.

Example
s 3 a 3 c 2 t 3 2 0 b 2 4 0 c 0 t 2 a s 2 3 b 2 0 3 c 2 t 1 a s 0

b 0

Let us first choose the path (s, b, d, t) on the residual graph. The minimum flow along that path is 2. We update the flow graph and recompute the residual graph.

Example
s 3 a 3 c 2 t 3 2 2 b 2 4 2 c 2 t 2 a s 2 1 b 2 0 1 c 0 t 1 a s 0

b 0

Now lets choose the path (s, a, c, t) on the residual graph. The minimum flow along that path is 2. We update the flow graph and recompute the residual graph.

Example
s 3 a 3 c 2 t 3 2 3 b 2 4 2 c 2 t 3 a s 2 0 b 2 1 1 c 0 t 0 a s 0

b 0

Now lets choose the path (s, a, d, t) on the residual graph. The minimum flow along that path is 1. We update the flow graph and recompute the residual graph. There are no paths left, so we are done.

Discussion
In the prior example we in fact obtained the maximum flow. If we choose a greedy algorithm, wed be tempted to choose paths that allows the maximum amount of flow to be added at each step. This might not work. For example, lets choose (s, a, d, t) first, because this allows 3 units of flow to be added.

Example
s 3 a 3 c 2 t 3 2 3 b 2 4 0 c 0 t 3 a s 0 0 b 0 3 3 c 2 t 0 a s 2

b 2

There are no paths from s to t in the residual graph, so we are done, but we have not obtained the maximum possible flow.

A Better Algorithm
We

can make the algorithm work by allowing the algorithm to change its mind. In effect we allow the algorithm to undo its decisions by sending flow back in the opposite direction. This is best seen by example. We have to modify the residual graph.

Example
s 3 a 3 c 2 t 3 2 3 b 2 4 0 c 0 t 3 a s 0 0 3 b 0 3 3 1 c 2 t 3 0 a s 2

1
3

b 2

We again choose the path (s, a, d, t). But note we now allow the flow to backup in the residual graph.

Example
s 3 a 3 c 2 t 3 2 3 b 2 4 2 c 2 t 3 a s 2 0 3 b 2 1 1 c 2 0 t 3 0 a 2 3 s 2 0 b 2 0

1
1

We can now follow the path (s, b, d, a, c, t). The minimum flow along this path is 2. Note the flow from d to a is now 1 = 3 2. We are done. This is the maximum flow solution.

Conclusions
This

better greedy algorithm will always find the maximum flow solution if the edge capacities are rational numbers. Although we have used an acyclic graph in the example, the algorithm works on arbitrary graphs!

Minimum-Cost Spanning Tree


weighted

connected undirected graph cost of spanning tree is sum of edge costs The minimum spanning tree (MST) of a graph defines the cheapest subset of edges that keeps the graph in one connected component. Telephone companies are particularly interested in minimum spanning trees, because the minimum spanning tree of a set of sites defines the wiring scheme that connects the sites using as little wire as possible. It is the mother of all network design problems.

Spanning Tree
A

spanning tree of G is a subgraph which


is a tree contains all vertices of G

Minimum Spanning Trees


Undirected, connected graph G = (V,E) Weight function W: E R (assigning cost or length or other values to edges)

Minimum spanning tree: tree that connects all the vertices and minimizes

w(T )

(u ,v )T

w(u, v)

Example
1
2 7 8

3
4

10 12

5
6

14

7 3 8

2
Network

has 10 edges. Spanning tree has only n - 1 = 7 edges. Need to either select 7 edges or discard 3.

Edge Selection Greedy Strategies


Start

with an n-vertex 0-edge forest. Consider edges in ascending order of cost. Select edge if it does not form a cycle together with already selected edges.

Kruskals method.

Start

with a 1-vertex tree and grow it into an n-vertex tree by repeatedly adding a vertex and an edge. When there is a choice, add a least cost edge.

Prims method.

Kruskals Method
1
2 7 9 8 4

10 12

5
6

14

7
3

Start

with a forest that has no edges.

Consider edges in ascending order of cost. Edge (1,2) is considered first and added to the forest.

Kruskals Method
1
2 7 9 8 4

3 4

10 12

5
6

14

7
3

1
2 7

3
4

5 6 6

7
3

Edge

(7,8) is considered next and added.

Edge (3,4) is considered next and added. Edge (5,6) is considered next and added. Edge (2,3) is considered next and added. Edge (1,3) is considered next and rejected because it creates a cycle.

Kruskals Method
1
2 7 9 8 4

3 4

10 12

5
6

14

7
3

1
2 7

3
4

10

5
6

14

7
3

Edge

(2,4) is considered next and rejected because it creates a cycle.

Edge (3,5) is considered next and added. Edge (3,6) is considered next and rejected. Edge (5,7) is considered next and added.

Kruskals Method
1
2 2 7 9 8 4 4

10

5 12 6
6

14

7 3
8

1 2 2 7

10

4
4

5 6 6

14

7 3 8

- 1 edges have been selected and no cycle formed. So we must have a spanning tree. Cost is 46. Min-cost spanning tree is unique when all edge costs are different.

Prims Method
1
2 7 9 8 4

3 4

10 12

5
6

14

7
3 2

1 7 2

10

4
4

5 6 6

14

7 3 8

Start

with any single vertex tree.

Get a 2-vertex tree by adding a cheapest edge. Get a 3-vertex tree by adding a cheapest edge. Grow the tree one edge at a time until the tree has n - 1 edges (and hence has all n vertices).

Euler Circuits
Euler circuit, which must end on its starting vertex, is possible only if the graph is connected and each vertex has a even degree. If any vertex has odd degree, then we will reach the point where only one edge into v is unvisited. If exactly 2 vertices have odd degree all the edges will be visited but it will not return to its starting vertex. If more than 2 vertices have odd degree, then an Euler tour is not possible.

NP-complete problem
A problem is called NP (nondeterministic polynomial) if its solution (if one exists) can be guessed and verified in polynomial time. Nondeterministic means that no particular rule is followed to make the guess. If a problem is NP and all other NP problems are polynomialtime reducible to it, the problem is NP-complete. Thus, finding an efficient algorithm for any NP-complete problem implies that an efficient algorithm can be found for all such problems. When an NP-complete problem must be solved, one approach is to use a polynomial algorithm to approximate the solution; the answer thus obtained will not necessarily be optimal but will be reasonably close.

S-ar putea să vă placă și