You are on page 1of 5

ADA Assignment 2

NAME: Mudit Garg

Roll Number: 2016057

Group members​: Vaasu Gupta (2016275), Ayushman Pandita (2016026)

A1)
Consider a graph G = (V , E ) . we claim that after the execution of BFS algorithm on
graph G starting from a source vertex s, distance[v] = δ min (v, s) ∀ v ∈ V , where
distance[v] is the distance of vertex v from s calculated by the BFS algorithm and
δ min (v, s) is the minimum distance between v and s in graph G.

PROOF BY CONTRADICTION:
Assumption​: ∃u ∈ V such that distance[u] =/ δ min (u, s). Consider the vertex u which has
the smallest distance [δ min (u, s)] among all vertices where distance[u] =/ δ min (u, s) . Since
δ min (u, s) is the minimum distance, therefore distance[u] > δ min (u, s) . Now, vertex u must
be reachable from s, because if it’s not true then distance[u] > δ min (u, s) = ∞ will not hold.
Let w be the predecessor of u along the shortest path from s to u.
⇒ δ min (u, s) = δ min (w, s) + 1 . By way using which we have selected u we know that
distance[w] = δ min (w, s) . because if the above statement won’t be true then, w would be
the vertex with smallest distance whose minimum distance has been wrongly calculated
by BFS algorithm.
From all the highlighted equations we can see that
distance[u] > δ min (u, s) = δ min (w, s) + 1 = distance[w] + 1
That is
distance[u] > distance[w] + 1
Now, we consider the scenario when w is being popped from the queue in the BFS
algorithm. There are three possibilities for u

Case 1 ( u has not been pushed into the queue):


In this case, the algorithm will push all the neighbours of w into the queue and update
their distance to distance[v] = distance[w] + 1 . Since, u ∈ neighbours(w)
⇒ distance[u] = distance[w] + 1
Case 2 ( u is currently in the queue):
This means that u was put into the queue using vertex v which was popped earlier than
w from the queue. Also, distance[v] ≤ distance[w] and the algorithm would have have
updated u’s distance to distance[u] = distance[v] + 1 .
⇒ distance[u] ≤ distance[w] + 1

Case 3 ( u has already been popped out of the queue):


If this is the case then distance[u] ≤ distance[w] < distance[w] + 1
⇒ distance[u] < distance[w] + 1

We can see that all of the above cases contradict the fact that
distance[u] > distance[w] + 1
This contradiction has arrived due to our ​Assumption​: ∃u ∈ V such that
distance[u] =/ δ min (u, s).
Therefore, we can conclude that distance[u] = δ min (u, s) ∀ u ∈ V

A2)
The idea is to consider the board as a directed graph where each cell is connected to
next 6 cells via 6 different directed edges and if there is a ladder then it it connects the
lower cell to the upper cell via a directed edge with its tail at lower cell. Similar is the
case for snakes, if there is a snake with its head at cell v and tail at cell u, then there will
be a directed edge from v to u.
Next we use a version of BFS algorithm to find the minimum number of dice rolls
required to reach end vertex. The algorithm works in a following way. If we are at a
vertex ​v​, then we know that it will have ​next 6 vertices​ as its neighbours. However, if it
has a ​ladder​ or a ​snake​ then we are forced to take the corresponding thing. However if
we take either of them, the ​number of dice rolls required to reach the vertex at the
other side​ does not change. We also maintain a minDistance array, which records the
minimum dice role required to reach each vertex. If there is an alternative path that
reaches the vertex in less dice roles, then we update the minimum distance entry of that
vertex.

class vertex(object): 
def __init__(self, vertexNumber = 0, minDiceRoll = 0): 
self.vertexNumber = vertexNumber 
self.minDiceRoll = minDiceRoll 
 
def getMinDiceRolls(board, N): 
startingVertex = vertex(1,0) 
queue = [] 
queue.append(startingVertex) 
minDistance = [1000] * (N+1) 
minDistance[1] = 0 
while queue: 
v = queue.pop(0) 
elif board[v.vertexNumber] > 0 and v.minDiceRoll < 
minDistance[board[v.vertexNumber]]: 
minDistance[board[v.vertexNumber]] = v.minDiceRoll 
nextVertex = vertex(board[v.vertexNumber], v.minDiceRoll) 
queue.append(nextVertex) 
else: 
for i in range(v.vertexNumber+1, v.vertexNumber+7): 
if i<=N: 
if v.minDiceRoll+1 < minDistance[i]: 
minDistance[i] = v.minDiceRoll+1; 
nextVertex = vertex(i, v.minDiceRoll+1) 
queue.append(nextVertex) 
return minDistance[N] 

The above code finds out the minimum dice rolls required to reach the N​th​ cell in a
Snakes and Ladders Game. The input to the function getMinDiceRolls(board, N) is
board ​and​ N​. ​Board ​is a ​vector of length​ ​N​, such that the value at an ​ith​
​ ​position is
equal to the end of the ladder or the snake if any of the above is present at the ​ith​ ​ ​cell
else it is a ​0​.
For Example according to the diagram in question, its equivalent ​board​ vector is a s
follows:
N = 100
board = [0] * (N+1)
# Marking all the eight snakes
board[1] = 38
board[4] = 14
board[9] = 31
board[21] = 42
board[28] = 84
board[51] = 67
board[72] = 91
board[80] = 99
# Marking all the eight ladders
board[98] = 79
board[95] = 75
board[93] = 73
board[87] = 36
board[64] = 60
board[62] = 19
board[54] = 34
board[17] = 7

Now executing ​getMinDiceRolls(board, N) ​will return the minimum number of dice rolls
that is required to reach cell 100 from cell 1, which in the above case is ​6​.

PROOF OF CORRECTNESS:
Since the graph is connected and a BFS algorithm visits every node in a graph, thus, the
algorithm will reach the N​th​ node at least once in its complete execution. Therefore, the
algorithm will terminate. The algorithm always finds the shortest path from the first vertex
to the last one. Since there can be many paths between two vertices, the algorithm
considers the minimum distance required to visit that node. Therefore, it will always find
the minimum distance b/w two nodes. Since each edge counts for one dice throw (
except the edge for ladder and snake ), the algorithm finds the minimum dice rolls
required to reach the end node.

TIME COMPLEXITY:
The running time of a BFS algorithm is Θ(V + E ) . Now, in the graph for the board we
have N nodes, thus there are N vertices
⇒V =N
Also, each node is connected to at most 6 other nodes. The ladders and snake are not
counted since they do not contribute in a dice roll.
⇒ E = 6N
⇒ C omplexity = Θ(V + E ) = Θ(N + 6N ) = Θ(7N ) = Θ(N )

A3)
Working code written in python is given below:

def func(adjacency_matrix, change_colour, vertex, rows, columns): 


vertex_colour = adjacency_matrix[vertex[0]][vertex[1]] 
if(vertex_colour!=change_colour): 
row = vertex[0] 
column = vertex[1] 
print(row, column) 
adjacency_matrix[row][column] = change_colour 
if row+1<rows and adjacency_matrix[row+1][column]==vertex_colour: 
func(adjacency_matrix, change_colour, [row+1, column], rows, 
columns) 
if row-1>0 and adjacency_matrix[row-1][column]==vertex_colour: 
func(adjacency_matrix, change_colour, [row-1, column], rows, 
columns) 
if column+1<columns and 
adjacency_matrix[row][column+1]==vertex_colour: 
func(adjacency_matrix, change_colour, [row, column+1], rows, 
columns) 
if column-1<columns and 
adjacency_matrix[row][column-1]==vertex_colour: 
func(adjacency_matrix, change_colour, [row, column-1], rows, 
columns) 
 
If the current vertex has the same colour as the colour to be changed, then there would
be no apparent changes to the matrix, that is, the colour of each cell would remain same,
thus there would be no effective changes, and therefore the algorithm does not execute.
If the color is different, then the algorithm changes the color of the current vertex and
repeat the process for vertex at its right, left, bottom, top, if any of the above exist.

PROOF OF CORRECTNESS:
Since there are finite number of vertices and at max all the vertices would be required to
be changed, therefore the algorithm terminates after a finite number of steps. The
algorithm changes the color of the vertices at all the 4 sides only if their color match the
color of current vertex, thus every path beginning from the current vertex and having
color sae as the current vertex will have all its nodes updated to new color.

TIME COMPLEXITY:
In the worst case scenario, the color of each vertex would have to be changed, and
since we are guaranteed that the algorithm won’t track back to the vertex already
changed ( because if a vertex has already been changed then its color would match the
change_color and the algorithm won’t execute further ), the algorithm will terminate in
Θ(n) steps.

You might also like