# Job Sequencing Problem – Loss Minimization

Last Updated : 27 Mar, 2023

We are given N jobs numbered 1 to N. For each activity, let Ti denotes the number of days required to complete the job. For each day of delay before starting to work for job i, a loss of Li is incurred. We are required to find a sequence to complete the jobs so that overall loss is minimized. We can only work on one job at a time. If multiple such solutions are possible, then we are required to give the lexicographically least permutation (i.e earliest in dictionary order). Examples:

```Input : L = {3, 1, 2, 4} and
T = {4, 1000, 2, 5}
Output : 3, 4, 1, 2
Explanation: We should first complete
job 3, then jobs 4, 1, 2 respectively.

Input : L = {1, 2, 3, 5, 6}
T = {2, 4, 1, 3, 2}
Output : 3, 5, 4, 1, 2
Explanation: We should complete jobs
3, 5, 4, 1 and then 2 in this order.```

Let us consider two extreme cases and we shall deduce the general case solution from them.

1. All jobs take same time to finish, i.e Ti = k for all i. Since all jobs take same time to finish we should first select jobs which have large Loss (Li). We should select jobs which have the highest losses and finish them as early as possible. Thus this is a greedy algorithm. Sort the jobs in descending order based on Li only.
2. All jobs have the same penalty. Since all jobs have the same penalty we will do those jobs first which will take less amount of time to finish. This will minimize the total delay, and hence also the total loss incurred. This is also a greedy algorithm. Sort the jobs in ascending order based on Ti. Or we can also sort in descending order of 1/Ti.

From the above cases, we can easily see that we should sort the jobs not on the basis of Li or Ti alone. Instead, we should sort the jobs according to the ratio Li/Ti, in descending order.

We can get the lexicographically smallest permutation of jobs if we perform a stable sort on the jobs. An example of a stable sort is merge sort.

To get most accurate result avoid dividing Li by Ti. Instead, compare the two ratios like fractions. To compare a/b and c/d, compare ad and bc.

## C++

 `// CPP program to minimize loss using stable sort.` `#include ` `#include ` `#include ` `using` `namespace` `std;`   `#define all(c) c.begin(), c.end()`   `// Each job is represented as a pair of int and pair.` `// This is done to provide implementation simplicity` `// so that we can use functions provided by algorithm` `// header` `typedef` `pair<``int``, pair<``int``, ``int``> > job;`   `// compare function is given so that we can specify` `// how to compare a pair of jobs` `bool` `cmp_pair(job a, job b)` `{` `    ``int` `a_Li, a_Ti, b_Li, b_Ti;` `    ``a_Li = a.second.first;` `    ``a_Ti = a.second.second;` `    ``b_Li = b.second.first;` `    ``b_Ti = b.second.second;`   `    ``// To compare a/b and c/d, compare ad and bc` `    ``return` `(a_Li * b_Ti) > (b_Li * a_Ti);` `}`   `void` `printOptimal(``int` `L[], ``int` `T[], ``int` `N)` `{` `    ``vector list; ``// (Job Index, Si, Ti)`   `    ``for` `(``int` `i = 0; i < N; i++) {` `        ``int` `t = T[i];` `        ``int` `l = L[i];`   `        ``// Each element is: (Job Index, (Li, Ti) )` `        ``list.push_back(make_pair(i + 1, make_pair(l, t)));` `    ``}`   `    ``stable_sort(all(list), cmp_pair);`   `    ``// traverse the list and print job numbers` `    ``cout << ``"Job numbers in optimal sequence are\n"``;` `    ``for` `(``int` `i = 0; i < N; i++)` `        ``cout << list[i].first << ``" "``;`   `}`   `// Driver code` `int` `main()` `{` `    ``int` `L[] = { 1, 2, 3, 5, 6 };` `    ``int` `T[] = { 2, 4, 1, 3, 2 };` `    ``int` `N = ``sizeof``(L) / ``sizeof``(L[0]);` `    ``printOptimal(L, T, N);` `    ``return` `0;` `}`

## Java

 `//Java program to minimize loss using stable sort.`   `import` `java.io.*;` `import` `java.util.*;`   `class` `GFG {` `    `  `    ``// compare function is given so that we can specify` `    ``// how to compare a pair of jobs` `    ``public` `static` `class` `cmp_pair ``implements` `Comparator` `    ``{` `        ``@Override` `        ``public` `int` `compare(job a, job b){` `            ``int` `a_Li, a_Ti, b_Li, b_Ti;` `            ``a_Li = a.li;` `            ``a_Ti = a.ti;` `            ``b_Li = b.li;` `            ``b_Ti = b.ti;` `          `  `            ``// To compare a/b and c/d, compare ad and bc` `            ``return` `(a_Li * b_Ti) > (b_Li * a_Ti)?-``1``:``1``;` `        ``}` `    ``}` `    `  `    ``public` `static` `void` `printOptimal(``int` `L[], ``int` `T[], ``int` `N)` `    ``{` `        ``List list = ``new` `ArrayList<>(); ``// (Job Index, Si, Ti)` `      `  `        ``for` `(``int` `i = ``0``; i < N; i++) {` `            ``int` `t = T[i];` `            ``int` `l = L[i];` `      `  `            ``// Each element is: (Job Index, (Li, Ti) )` `            ``list.add(``new` `job(i + ``1``, l, t));` `        ``}` `      `  `        ``Collections.sort(list,``new` `cmp_pair());` `      `  `        ``// traverse the list and print job numbers` `        ``System.out.println(``"Job numbers in optimal sequence are"``);` `        ``for` `(``int` `i = ``0``; i < N; i++) ` `            ``System.out.print(list.get(i).index+``" "``);   ` `      `  `    ``}` `    `  `    ``public` `static` `void` `main (String[] args) {` `        ``int` `L[] = { ``1``, ``2``, ``3``, ``5``, ``6` `};` `        ``int` `T[] = { ``2``, ``4``, ``1``, ``3``, ``2` `};` `        ``int` `N = L.length;` `        ``printOptimal(L, T, N);` `    ``}` `}`   `// Each job is represented as a pair of int and pair.` `// This is done to provide implementation simplicity` `// so that we can use functions provided by algorithm` `// header` `class` `job{` `    ``int` `index,ti,li;` `    ``job(``int` `i,``int` `l, ``int` `t){` `        ``this``.index=i;` `        ``this``.ti=t;` `        ``this``.li=l;` `    ``}` `}`   `//This code is contributed by shruti456rawal`

## Python3

 `# Python program to minimize loss using stable sort.` `import` `functools` `import` `operator` `from` `typing ``import` `List`   `# compare function is given so that we can specify` `# how to compare a pair of jobs` `class` `cmp_pair:` `    ``def` `__call__(``self``, a, b):` `        ``a_Li, a_Ti, b_Li, b_Ti ``=` `a.li, a.ti, b.li, b.ti` `        `  `        ``# To compare a/b and c/d, compare ad and bc` `        ``return` `-``1` `if` `(a_Li ``*` `b_Ti) > (b_Li ``*` `a_Ti) ``else` `1`   `class` `job:` `    ``def` `__init__(``self``, i, l, t):` `        ``self``.index, ``self``.ti, ``self``.li ``=` `i, t, l`   `def` `printOptimal(L: ``List``[``int``], T: ``List``[``int``], N: ``int``) ``-``> ``None``:` `    ``job_list ``=` `[]` `    ``for` `i ``in` `range``(N):` `        ``t, l ``=` `T[i], L[i]` `        `  `        ``# Each element is: (Job Index, (Li, Ti) )` `        ``job_list.append(job(i ``+` `1``, l, t))` `    ``job_list.sort(key``=``functools.cmp_to_key(cmp_pair()))` `    `  `    ``# traverse the list and print job numbers` `    ``print``(``"Job numbers in optimal sequence are"``)` `    ``for` `i ``in` `range``(N):` `        ``print``(job_list[i].index, end``=``" "``)`   `L ``=` `[``1``, ``2``, ``3``, ``5``, ``6``]` `T ``=` `[``2``, ``4``, ``1``, ``3``, ``2``]` `N ``=` `len``(L)` `printOptimal(L, T, N)`   `# This code is contributed by Prince`

## Javascript

 `// JavaScript program for the above approach `   `function` `cmp_pair(a, b) {` `  ``const a_Li = a.li, a_Ti = a.ti, b_Li = b.li, b_Ti = b.ti;` `  `  `  ``// To compare a/b and c/d, compare ad and bc` `  ``return` `(a_Li * b_Ti) > (b_Li * a_Ti) ? -1 : 1;` `}`   `class job {` `  ``constructor(i, l, t) {` `    ``this``.index = i;` `    ``this``.ti = t;` `    ``this``.li = l;` `  ``}` `}`   `function` `printOptimal(L, T, N) {` `  ``const job_list = [];` `  ``for` `(let i = 0; i < N; i++) {` `    ``const t = T[i], l = L[i];` `    `  `    ``// Each element is: (Job Index, (Li, Ti) )` `    ``job_list.push(``new` `job(i + 1, l, t));` `  ``}` `  ``job_list.sort(cmp_pair);` `  `  `  ``// traverse the list and print job numbers` `  ``console.log(``"Job numbers in optimal sequence are"``);` `  ``for` `(let i = 0; i < N; i++) {` `    ``process.stdout.write(job_list[i].index + ``" "``);` `  ``}` `}`   `const L = [1, 2, 3, 5, 6];` `const T = [2, 4, 1, 3, 2];` `const N = L.length;` `printOptimal(L, T, N);`   `// This code is contributed by adityashatmfh`

## C#

 `
``//C# program to minimize loss using stable sort.

using System;
using System.Collections.Generic;

public class GFG {

// compare function is given so that we can specify
// how to compare a pair of jobs
public class Cmp_pair : IComparer{
public int Compare(job a, job b){
int a_Li, a_Ti, b_Li, b_Ti;
a_Li = a.li;
a_Ti = a.ti;
b_Li = b.li;
b_Ti = b.ti;

// To compare a/b and c/d, compare ad and bc
return (a_Li * b_Ti) > (b_Li * a_Ti)?-1:1;
}
}

public static void printOptimal(int[] L, int[] T, int N)
{
List list = new List(); // (Job Index, Si, Ti)

for (int i = 0; i < N; i++) {
int t = T[i];
int l = L[i];

// Each element is: (Job Index, (Li, Ti) )
list.Add(new job(i + 1, l, t));
}

list.Sort(new Cmp_pair());

// traverse the list and print job numbers
Console.WriteLine("Job numbers in optimal sequence are");
foreach(job j in list)
Console.Write(j.index+" ");

}

public static void Main () {
int[] L = { 1, 2, 3, 5, 6 };
int[] T = { 2, 4, 1, 3, 2 };
int N = L.Length;
printOptimal(L, T, N);
}
}

// Each job is represented as a pair of int and pair.
// This is done to provide implementation simplicity
// so that we can use functions provided by algorithm
public class job{
public int index,ti,li;
public job(int i,int l, int t){
this.index=i;
this.ti=t;
this.li=l;
}
}
`

Output

```Job numbers in optimal sequence are
3 5 4 1 2 ```

Time Complexity: O(N log N)
Space Complexity: O(N)

Previous
Next