Skip to content

Commit c0fec8d

Browse files
authored
Add Optimal Job Scheduling (#3868)
1 parent 39df47b commit c0fec8d

File tree

2 files changed

+250
-0
lines changed

2 files changed

+250
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
package com.thealgorithms.dynamicprogramming;
2+
3+
/**
4+
* This class refers to the Optimal Job Scheduling problem with the following constrains:
5+
* - precedence relation between the processes
6+
* - machine pair dependent transportation delays
7+
*
8+
* https://en.wikipedia.org/wiki/Optimal_job_scheduling
9+
*
10+
11+
*/
12+
public class OptimalJobScheduling {
13+
14+
private final int numberProcesses;
15+
private final int numberMachines;
16+
private final int[][] Run;
17+
private final int[][] Transfer;
18+
private final int[][] Cost;
19+
20+
/**
21+
* Constructor of the class.
22+
* @param numberProcesses ,refers to the number of precedent processes(N)
23+
* @param numberMachines ,refers to the number of different machines in our disposal(M)
24+
* @param Run , N*M matrix refers to the cost of running each process to each machine
25+
* @param Transfer ,M*M symmetric matrix refers to the transportation delay for each pair of machines
26+
*/
27+
public OptimalJobScheduling(int numberProcesses, int numberMachines, int[][] Run, int[][] Transfer) {
28+
this.numberProcesses = numberProcesses;
29+
this.numberMachines = numberMachines;
30+
this.Run = Run;
31+
this.Transfer = Transfer;
32+
this.Cost = new int[numberProcesses][numberMachines];
33+
}
34+
35+
/**
36+
* Function which computes the cost of process scheduling to a number of VMs.
37+
*/
38+
public void execute(){
39+
this.calculateCost();
40+
this.showResults();
41+
}
42+
43+
/**
44+
* Function which computes the cost of running each Process to each and every Machine
45+
*/
46+
private void calculateCost(){
47+
48+
for (int i=0; i < numberProcesses; i++){ //for each Process
49+
50+
for (int j=0; j < numberMachines; j++) { //for each Machine
51+
52+
Cost[i][j] = runningCost(i, j);
53+
}
54+
}
55+
}
56+
57+
/**
58+
* Function which returns the minimum cost of running a certain Process to a certain Machine.In order for the Machine to execute the Process ,he requires the output
59+
* of the previously executed Process, which may have been executed to the same Machine or some other.If the previous Process has been executed to another Machine,we
60+
* have to transfer her result, which means extra cost for transferring the data from one Machine to another(if the previous Process has been executed to the same
61+
* Machine, there is no transport cost).
62+
*
63+
* @param process ,refers to the Process
64+
* @param machine ,refers to the Machine
65+
* @return the minimum cost of executing the process to the certain machine.
66+
*/
67+
private int runningCost(int process, int machine) {
68+
69+
if (process==0) //refers to the first process,which does not require for a previous one to have been executed
70+
return Run[process][machine];
71+
else {
72+
73+
int[] runningCosts = new int[numberMachines]; //stores the costs of executing our Process depending on the Machine the previous one was executed
74+
75+
for (int k=0; k < numberMachines; k++) //computes the cost of executing the previous process to each and every Machine
76+
runningCosts[k] = Cost[process-1][k] + Transfer[k][machine] + Run[process][machine]; //transferring the result to our Machine and executing the Process to our Machine
77+
78+
return findMin(runningCosts); //returns the minimum running cost
79+
}
80+
}
81+
82+
/**
83+
* Function used in order to return the minimum Cost.
84+
* @param cost ,an Array of size M which refers to the costs of executing a Process to each Machine
85+
* @return the minimum cost
86+
*/
87+
private int findMin(int[] cost) {
88+
89+
int min=0;
90+
91+
for (int i=1;i<cost.length;i++){
92+
93+
if (cost[i]<cost[min])
94+
min=i;
95+
}
96+
return cost[min];
97+
}
98+
99+
/**
100+
* Method used in order to present the overall costs.
101+
*/
102+
private void showResults(){
103+
104+
for (int i=0; i < numberProcesses; i++){
105+
106+
for (int j=0; j < numberMachines; j++) {
107+
System.out.print(Cost[i][j]);
108+
System.out.print(" ");
109+
}
110+
111+
System.out.println();
112+
}
113+
System.out.println();
114+
}
115+
116+
/**
117+
* Getter for the running Cost of i process on j machine.
118+
*/
119+
public int getCost(int process,int machine) {
120+
return Cost[process][machine];
121+
}
122+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
package com.thealgorithms.dynamicprogramming;
2+
3+
import org.junit.jupiter.api.Test;
4+
5+
import static org.junit.jupiter.api.Assertions.assertEquals;
6+
7+
/**
8+
9+
*/
10+
public class OptimalJobSchedulingTest {
11+
12+
@Test
13+
public void testOptimalJobScheduling1(){
14+
15+
int numberProcesses = 5;
16+
int numberMachines = 4;
17+
18+
int[][] Run = {
19+
{5, 1, 3, 2},
20+
{4, 2, 1, 3},
21+
{1, 5, 2, 1},
22+
{2, 3, 4, 2},
23+
{1, 1, 3, 1}};
24+
25+
int[][] Transfer = {
26+
{0, 1, 2, 4},
27+
{1, 0, 2, 3},
28+
{2, 2, 0, 1},
29+
{4, 3, 1, 0}};
30+
31+
OptimalJobScheduling opt = new OptimalJobScheduling(numberProcesses,numberMachines,Run,Transfer);
32+
33+
opt.execute();
34+
35+
36+
int[][] costs = {
37+
{5, 1, 3, 2},
38+
{6, 3, 4, 5},
39+
{5, 8, 6, 6},
40+
{7, 9, 10, 8},
41+
{8, 9, 12, 9}};
42+
43+
for (int i=0; i < numberProcesses; i++){
44+
45+
for (int j=0; j < numberMachines; j++){
46+
47+
assertEquals(costs[i][j],opt.getCost(i,j));
48+
}
49+
}
50+
}
51+
52+
@Test
53+
public void testOptimalJobScheduling2(){
54+
55+
int numberProcesses = 3;
56+
int numberMachines = 3;
57+
58+
int[][] Run = {
59+
{5, 1, 3},
60+
{4, 2, 1},
61+
{1, 5, 2}};
62+
63+
int[][] Transfer = {
64+
{0, 1, 2},
65+
{1, 0, 2},
66+
{2, 2, 0}};
67+
68+
OptimalJobScheduling opt = new OptimalJobScheduling(numberProcesses,numberMachines,Run,Transfer);
69+
70+
opt.execute();
71+
72+
int[][] costs = {
73+
{5, 1, 3},
74+
{6, 3, 4},
75+
{5, 8, 6}};
76+
77+
for (int i=0; i < numberProcesses; i++){
78+
79+
for (int j=0; j < numberMachines; j++){
80+
81+
assertEquals(costs[i][j],opt.getCost(i,j));
82+
}
83+
}
84+
}
85+
86+
@Test
87+
public void testOptimalJobScheduling3(){
88+
89+
int numberProcesses = 6;
90+
int numberMachines = 4;
91+
92+
int[][] Run = {
93+
{5, 1, 3, 2},
94+
{4, 2, 1, 1},
95+
{1, 5, 2, 6},
96+
{1, 1, 2, 3},
97+
{2, 1, 4, 6},
98+
{3, 2, 2, 3},
99+
};
100+
101+
int[][] Transfer = {
102+
{0, 1, 2, 1},
103+
{1, 0, 2, 3},
104+
{2, 2, 0, 2},
105+
{1, 3, 2, 0},
106+
};
107+
108+
OptimalJobScheduling opt = new OptimalJobScheduling(numberProcesses,numberMachines,Run,Transfer);
109+
110+
opt.execute();
111+
112+
int[][] costs = {
113+
{5, 1, 3, 2},
114+
{6, 3, 4, 3},
115+
{5, 8, 6, 9},
116+
{6, 7, 8, 9},
117+
{8, 8, 12, 13},
118+
{11, 10, 12, 12}};
119+
120+
for (int i=0; i < numberProcesses; i++){
121+
122+
for (int j=0; j < numberMachines; j++){
123+
124+
assertEquals(costs[i][j],opt.getCost(i,j));
125+
}
126+
}
127+
}
128+
}

0 commit comments

Comments
 (0)