Skip to content

Initial commit #3868

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package com.thealgorithms.dynamicprogramming;

/**
* This class refers to the Optimal Job Scheduling problem with the following constrains:
* - precedence relation between the processes
* - machine pair dependent transportation delays
*
* https://en.wikipedia.org/wiki/Optimal_job_scheduling
*
* @author [email protected]
*/
public class OptimalJobScheduling {

private final int numberProcesses;
private final int numberMachines;
private final int[][] Run;
private final int[][] Transfer;
private final int[][] Cost;

/**
* Constructor of the class.
* @param numberProcesses ,refers to the number of precedent processes(N)
* @param numberMachines ,refers to the number of different machines in our disposal(M)
* @param Run , N*M matrix refers to the cost of running each process to each machine
* @param Transfer ,M*M symmetric matrix refers to the transportation delay for each pair of machines
*/
public OptimalJobScheduling(int numberProcesses, int numberMachines, int[][] Run, int[][] Transfer) {
this.numberProcesses = numberProcesses;
this.numberMachines = numberMachines;
this.Run = Run;
this.Transfer = Transfer;
this.Cost = new int[numberProcesses][numberMachines];
}

/**
* Function which computes the cost of process scheduling to a number of VMs.
*/
public void execute(){
this.calculateCost();
this.showResults();
}

/**
* Function which computes the cost of running each Process to each and every Machine
*/
private void calculateCost(){

for (int i=0; i < numberProcesses; i++){ //for each Process

for (int j=0; j < numberMachines; j++) { //for each Machine

Cost[i][j] = runningCost(i, j);
}
}
}

/**
* 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
* 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
* 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
* Machine, there is no transport cost).
*
* @param process ,refers to the Process
* @param machine ,refers to the Machine
* @return the minimum cost of executing the process to the certain machine.
*/
private int runningCost(int process, int machine) {

if (process==0) //refers to the first process,which does not require for a previous one to have been executed
return Run[process][machine];
else {

int[] runningCosts = new int[numberMachines]; //stores the costs of executing our Process depending on the Machine the previous one was executed

for (int k=0; k < numberMachines; k++) //computes the cost of executing the previous process to each and every Machine
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

return findMin(runningCosts); //returns the minimum running cost
}
}

/**
* Function used in order to return the minimum Cost.
* @param cost ,an Array of size M which refers to the costs of executing a Process to each Machine
* @return the minimum cost
*/
private int findMin(int[] cost) {

int min=0;

for (int i=1;i<cost.length;i++){

if (cost[i]<cost[min])
min=i;
}
return cost[min];
}

/**
* Method used in order to present the overall costs.
*/
private void showResults(){

for (int i=0; i < numberProcesses; i++){

for (int j=0; j < numberMachines; j++) {
System.out.print(Cost[i][j]);
System.out.print(" ");
}

System.out.println();
}
System.out.println();
}

/**
* Getter for the running Cost of i process on j machine.
*/
public int getCost(int process,int machine) {
return Cost[process][machine];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package com.thealgorithms.dynamicprogramming;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

/**
* @author [email protected]
*/
public class OptimalJobSchedulingTest {

@Test
public void testOptimalJobScheduling1(){

int numberProcesses = 5;
int numberMachines = 4;

int[][] Run = {
{5, 1, 3, 2},
{4, 2, 1, 3},
{1, 5, 2, 1},
{2, 3, 4, 2},
{1, 1, 3, 1}};

int[][] Transfer = {
{0, 1, 2, 4},
{1, 0, 2, 3},
{2, 2, 0, 1},
{4, 3, 1, 0}};

OptimalJobScheduling opt = new OptimalJobScheduling(numberProcesses,numberMachines,Run,Transfer);

opt.execute();


int[][] costs = {
{5, 1, 3, 2},
{6, 3, 4, 5},
{5, 8, 6, 6},
{7, 9, 10, 8},
{8, 9, 12, 9}};

for (int i=0; i < numberProcesses; i++){

for (int j=0; j < numberMachines; j++){

assertEquals(costs[i][j],opt.getCost(i,j));
}
}
}

@Test
public void testOptimalJobScheduling2(){

int numberProcesses = 3;
int numberMachines = 3;

int[][] Run = {
{5, 1, 3},
{4, 2, 1},
{1, 5, 2}};

int[][] Transfer = {
{0, 1, 2},
{1, 0, 2},
{2, 2, 0}};

OptimalJobScheduling opt = new OptimalJobScheduling(numberProcesses,numberMachines,Run,Transfer);

opt.execute();

int[][] costs = {
{5, 1, 3},
{6, 3, 4},
{5, 8, 6}};

for (int i=0; i < numberProcesses; i++){

for (int j=0; j < numberMachines; j++){

assertEquals(costs[i][j],opt.getCost(i,j));
}
}
}

@Test
public void testOptimalJobScheduling3(){

int numberProcesses = 6;
int numberMachines = 4;

int[][] Run = {
{5, 1, 3, 2},
{4, 2, 1, 1},
{1, 5, 2, 6},
{1, 1, 2, 3},
{2, 1, 4, 6},
{3, 2, 2, 3},
};

int[][] Transfer = {
{0, 1, 2, 1},
{1, 0, 2, 3},
{2, 2, 0, 2},
{1, 3, 2, 0},
};

OptimalJobScheduling opt = new OptimalJobScheduling(numberProcesses,numberMachines,Run,Transfer);

opt.execute();

int[][] costs = {
{5, 1, 3, 2},
{6, 3, 4, 3},
{5, 8, 6, 9},
{6, 7, 8, 9},
{8, 8, 12, 13},
{11, 10, 12, 12}};

for (int i=0; i < numberProcesses; i++){

for (int j=0; j < numberMachines; j++){

assertEquals(costs[i][j],opt.getCost(i,j));
}
}
}
}