Вы находитесь на странице: 1из 16

Chapter Three

Graph Algorithm

Introduction
The objective of this article is to provide a basic introduction about graphs and the commonly
used algorithms used for traversing the graph, BFS and DFS. Breadth First Search (BFS) and
Depth First Search (DFS) are the two popular algorithms. This chapter will help you to get
some basic understanding about what graphs are, how they are represented, graph traversals
using BFS and DFS and time/space complexity of each algorithm.

Graph Algorithms: We are now beginning a major new section of the course. We will be
discussing algorithms for both directed and undirected graphs. Intuitively, a graph is a
collection of vertices or nodes, connected by a collection of edges. Graphs are extremely
important because they are a very flexible mathematical model for many application
problems. Basically, any time you have a set of objects, and there is some “connection” or
“relationship” or “interaction” between pairs of objects, a graph is a good way to model this.
Examples of graphs in application include communication and transportation networks, VLSI
and other sorts of logic circuits, surface meshes used for shape description in computer-aided
design and geographic information systems ,precedence constraints in scheduling systems.
The list of application is almost too long to even consider enumerating it.
Most of the problems in computational graph theory that we will consider arise because they
are of importance to one or more of these application areas. Furthermore, many of these
problems form the basic building blocks from which more complex algorithms are then built.

Graph Background and Terminology


Informally, a graph is a diagram consisting of points, called vertices, joined together by lines,
called edges; each edge joins exactly two vertices. A graph G is a triple consisting of a vertex
set of V(G), an edge set E(G), and a relation that associates with each edge two vertices (not
necessarily distinct) called its endpoints.

Definition of Graph
A graph G = (V, E) consists of a (finite) set denoted by V, or by V(G) if one wishes to make
clear which graph is under consideration, and a collection of E, or E(G), of unordered pairs
{u, v} of distinct elements from V. Each element of V is called a vertex or a point or a node,
and each element of E is called an edge or a line or a link.

DBU Dep’t of CS Insructor G.Kedir Page 1


Formally, a graph G is an ordered pair of disjoint sets (V, E), where V is called the vertex or
node set, while set E is the edge set of graph G. Typically, it is assumed that self-loops (i.e.
edges of the form (u, u), for some u Î V) are not contained in a graph.

Directed and Undirected Graph


A graph G = (V, E) is directed if the edge set is composed of ordered vertex (node) pairs. A
graph is undirected if the edge set is composed of unordered vertex pair.

Graphs are good in modeling real world problems like representing cities which are
connected by roads and finding the paths between cities, modeling air traffic controller
system, etc. These kinds of problems are hard to represent using simple tree structures. The
following example shows a very simple graph:

In the above graph, A,B,C,D,E,F are called nodes and the connecting lines between these
nodes are called edges. The edges can be directed edges which are shown by arrows; they
can also be weighted edges in which some numbers are assigned to them. Hence, a graph
can be a directed/undirected and weighted/un-weighted graph. In this article, we will
discuss undirected and un-weighted graphs.

DBU Dep’t of CS Insructor G.Kedir Page 2


Every graph has two components, Nodes and Edges.

1. Nodes
A graph is a set of nodes and a set of edges that connect the nodes. Graphs are used to model
situations where each of the nodes in a graph must be visited, sometimes in a particular order,
and the goal is to find the most efficient way to “traverse” the graph. The elements of a graph
are called nodes, and the elements that are below a particular node are called the node’s
children. it is represented by Circle.

2. Edges
Edges represent the connection between nodes. There are two ways to represent edges.

Adjacency Matrix
It is a two dimensional array with Boolean flags. As an example, we can represent the edges
for the above graph using the following adjacency matrix.

In the given graph, A is connected with B, C and D nodes, so adjacency matrix will have 1s
in the ‘A’ row for the ‘B’, ‘C’ and ‘D’ column.
 The advantages of representing the edges using adjacency matrix are:
Simplicity in implementation as you need a 2-dimensional array
Creating edges/removing edges is also easy as you need to update the Booleans

 The drawbacks of using the adjacency matrix are:


Increased memory as you need to declare N*N matrix where N is the total number of nodes.
Redundancy of information, i.e. to represent an edge between A to B and B to A, it requires
to set two Boolean flag in an adjacency matrix.

DBU Dep’t of CS Insructor G.Kedir Page 3


Adjacency List
It is an array of linked list nodes. In other words, it is like a list whose elements are a linked
list. For the given graph example, the edges will be represented by the below adjacency
list:

Exercise 1 Represent the following graph edges using

1. Adjacency matrix and


2. adjacency List

A D

B C

DBU Dep’t of CS Insructor G.Kedir Page 4


Graph Traversal
The breadth first search (BFS) and the depth first search (DFS) are the two algorithms
used for traversing and searching a node in a graph. They can also be used to find out
whether a node is reachable from a given node or not.

Depth First Search (DFS)


The aim of DFS algorithm is to traverse the graph in such a way that it tries to go far from
the root node. Stack (LIFO) is used in the implementation of the depth first search. Let’s
see how depth first search works with respect to the following graph:

As stated before, in DFS, nodes are visited by going through the depth of the tree from the
starting node. If we do the depth first traversal of the above graph and print the visited
node, it will be “E F B C D A”. DFS visits the root node and then its children nodes until
it reaches the end node, i.e. E and F nodes, then moves up to the parent nodes.
Algorithmic Steps
Step 1: Push the root node in the Stack.
Step 2: Peek the node of the stack.
Step 3: If the node has unvisited child nodes, get the unvisited child node, mark it as
traversed and push it on stack.
Step 4: If the node does not have any unvisited child nodes, pop the node from the stack
Step 5: Loop step 2 until stack is empty.
.

DBU Dep’t of CS Insructor G.Kedir Page 5


Depth-First Search
s.marked = true;
Stack S = new Stack();
S.push(s);
while(! S.isempty()){
v = S.peek();
u = firstUnmarkedAdj(v);
if (u == null) S.pop();
else {
u.marked = true;
S.push(u);
}}

Complexity of depth-first search


 Each vertex is pushed on the stack and popped at most once.
 for every vertex we check what the next unvisited neighbour is. Implemented naively,
this would require traversing the adjacency list 1+2+...+n times (where n is the length of
the adjacency list), which is n(n+1). If we use firstUnmarkedAdj() method we only need
to traverse it once.
 This gives O(V+E).

Breadth First Search (BFS)


This is a very different approach for traversing the graph nodes. The aim of BFS algorithm is
to traverse the graph as close as possible to the root node. Queue (FIFO) is used in the
implementation of the breadth first search. Let’s see how BFS traversal works with
respect to the following graph:

DBU Dep’t of CS Insructor G.Kedir Page 6


If we do the breadth first traversal of the above graph and print the visited node as the output,
it will print the following output. “A B C D E F”. The BFS visits the nodes level by level,
so it will start with level 0 which is the root node, and then it moves to the next levels
which are B, C and D, then the last levels which are E and F.
Algorithmic Steps
Step 1: Push the root node in the Queue.
Step 2: Remove the node from the Queue.
Step 3: If the removed node has unvisited child nodes, mark them as visited and insert the
unvisited children in the queue.
Step 4: Loop until the queue is empty.

Breadth First Search


s.marked = true;
Queue Q = new Queue();
Q.enqueue(s);
while(! Q.isempty()) {
v = Q.dequeue();
u = firstUnmarkedAdj(v);
while (u != null){
u.marked = true;
Q.enqueue(u);
u = firstUnmarkedAdj(v);
}}

Complexity of breadth-first search


Assume an adjacency list representation, V is the number of vertices, E the number of edges.
Each vertex is enqueued and dequeued at most once.
Scanning for all adjacent vertices takes O(E) time, since sum of lengths of adjacency lists is
E.
Gives a O(V+E) time complexity.

Worst Case Time Complexity of BFS and DFS


In terms of the number of vertices V: two nested loops over V, hence O(V 2). More useful
complexity estimate is in terms of the number of edges. Usually, the number of edges is less
than V2.
Worst Case Space Complexity of BFS and DFS
Need a queue/stack of size |V| (the number of vertices). Space complexity O(V).

DBU Dep’t of CS Insructor G.Kedir Page 7


Spanning Tree
If G is a connected graph, the spanning tree in G is a subgraph of G which includes every
vertex of G and is also a tree.

Consider the following graph

The following are the three of its spanning trees:

DBU Dep’t of CS Insructor G.Kedir Page 8


Expensive!

Minimize the total length of wire connecting


the customers
Minimum Spanning Trees
Spanning trees
A spanning tree of a graph is just a subgraph that contains all the vertices and is a tree. A
graph may have many spanning trees; for instance the complete graph on four vertices

Ao-------------oB
D

B o-------------oC
Exercise
This graph have sixty spanning tree try it by yourself

Now suppose the edges of the graph have weights or lengths. The weight of a tree is just the
sum of weights of its edges. Obviously, different trees have different lengths.

DBU Dep’t of CS Insructor G.Kedir Page 9


Shortest Path Algorithms
Introduction

Dijkstra's algorithm, named after its discoverer, Dutch computer scientist Edsger Dijkstra, is
a greedy algorithm that solves the single-source shortest path problem for a directed
graph with non negative edge weights. For example, if the vertices (nodes) of the graph
represent cities and edge weights represent driving distances between pairs of cities
connected by a direct road, Dijkstra's algorithm can be used to find the shortest route
between two cities. Also, this algorithm can be used for shortest path to destination in
traffic network.
Using the Code

I will explain this algorithm over an example.

We are in A node and the problem is we must go other nodes with minimum cost. L[,] is our
distances between pairs of nodes array.
Collapse | Copy Code
int[,] L ={
{-1, 5, -1, -1, -1, 3, -1, -1},
{ 5, -1, 2, -1, -1, -1, 3, -1},
{-1, 2, -1, 6, -1, -1, -1, 10},
{-1, -1, 6, -1, 3, -1, -1, -1},
{-1, -1, -1, 3, -1, 8, -1, 5},
{ 3, -1, -1, -1, 8, -1, 7, -1},
{-1, 3, -1, -1, -1, 7, -1, 2},
{-1, -1, 10, -1, 5, -1, 2, -1}

DBU Dep’t of CS Insructor G.Kedir Page 10


};

D[] shows the cost array. We will write the shortest cost in D array. C[] shows our nodes.
Pseudocode
Collapse | Copy Code
function Dijkstra(L[1..n, 1..n]) : array [2..n]
array D[2..n]
set C
C <- {2, 3, 4, 5, 6, …, n}
for i <- 2 to n
D[i] <- L[1,i]
repeat n - 2 times
v <- C // minimum D[v] extract to C
v <- C - {v}
for each w in C do
D[w] <- min(D[w], D[v] + L[v,w])
return D

It is shown below how the algorithm steps are worked:

D[]-> -1, 5,-1,-1,-1, 3,-1,-1

C[]-> -1, 1, 2, 3, 4, 5, 6, 7

DBU Dep’t of CS Insructor G.Kedir Page 11


D[]-> -1, 5,-1,-1,11, 3,10,-1

C[]-> -1, 1, 2, 3, 4,-1, 6, 7

D[]-> -1, 5, 7,-1,11, 3, 8,-1

C[]-> -1,-1, 2, 3, 4,-1, 6, 7

DBU Dep’t of CS Insructor G.Kedir Page 12


D[]-> -1, 5, 7,13,11, 3, 8,17

C[]-> -1,-1,-1, 3, 4,-1, 6, 7

D[]-> -1, 5, 7,13,11, 3, 8,10

C[]-> -1,-1,-1, 3, 4,-1,-1, 7

DBU Dep’t of CS Insructor G.Kedir Page 13


D[]-> -1, 5, 7,13,11, 3, 8,10

C[]-> -1,-1,-1, 3, 4,-1,-1,-1

D[]-> -1, 5, 7,13,11, 3, 8, 8

C[]-> -1,-1,-1,-1,-1,-1,-1,-1

Using the Code


class Dijkstra
{
private int rank = 0;

DBU Dep’t of CS Insructor G.Kedir Page 14


private int[,] L;
private int[] C;
public int[] D;
private int trank = 0;
public Dijkstra(int paramRank,int [,]paramArray)
{
L = new int[paramRank, paramRank];
C = new int[paramRank];
D = new int[paramRank];
rank = paramRank;
for (int i = 0; i < rank; i++)
{
for (int j = 0; j < rank; j++) {
L[i, j] = paramArray[i, j];
}
}

for (int i = 0; i < rank; i++)


{
C[i] = i;
}
C[0] = -1;
for (int i = 1; i < rank; i++)
D[i] = L[0, i];
}
public void DijkstraSolving()
{
int minValue = Int32.MaxValue;
int minNode = 0;
for (int i = 0; i < rank; i++)
{
if (C[i] == -1)
continue;
if (D[i] > 0 && D[i] < minValue)
{
minValue = D[i];
minNode = i;
}
}
C[minNode] = -1;
for (int i = 0; i < rank; i++)
DBU Dep’t of CS Insructor G.Kedir Page 15
{
if (L[minNode, i] < 0)
continue;
if (D[i] < 0) {
D[i] = minValue + L[minNode, i];
continue;
}
if ((D[minNode] + L[minNode, i]) < D[i])
D[i] = minValue+ L[minNode, i];
}
}
public void Run()
{
for (trank = 1; trank >rank; trank++)
{
DijkstraSolving();
Console.WriteLine("iteration" + trank);
for (int i = 0; i < rank; i++)
Console.Write(D[i] + " ");
Console.WriteLine("");
for (int i = 0; i < rank; i++)
Console.Write(C[i] + " ");
Console.WriteLine("");
}
}
}

DBU Dep’t of CS Insructor G.Kedir Page 16

Вам также может понравиться