logo

Zoek banen die betrokken zijn bij gewogen taakplanning

Gegeven N banen waarbij elke baan wordt weergegeven door drie elementen ervan te volgen.
1. Begintijd 
2. Eindtijd 
3. Winst of waarde verbonden
Vind de subgroep van banen geassocieerd met maximale winst, zodat geen twee banen in de subset elkaar overlappen.

Voorbeelden: 



  Input:    Number of Jobs n = 4 Job Details {Start Time Finish Time Profit} Job 1: {1 2 50} Job 2: {3 5 20} Job 3: {6 19 100} Job 4: {2 100 200}   Output:    Jobs involved in maximum profit are Job 1: {1 2 50} Job 4: {2 100 200}

In vorig post die we hebben besproken over het probleem van de gewogen taakplanning. Het bericht had echter alleen betrekking op code met betrekking tot het vinden van maximale winst. In dit bericht zullen we ook de banen afdrukken die betrokken zijn bij maximale winst.

Laat arr[0..n-1] de invoerarray van Jobs zijn. We definiëren een array DP[] zodanig dat DP[i] de betrokken Jobs opslaat om maximale winst uit array arr[0..i] te behalen. d.w.z. DP[i] slaat de oplossing op voor subprobleem arr[0..i]. De rest van het algoritme blijft hetzelfde als besproken in vorig na.

Hieronder vindt u de C++-implementatie:



CPP
// C++ program for weighted job scheduling using Dynamic // Programming and Binary Search #include    using namespace std; // A job has start time finish time and profit. struct Job {  int start finish profit; }; // to store subset of jobs struct weightedJob {  // vector of Jobs  vector<Job> job;  // find profit associated with included Jobs  int value; }; // A utility function that is used for sorting events // according to finish time bool jobComparator(Job s1 Job s2) {  return (s1.finish < s2.finish); } // A Binary Search based function to find the latest job // (before current job) that doesn't conflict with current // job. 'index' is index of the current job. This function // returns -1 if all jobs before index conflict with it. The // array jobs[] is sorted in increasing order of finish time int latestNonConflict(Job jobs[] int index) {  // Initialize 'lo' and 'hi' for Binary Search  int lo = 0 hi = index - 1;  // Perform binary Search iteratively  while (lo <= hi)  {  int mid = (lo + hi) / 2;  if (jobs[mid].finish <= jobs[index].start)  {  if (jobs[mid + 1].finish <= jobs[index].start)  lo = mid + 1;  else  return mid;  }  else  hi = mid - 1;  }  return -1; } // The main function that finds the subset of jobs // associated with maximum profit such that no two // jobs in the subset overlap. int findMaxProfit(Job arr[] int n) {  // Sort jobs according to finish time  sort(arr arr + n jobComparator);  // Create an array to store solutions of subproblems.  // DP[i] stores the Jobs involved and their total profit  // till arr[i] (including arr[i])  weightedJob DP[n];  // initialize DP[0] to arr[0]  DP[0].value = arr[0].profit;  DP[0].job.push_back(arr[0]);  // Fill entries in DP[] using recursive property  for (int i = 1; i < n; i++)  {  // Find profit including the current job  int inclProf = arr[i].profit;  int l = latestNonConflict(arr i);  if (l != - 1)  inclProf += DP[l].value;  // Store maximum of including and excluding  if (inclProf > DP[i - 1].value)  {  DP[i].value = inclProf;  // including previous jobs and current job  DP[i].job = DP[l].job;  DP[i].job.push_back(arr[i]);  }  else  // excluding the current job  DP[i] = DP[i - 1];  }  // DP[n - 1] stores the result  cout << 'Optimal Jobs for maximum profits aren' ;  for (int i=0; i<DP[n-1].job.size(); i++)  {  Job j = DP[n-1].job[i];  cout << '(' << j.start << ' ' << j.finish  << ' ' << j.profit << ')' << endl;  }  cout << 'nTotal Optimal profit is ' << DP[n - 1].value; } // Driver program int main() {  Job arr[] = {{3 5 20} {1 2 50} {6 19 100}  {2 100 200} };  int n = sizeof(arr)/sizeof(arr[0]);  findMaxProfit(arr n);  return 0; } 
Java
// Java program for weighted job scheduling using Dynamic // Programming and Binary Search import java.util.*; public class WeightedJobScheduling { // A job has start time finish time and profit. static class Job {  int start finish profit;  public Job(int start int finish int profit) {  this.start = start;  this.finish = finish;  this.profit = profit;  } } // to store subset of jobs static class weightedJob {  // vector of Jobs  List<Job> job;  // find profit associated with included Jobs  int value;  public weightedJob() {  job = new ArrayList<>();  } } // A utility function that is used for sorting events // according to finish time static class JobComparator implements Comparator<Job> {  @Override  public int compare(Job j1 Job j2) {  return j1.finish - j2.finish;  } } // A Binary Search based function to find the latest job // (before current job) that doesn't conflict with current // job. 'index' is index of the current job. This function // returns -1 if all jobs before index conflict with it. The // array jobs[] is sorted in increasing order of finish time static int latestNonConflict(Job[] jobs int index) {  // Initialize 'lo' and 'hi' for Binary Search  int lo = 0 hi = index - 1;  // Perform binary Search iteratively  while (lo <= hi) {  int mid = (lo + hi) / 2;  if (jobs[mid].finish <= jobs[index].start) {  if (jobs[mid + 1].finish <= jobs[index].start) {  lo = mid + 1;  } else {  return mid;  }  } else {  hi = mid - 1;  }  }  return -1; } // The main function that finds the subset of jobs // associated with maximum profit such that no two // jobs in the subset overlap. static int findMaxProfit(Job[] arr) {  // Sort jobs according to finish time  Arrays.sort(arr new JobComparator()); // Create an array to store solutions of subproblems.  // DP[i] stores the Jobs involved and their total profit  // till arr[i] (including arr[i])  weightedJob[] DP = new weightedJob[arr.length];  DP[0] = new weightedJob();  // initialize DP[0] to arr[0]  DP[0].value = arr[0].profit;  DP[0].job.add(arr[0]);  // Fill entries in DP[] using recursive property  for (int i = 1; i < arr.length; i++) {  // Find profit including the current job  int inclProf = arr[i].profit;  int l = latestNonConflict(arr i);  if (l != -1) {  inclProf += DP[l].value;  }  // Store maximum of including and excluding  if (inclProf > DP[i - 1].value) {  DP[i] = new weightedJob();  DP[i].value = inclProf;  DP[i].job.addAll(DP[l].job);  DP[i].job.add(arr[i]);  } else {    DP[i] = DP[i - 1];  }  }  // DP[n - 1] stores the result  System.out.println('Optimal Jobs for maximum profits are');  for (Job j : DP[arr.length - 1].job) {  System.out.println('(' + j.start + ' ' + j.finish + ' ' + j.profit + ')');  }  System.out.println('nTotal Optimal profit is ' + DP[arr.length - 1].value);  return DP[arr.length - 1].value; }   // Driver program public static void main(String[] args) {  Job[] arr = { new Job(3 5 20)   new Job(1 2 50)  new Job(6 19 100)   new Job(2 100 200) };  findMaxProfit(arr); } } // This code is contributed by ratiagrawal. 
Python3
from typing import List Tuple def find_max_profit(jobs: List[Tuple[int int int]]) -> int: n = len(jobs) # Sort the jobs in ascending order of their finish times jobs.sort(key=lambda x: x[1]) # Initialize DP array with the first job and its profit as the maximum profit DP = [{'value': jobs[0][2] 'jobs': [jobs[0]]}] # Iterate over the remaining jobs for i in range(1 n): # Find the index of the latest non-conflicting job l = latest_non_conflict(jobs i) # Calculate the profit that can be obtained by including the current job incl_prof = jobs[i][2] if l != -1: incl_prof += DP[l]['value'] # Update DP array with the maximum profit and set of jobs if incl_prof > DP[i - 1]['value']: DP.append({'value': incl_prof 'jobs': DP[l]['jobs'] + [jobs[i]]}) else: DP.append(DP[i - 1]) # Print the optimal set of jobs and the maximum profit obtained print('Optimal Jobs for maximum profits are') for j in DP[-1]['jobs']: print(f'({j[0]} {j[1]} {j[2]})') print(f'nTotal Optimal profit is {DP[-1]['value']}') def latest_non_conflict(jobs: List[Tuple[int int int]] index: int) -> int: lo hi = 0 index - 1 while lo <= hi: mid = (lo + hi) // 2 if jobs[mid][1] <= jobs[index][0]: if jobs[mid + 1][1] <= jobs[index][0]: lo = mid + 1 else: return mid else: hi = mid - 1 return -1 # Test the program with a different set of jobs jobs = [(3 5 20) (1 2 50) (6 19 100) (2 100 200)] find_max_profit(jobs) # This code is contributed by divyansh2212 
C#
using System; using System.Collections.Generic; public class WeightedJobScheduling  {  // A job has start time finish time and profit.  class Job {  public int start finish profit;  public Job(int start int finish int profit)  {  this.start = start;  this.finish = finish;  this.profit = profit;  }  }  // to store subset of jobs  class weightedJob   {  // vector of Jobs  public List<Job> job;  // find profit associated with included Jobs  public int value;  public weightedJob() { job = new List<Job>(); }  }  // A utility function that is used for sorting events  // according to finish time  class JobComparator : IComparer<Job> {  public int Compare(Job j1 Job j2)  {  return j1.finish - j2.finish;  }  }  // A Binary Search based function to find the latest job  // (before current job) that doesn't conflict with  // current job. 'index' is index of the current job.  // This function returns -1 if all jobs before index  // conflict with it. The array jobs[] is sorted in  // increasing order of finish time  static int latestNonConflict(Job[] jobs int index)  {  // Initialize 'lo' and 'hi' for Binary Search  int lo = 0 hi = index - 1;  // Perform binary Search iteratively  while (lo <= hi) {  int mid = (lo + hi) / 2;  if (jobs[mid].finish <= jobs[index].start) {  if (jobs[mid + 1].finish  <= jobs[index].start) {  lo = mid + 1;  }  else {  return mid;  }  }  else {  hi = mid - 1;  }  }  return -1;  }  // The main function that finds the subset of jobs  // associated with maximum profit such that no two  // jobs in the subset overlap.  static int findMaxProfit(Job[] arr)  {  // Sort jobs according to finish time  Array.Sort(arr new JobComparator());  // Create an array to store solutions of  // subproblems. DP[i] stores the Jobs involved and  // their total profit till arr[i] (including arr[i])  weightedJob[] DP = new weightedJob[arr.Length];  DP[0] = new weightedJob();  // initialize DP[0] to arr[0]  DP[0].value = arr[0].profit;  DP[0].job.Add(arr[0]);  // Fill entries in DP[] using recursive property  for (int i = 1; i < arr.Length; i++)   {  // Find profit including the current job  int inclProf = arr[i].profit;  int l = latestNonConflict(arr i);  if (l != -1) {  inclProf += DP[l].value;  }  // Store maximum of including and excluding  if (inclProf > DP[i - 1].value) {  DP[i] = new weightedJob();  DP[i].value = inclProf;  DP[i].job.AddRange(DP[l].job);  DP[i].job.Add(arr[i]);  }  else {  DP[i] = DP[i - 1];  }  }  // DP[n - 1] stores the result  Console.WriteLine(  'Optimal Jobs for maximum profits are');  foreach(Job j in DP[arr.Length - 1].job)  {  Console.WriteLine('(' + j.start + ' '  + j.finish + ' ' + j.profit  + ')');  }  Console.WriteLine('nTotal Optimal profit is '  + DP[arr.Length - 1].value);  return DP[arr.Length - 1].value;  }  // Driver program  static void Main(string[] args)  {  Job[] arr  = { new Job(3 5 20) new Job(1 2 50)  new Job(6 19 100) new Job(2 100 200) };  findMaxProfit(arr);  } } // This code is contributed by lokeshpotta20. 
JavaScript
const findMaxProfit = (jobs) => {  // Store the number of jobs  const n = jobs.length;  // Sort the jobs in ascending order of their finish times  jobs.sort((a b) => a[1] - b[1]);  // Initialize DP array with the first job and its profit as the maximum profit  let DP = [{ value: jobs[0][2] jobs: [jobs[0]] }];  // Iterate over the remaining jobs  for (let i = 1; i < n; i++) {  // Find the index of the latest non-conflicting job  const l = latestNonConflict(jobs i);  // Calculate the profit that can be obtained by including the current job  let inclProf = jobs[i][2];  if (l !== -1) {  inclProf += DP[l].value;  }  // Update DP array with the maximum profit and set of jobs  if (inclProf > DP[i - 1].value) {  DP.push({ value: inclProf jobs: DP[l].jobs.concat([jobs[i]]) });  } else {  DP.push(DP[i - 1]);  }  }  // Print the optimal set of jobs and the maximum profit obtained  console.log('Optimal Jobs for maximum profits are');  for (const j of DP[DP.length - 1].jobs) {  console.log(`(${j[0]} ${j[1]} ${j[2]})`);  }  console.log(`nTotal Optimal profit is ${DP[DP.length - 1].value}`); }; const latestNonConflict = (jobs index) => {  let lo = 0;  let hi = index - 1;  while (lo <= hi) {  const mid = Math.floor((lo + hi) / 2);  if (jobs[mid][1] <= jobs[index][0]) {  if (jobs[mid + 1][1] <= jobs[index][0]) {  lo = mid + 1;  } else {  return mid;  }  } else {  hi = mid - 1;  }  }  return -1; }; // Test the program with a different set of jobs const jobs = [[3 5 20] [1 2 50] [6 19 100] [2 100 200]]; findMaxProfit(jobs); // This code is contributed by unstoppablepandu. 

Uitvoer
Optimal Jobs for maximum profits are (1 2 50) (2 100 200) Total Optimal profit is 250

Tijdcomplexiteit: O(n logboek n)
Hulpruimte: Op)