710247. Minimum time taken by each job to be completed given by a Directed Acyclic Graph
Minimum time taken by each job to be completed given by a Directed Acyclic Graph
Summary
Given a directed acyclic graph (DAG) where each node represents a job and the edges represent the dependencies between jobs, find the minimum time taken by each job to be completed. The minimum time for a job is the maximum time it takes to complete all its dependent jobs.
Detailed Explanation
To solve this problem, we can use Topological Sorting (TS) algorithm. TS is an ordering of vertices in a directed acyclic graph such that for every edge (u,v), vertex u comes before v in the ordering.
Here's a step-by-step breakdown of the solution:
- Perform a DFS on the given DAG and keep track of the visited nodes.
- During the DFS, calculate the in-degree of each node (i.e., the number of edges pointing to it).
- Initialize an empty queue and add all nodes with zero in-degree to the queue.
- While the queue is not empty:
- Dequeue a node from the queue.
- For each neighbor of the dequeued node, decrement its in-degree by one.
- If the in-degree becomes zero for any neighbor, add it to the queue.
- The order in which nodes are dequeued from the queue is the topological sorting.
Now that we have the topological sorting, we can calculate the minimum time taken by each job as follows:
- Initialize a variable
minTimeto store the minimum time for each job. - For each node in the topological sorting:
- Calculate its minimum time by taking the maximum of its own processing time and the minimum times of all its dependent jobs.
- Update
minTimewith this calculated value.
The time complexity of this solution is O(V + E), where V is the number of nodes (jobs) and E is the number of edges (dependencies). The space complexity is O(V), as we need to store the visited nodes, in-degrees, and the queue.
Optimized Solutions
Java
import java.util.*;
class Job {
int id;
int processingTime;
List<Job> dependencies;
Job(int id, int processingTime) {
this.id = id;
this.processingTime = processingTime;
this.dependencies = new ArrayList<>();
}
}
public class Main {
public static void main(String[] args) {
// Create the DAG
Job job1 = new Job(1, 3);
Job job2 = new Job(2, 2);
Job job3 = new Job(3, 5);
Job job4 = new Job(4, 1);
Job job5 = new Job(5, 4);
job1.dependencies.add(job2);
job1.dependencies.add(job4);
job3.dependencies.add(job4);
job4.dependencies.add(job5);
// Perform Topological Sorting
List<Job> topologicalOrdering = new ArrayList<>();
Map<Job, Integer> inDegrees = new HashMap<>();
for (Job job : Arrays.asList(job1, job2, job3, job4, job5)) {
if (!inDegrees.containsKey(job)) {
inDegrees.put(job, 0);
}
for (Job dependency : job.dependencies) {
inDegrees.put(dependency, inDegrees.getOrDefault(dependency, 0) + 1);
}
}
Queue<Job> queue = new LinkedList<>();
for (Map.Entry<Job, Integer> entry : inDegrees.entrySet()) {
if (entry.getValue() == 0) {
queue.add(entry.getKey());
}
}
while (!queue.isEmpty()) {
Job job = queue.poll();
topologicalOrdering.add(job);
for (Job dependency : job.dependencies) {
inDegrees.put(dependency, inDegrees.get(dependency) - 1);
if (inDegrees.get(dependency) == 0) {
queue.add(dependency);
}
}
}
// Calculate the minimum time taken by each job
Map<Job, Integer> minTimes = new HashMap<>();
for (Job job : topologicalOrdering) {
int minTime = Math.max(job.processingTime, Collections.max(job.dependencies, Comparator.comparingInt(dependency -> dependency.processingTime).thenComparing(Int::intValue)).processingTime);
minTimes.put(job, minTime);
}
// Print the minimum time taken by each job
for (Map.Entry<Job, Integer> entry : minTimes.entrySet()) {
System.out.println("Job " + entry.getKey().id + ": " + entry.getValue());
}
}
}