Assignmentn
Assignmentn
(a) Firstly, we will sort the last k elements in O(k log k) time. Then we will apply binary search in the
first (n-k) elements to find the maximum value. In this way we will get 3 sorted subarrays. Now, to
check if any element is present in the array, we can compare the element to the range of the three
sorted subarrays and apply binary search on them.
PSEUDOCODE :
return mid;
else
return -1;
// now apply normal binary search to the 3 sorted subarrays to find if the element is present in the
array or not
Sorting the last k elements take O(k* log k) time. Finding the max element also eventually takes
O(log n) time. Now applying normal binary search also takes O(log n) time only. So for q queries, we
have O(k *log k + q *log n) time complexity.
Question 3
(a)
For a permutation of an array to have minimum cost, the elements in array must either
be sorted in increasing or decreasing order.
Proof: by Induction
Base Case : Consider the case of array containing only 2 elements. Then the elements
are either in increasing order or decreasing order.
Induction Step: Assume that the array of length n is in ascending order. Now we add one
more element to the array in such a way that the cost is minimised. Let the elements in
the array be a1,a2,...,an such that a1 < a2 < ··· < an. Let the new element to be added in the
array be an+1
Case : 1 There exist two elements ap,ap+1 in the array such that ap <
If k ≠ p then an+1 does not lie in between ak+1, ak then the sum abs(ak+1 an+1) + abs(ak an+1)
will be greater than ak+1ak and the newCost will be greater than prevCost.
If k = p, then the sum abs(ak+1 - an+1) + abs(ak - an+1) will be equal to ak+1 -ak and the
newCost will be equal to prevCost.
If the element is inserted at the beginning or at the end of the array, then the newCost
will have an additional term corresponding to abs(an+1 - a1 or an+1 - an along with
prevCost which is more than the case when an+1 is inserted between ap and ap+1.
Case2: an+1<a1
Now if we insert the new element between any elements ak, ak+1, then the
Clearly this way new cost is minimised.The above arguments can also be generalised for
decreasing arrays.
(b) Algorithm 3: Pseudo Code : Cost(mat[n][2]){
cost <-0
vis[n] <-0 (all elements initialized to 0) for(i=0 ; i<n ; i++){
if(vis[i]==0){
if(mat[i][1]==i) vis[i] 1
else{
sumchain <-0
vis[j] <-1
sumchain+=mat[j][0]
j <-mat[j][1]
minchain=min(minchain,mat[j][0])
}
cost+=(sumchain-minchain) }
return cost
}
main(){ arr[n]
mat1[n][2],mat2[n][2]
mat1[i][0]=arr[i]
mat2[i][0]=arr[i]
mat1[i][1]=i
mat2[i][1]=i
}
sort rows of mat1 in ascending order and mat2 in descending order based on first
elements
cost1 <-cost(mat1[n][2])
cost2 <-cost(mat2[n][2])
return min(cost1,cost2)
Description :
The above algorithim computes the chains(subarrays whose elements when rearranged
among themselves goes to their correct sorted positions. Among such chains the
minimum cost of rearranging occurs when we swap every el- ement other than the
minimum element with the minimum elements. Hence the cost of sorting the elements
in a chain is given by sumChain-minChain. In this way we calculate the costs for sorting
the elements in both ascending and descending order and output the minimum of the
costs.
Main( ) :
Cost( ) :
In this function, we keep track of all the vertices visited in process of identifying chains
using a checker array vis[n]. This ensures that each vertex is visited exactly once in
calculating the cost of individual chains. Hence this overall function calculates the cost
in O(n).
Hence the overall time complexity of the algorithm is O(n log n).
QUESTION 4
(a) To address the given issue, our initial step involves maintaining the graph as is, without
removing any edges. We then proceed to determine the shortest feasible path, denoted as
'p,' between nodes (s, t) within this graph. Subsequently, we set the value of M[u][v] to
represent the shortest distance between s and t for all pairs (u, v) belonging to the set E. It is
important to note that the values within all Muv cells will remain constant throughout the
edge deletion process for any edge (u, v) if it is not part of the path 'p.' However, for the
remaining cells, we must perform a Breadth-First Search anew, utilizing the adjacency list
starting from s. During this iteration, we will exclude traversing the link corresponding to the
given edge (u, v), assuming that deleting an edge is equivalent to removing its corresponding
link within the adjacency list.
Pseudocode:
// let there are n nodes numbered from 0 to n - 1, and the index of s(source) is 0
// initialize an array parent[n] storing parent nodes of all nodes from 0 to n - 1 in the shortest
path ‘p’
parent[n];
parent[0] = -1;
BFS(s, G):
dist[s] = 0;
enqueue(s, Q);
v = dequeue(Q);
if (dist[w] = infinity):
dist[w] = dist[v] + 1;
enqueue(w, Q);
parent[w] = v;
return dist[v];
Function PathFinder(v):
path = CreateEmptyList();
while v != -1:
path.insert(v);
v = par[v];
len = path.size();
return path
We start by creating a matrix, M[n][n], where each element is initially set to the distance
between s and t in the original graph. Next, we develop a new algorithm, NEW_BFS, which
closely resembles the original Breadth-First Search (BFS) algorithm. However, it includes two
additional inputs representing the vertices associated with the edge to be eliminated. During
the execution of NEW_BFS, if it detects that these vertices exist as an edge, it will
intentionally disregard them during the process.
Pseudocode:
• When the edge belongs to the path, NEW_BFS is performed, taking O(|V| + |E|) time. Since
the path from vertex s to vertex t can have at most (n - 1) vertices (where |V| = n), which occurs
atmost (n-1) times.
Initializing the matrix M[n][n] takes O(n2) time. Combining all cases, the worst case time complexity
of the algorithm is O(n * (n+m)).
(c) Proof of Correctness: The fact that BFS gives the shortest path between two nodes and its
correctness has been discussed in the lectures.
1. When an edge is not part of the path and is subsequently removed, it has no impact on the
shortest distance between s and t. The initial BFS guarantees that the path discovered from s to t is
indeed the shortest one possible. Therefore, eliminating an edge that lies outside this path does not
alter the shortest distance.
2. If an edge located on the path is removed, the algorithm executes an additional BFS, ensuring that
it accounts for the removal of this specific edge. The correctness of the BFS guarantees that the
resultant distance between s and t remains the shortest achievable distance.
To summarize, the algorithm adeptly manages both scenarios of edge removal, consistently
preserving the shortest distance between s and t.
Question 5
When we apply BFT on the graph given in the question, the distance of any node from s
cannot be more than 3k. And also there is an edge from every vertex at distance d to
every vertex at d+1.This means that we can traverse between any vertices u,v at
di↵erent distance from s by travelling a distance equal to dis(s,v)-dis(s,u). If two
vertices u,v are at same distance from s then v can be reached from u by travelling a
distance of 2 edges.(go to a common ancestor to both the vertices and come to v from it)
• Case 1: When the maximum distance of any node from s is greater than or equal to 2k,
then we choose our vertex t as any vertex at a distance of 2k from s.
• Case 2: When the maximum distance of any node from s is less than 2k, then we
choose t as any vertex that is at maximum distance from s.
Time Complexity :
The algorithm use BFT only once to calculate the distances of vertices from given vertex
s.While calculating the distances if the maximum distance to any vertex from s is equal
to 2k, then the function returns that vertex. If not the function returns the vertex that is
at maximum distance from s. Hence the overall time complexity of the algorithm will be
O(N+M), where N,M are the number of vertices and edges in the graph.
Proof of Correctness :
We Assume the correctness of BFT to prove this algorithm. We know that every vertex
is is reached in BFT from s in a connected graph. In the above algorithm when a
particular vertex is reached, its distance from s is checked. maxDis variable stores the
value of the maximum of all the distances from s and t stores the vertex that is at that
distance. If the maxDis exceeds 2k at any vertex w, then t is returned. If after travelling
all the vertices, the maxDis is less than 2k, then the vertex with maximum distance from
s, that is t is returned.The entire idea of correctness of the algorithm lies in the fact that
during BFT, all the vertices that are reachable from s are visited.
maxDis <-0
t<-s
createEmptyQueue(Q)
distance(s)<- 0
enQueue(s,Q)
while(! isEmptyQueue(Q)){
v <-deQueue(Q)
for(each neighbour w of v in G){
if(distance(w) <-infinite)
maxDis=distance(w)
t<-w
}
if(maxDis >=2k) return t
enQueue(w, Q)
}
}
}
return t }