0% found this document useful (0 votes)
7 views

Assignment 4[1]

The document outlines two assignments for civil engineering and delivery coordination involving algorithms for constructing a minimum road network and finding the shortest delivery route, respectively. It includes detailed algorithms for Prim's and Kruskal's methods for Minimum Spanning Trees, along with source code and complexity analyses. The assignments emphasize constraints such as budget limitations and the need for efficient route planning.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views

Assignment 4[1]

The document outlines two assignments for civil engineering and delivery coordination involving algorithms for constructing a minimum road network and finding the shortest delivery route, respectively. It includes detailed algorithms for Prim's and Kruskal's methods for Minimum Spanning Trees, along with source code and complexity analyses. The assignments emphasize constraints such as budget limitations and the need for efficient route planning.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 18

ASSIGNMENT-4

A-4.1. Consider yourself as a civil engineer tasked with designing a low


budget road network to connect a set of cities within a region. Each city
represents a node in the network, and the roads connecting the cities
represent edges. Your objective is to develop an algorithm to construct the
minimum road network, ensuring that all cities are connected while
minimizing the total cost of road construction.

Constraints:
• Each city must be connected to the road network.
• The road network must form a tree structure without any cycles.
• The total cost of road construction must be minimized.
• The road construction budget is limited.
• The distances between cities represent the weights of the edges in the
graph.
A-4.2. You are a delivery coordinator for an e-commerce company,
responsible for dispatching packages to customers within a city. The city is
represented as a graph, where each intersection is a node, and each road
between intersections is an edge. Your task is to develop an algorithm to
find the shortest route for delivering all packages, starting from the
company's warehouse and returning to the warehouse after all deliveries are
made.

Constraints:
• The city graph is undirected and connected that is given above.
• Each intersection can have multiple outgoing roads leading to other
intersections.
• Each package has a specific delivery address (intersection).
• The delivery person begins at the warehouse and must return to the
warehouse after delivering all packages.
• The objective is to minimize the total distance travelled by the delivery
person.
• Only one package can be carried at a time.
• Each package must be delivered to its designated address.
A-4.1 Algorithm:

minKey Function
1. Set min to a very large number (INT_MAX):
• This is used to keep track of the smallest key value found so far.
2. Set min_index to -1:
• This will hold the index of the city with the smallest key value.
3. Loop through all vertices (cities) from 0 to V-1:
• for (int v = 0; v < V; v++)
4. Inside the loop, check:
• If mstSet[v] == 0 → the city is not yet included in MST
• AND key[v] < min → the key (distance) is smaller than the
current min
5. If both conditions are true:
• Update min = key[v]
• Update min_index = v
→ This means we found a better (closer) unconnected city.
6. After the loop ends, return min_index:
• This gives the index of the city that is closest and not yet
connected.

primMST Function
1. Create three arrays:
• parent[]: Keeps track of the parent city for each city in the MST.
• key[]: Stores the minimum cost to connect each city to the MST
(start with infinity for all cities).
• mstSet[]: Tracks which cities are already connected to the MST
(all false at the start).
2. Initialize the arrays:
• Set key[] for all cities to infinity (∞), except key[0] = 0 (since we
start from city 0).
• Set mstSet[] for all cities to false (no cities are connected at the
beginning).
• Set parent[0] = -1 (city 0 has no parent since it's the first city).
3. Repeat V-1 times (because we need to connect V-1 edges):
• Find the city with the smallest key that is not yet connected
using the minKey() function.
o u = minKey(key, mstSet)
• Mark the city as connected:
o mstSet[u] = true (Now city u is included in the MST).
4. Look at each neighboring city:
• For each city v:
o If there is a road between city u and v (graph[u][v] != 0),
and:
o City v is not connected (mstSet[v] == false), and
o The road between u and v is shorter than the current key
for city v (graph[u][v] < key[v]):
▪ Update parent[v] to city u (this means city v is now
connected to city u).
▪ Update key[v] to the cost of the road between u and
v.
5. After the loop ends (all cities are connected):
• Print the MST by looking at the parent[] array.
o Each parent[i] tells us which city is connected to city i in
the MST.
• Calculate the total weight of the MST:
o Sum up all the roads used (from graph[u][v]).
A-4.1 Source Code:
#include <stdio.h>
#include <limits.h>
#define V 8
int minKey(int key[], int mstSet[]) {
int min = INT_MAX, min_index;
for (int v = 0; v < V; v++)
if (!mstSet[v] && key[v] < min) min = key[v], min_index = v;
return min_index;
}
void primMST(int graph[V][V]) {
int parent[V], key[V], mstSet[V] = {0}, totalWeight = 0;
for (int i = 0; i < V; i++) key[i] = INT_MAX;
key[0] = 0, parent[0] = -1;

for (int count = 0; count < V - 1; count++) {


int u = minKey(key, mstSet);
mstSet[u] = 1;
for (int v = 0; v < V; v++)
if (graph[u][v] && !mstSet[v] && graph[u][v] < key[v])
parent[v] = u, key[v] = graph[u][v];
}
printf("Edge \tWeight\n");
for (int i = 1; i < V; i++) {
printf("C%d - C%d\t%d\n", parent[i] + 1, i + 1, graph[i][parent[i]]);
totalWeight += graph[i][parent[i]];
}
printf("Total Weight of MST: %d\n", totalWeight);
}
int main() {
int graph[V][V] = {
{0, 40, 60, 45, 0, 0, 0, 0},
{40, 0, 0, 30, 100, 0, 0, 0},
{60, 0, 0, 40, 0, 0, 80, 70},
{45, 30, 40, 0, 60, 0, 50, 0},
{0, 100, 0, 60, 0, 50, 30, 0},
{0, 0, 0, 0, 50, 0, 30, 70},
{0, 0, 80, 50, 30, 30, 0, 40},
{0, 0, 70, 0, 0, 70, 40, 0}
};
primMST(graph);
return 0;

primMST(graph);
return 0;
}
A-4.1 Input/Output:
A-4.1 Analysis:
1. Time Complexity Analysis:
•Finding the minimum key vertex (in minKey()):
• Scans all vertices to find the minimum key[v] not yet
included in MST.
• Time per call: O(V)
• Called V times → total: O(V²)
•Updating adjacent vertices in the main loop of primMST() :
• For each of the V vertices, the inner loop checks all V possible
adjacent vertices.
• In the worst case (dense graph), this results in O(V²) total
operations.

2. Space Complexity Analysis:


• Graph representation:
• The graph is stored as an adjacency matrix of size V×V
→ O(V²)
• Arrays:
• key[], parent[], and mstSet[] → each of size V → O(V)
• Overall Space Complexity: O(V²).
A-4.2 Algorithm:

Find Function

1. Check if i is its own parent:

• If yes, then i is the leader. Return i.

2. If not, it means i has a parent, so:

• Call FIND on i's parent to keep going up until you find the
leader.

• While you're doing this, update i's parent directly to the leader
(this is called path compression — it makes future lookups
faster).

3. Return the leader (main parent) you found

union_sets Function
1. Find roots of x and y:
• xroot = find(x)
• yroot = find(y)
• This gets the root representative of the sets that x and y belong
to.
2. Compare their ranks:
• IF rank[xroot] < rank[yroot]
• Attach the tree with smaller rank to the root of the larger
rank tree.
• This helps keep the tree shallow → faster future lookups.
3. Merge accordingly:
• If xroot's rank is less, attach it under yroot.
• If yroot's rank is less, attach it under xroot.
• If they are equal, attach one to the other and increase the
rank of the new root.
Merge Sort:

Merge Sort Function


3. Initial step:
• Call mergeSort(arr, 0, length - 1)
• You're telling the algorithm to sort the whole array.

4. Divide:
• If the array (or sub-array) has more than 1 element:
o Find the middle point: mid = (left + right) / 2
o Recursively call mergeSort() on the left half
o Recursively call mergeSort() on the **right half`
• Keep dividing until each part has only one element (which is
already "sorted").

5. Conquer (Merge):
• Once divided into single elements, start merging back:
• Compare elements from two parts.
• Put them together in sorted order.
• Use the merge() function to do this.

6. Repeat Until Sorted:


• Merge continues up the chain.
• Eventually, the entire array is merged and sorted.

Merge Function
1. Split the array into two halves:
• Left half: from left to mid
• Right half: from mid + 1 to right
2. Copy those two halves into two new temporary arrays: L[] and
R[].
3. Compare elements from both arrays:
• If L[i].weight is smaller or equal, take from L
• Otherwise, take from R
• Put the chosen element back into the main array arr[k]
4. Copy any leftovers from L[] or R[] into arr[].
kruskalMST Function
1. Create Edge List:
• Loop through the graph matrix.
• For every connection graph[i][j] that’s not 0, make an edge
(i, j, weight).
• Store all these edges in an edge_list[].

2. Initialize Disjoint Sets:


• For each vertex:
• Set its own parent (parent[i] = i)
• Set rank to 0 (used to keep tree flat in union-find)

3. Sort Edges:
• Sort all edges in increasing order of weight using
mergeSort().

4. Pick Edges for MST:


• Go through each edge in sorted order.
• For each edge:
o Use find(u) and find(v) to get the set leaders.
o If they are in different sets, they’re not yet connected:
• Add the edge to the MST.
• Join the sets using union_sets().
• Add the weight to mst_weight.
• Increase edge_count.

5. Stop When MST is Ready:


• Stop when edge_count == V - 1 (a tree with V vertices has
V-1 edges).

6. Print Result:
• Show the total weight of the Minimum Spanning Tree.
A-4.2 Source Code:

#include <stdio.h>
#include <limits.h>

#define V 8

typedef struct {
int src, dest, weight;
} Edge;

int parent[V], rank[V];

int find(int i) {
if (parent[i] == i) return i;
return parent[i] = find(parent[i]);
}
void union_sets(int x, int y) {
int xroot = find(x);
int yroot = find(y);
if (rank[xroot] < rank[yroot]) parent[xroot] = yroot;
else if (rank[xroot] > rank[yroot]) parent[yroot] = xroot;
else {
parent[yroot] = xroot;
rank[xroot]++;
}
}
void merge(Edge arr[], int left, int mid, int right) {
int n1 = mid - left + 1;
int n2 = right - mid;
Edge L[n1], R[n2];

for (int i = 0; i < n1; i++) L[i] = arr[left + i];


for (int i = 0; i < n2; i++) R[i] = arr[mid + 1 + i];

int i = 0, j = 0, k = left;
while (i < n1 && j < n2) {
if (L[i].weight <= R[j].weight) arr[k++] = L[i++];
else arr[k++] = R[j++];
}
while (i < n1) arr[k++] = L[i++];
while (j < n2) arr[k++] = R[j++];
}
void mergeSort(Edge arr[], int left, int right) {
if (left < right) {
int mid = left + (right - left) / 2;
mergeSort(arr, left, mid);
mergeSort(arr, mid + 1, right);
merge(arr, left, mid, right);
}
}
void kruskalMST(int graph[V][V]) {
Edge edges[V * (V - 1) / 2];
int e = 0;
for (int i = 0; i < V; i++)
for (int j = i + 1; j < V; j++)
if (graph[i][j] != 0) {
edges[e].src = i;
edges[e].dest = j;
edges[e].weight = graph[i][j];
e++;
}
for (int i = 0; i < V; i++) {
parent[i] = i;
rank[i] = 0;
}
mergeSort(edges, 0, e - 1);
printf("Sorted Edges by Weight:\n");
for (int i = 0; i < e; i++) {
printf("C%d - C%d\tWeight: %d\n", edges[i].src + 1, edges[i].dest + 1,
edges[i].weight);
}
int mst_weight = 0;
int edge_count = 0;
printf("\nEdges in MST (Path) and Weights:\n");
for (int i = 0; i < e; i++) {
int u = edges[i].src;
int v = edges[i].dest;
int set_u = find(u);
int set_v = find(v);
if (set_u != set_v) {
printf("C%d - C%d\tWeight: %d\n", u + 1, v + 1, edges[i].weight);
mst_weight += edges[i].weight;
union_sets(set_u, set_v);
edge_count++;
if (edge_count == V - 1) break;
}
}
printf("\nTotal Weight of MST: %d\n", mst_weight);
}
int main() {
int graph[V][V] = {
{0, 40, 60, 45, 0, 0, 0, 0},
{40, 0, 0, 30, 100, 0, 0, 0},
{60, 0, 0, 40, 0, 0, 80, 70},
{45, 30, 40, 0, 60, 0, 50, 0},
{0, 100, 0, 60, 0, 50, 30, 0},
{0, 0, 0, 0, 50, 0, 30, 70},
{0, 0, 80, 50, 30, 30, 0, 40},
{0, 0, 70, 0, 0, 70, 40, 0}
};
kruskalMST(graph);
return 0;
}
A-4.2 Input/Output:
A-4.2 Analysis:
1. Time Complexity Analysis:
• Collecting all the edges from the graph
o This checks all possible pairs of cities (nodes).
o Time: Takes about V² time if there are many roads (dense
graph).
• Sorting the edges by weight (distance or cost)
o Uses merge sort.
o Time: Takes E log E time, where E is the number of roads
(edges).
• Building the Minimum Spanning Tree (MST)
o Goes through the edges one by one, and checks if connecting
two cities forms a cycle or not.
o Time: Almost E time, but very fast because of how union-find
is used.
• Overall Time:
O(E log E)
This means, Sorting the edges is the slowest part, and that's what
mainly decides the total time.

2. Space Complexity Analysis:


• Stores all the edges → Takes E space
• Parent and rank arrays (used to check connections between
cities) → Takes V space
• Extra space used by merge sort → Also takes E space
• Overall Space:
O(E + V)
This means, It uses memory based on the number of cities and
roads.

You might also like