-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
275 additions
and
0 deletions.
There are no files selected for viewing
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
+++++++++++++++++++++++++++++ | ||
ABZ5 Adams, Balas, and Zawack 10x10 instance (Table 1, instance 5) | ||
10 10 | ||
4 88 8 68 6 94 5 99 1 67 2 89 9 77 7 99 0 86 3 92 | ||
5 72 3 50 6 69 4 75 2 94 8 66 0 92 1 82 7 94 9 63 | ||
9 83 8 61 0 83 1 65 6 64 5 85 7 78 4 85 2 55 3 77 | ||
7 94 2 68 1 61 4 99 3 54 6 75 5 66 0 76 9 63 8 67 | ||
3 69 4 88 9 82 8 95 0 99 2 67 6 95 5 68 7 67 1 86 | ||
1 99 4 81 5 64 6 66 8 80 2 80 7 69 9 62 3 79 0 88 | ||
7 50 1 86 4 97 3 96 0 95 8 97 2 66 5 99 6 52 9 71 | ||
4 98 6 73 3 82 2 51 1 71 5 94 7 85 0 62 8 95 9 79 | ||
0 94 6 71 3 81 7 85 1 66 2 90 4 76 5 58 8 93 9 97 | ||
3 50 0 59 1 82 8 67 7 56 9 96 6 58 4 81 5 59 2 96 | ||
+++++++++++++++++++++++++++++ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
+++++++++++++++++++++++++++++ | ||
Adams, Balas, and Zawack 15 x 20 instance (Table 1, instance 7) | ||
20 15 | ||
2 24 3 12 9 17 4 27 0 21 6 25 8 27 7 26 1 30 5 31 11 18 14 16 13 39 10 19 12 26 | ||
6 30 3 15 12 20 11 19 1 24 13 15 10 28 2 36 5 26 7 15 0 11 8 23 14 20 9 26 4 28 | ||
6 35 0 22 13 23 7 32 2 20 3 12 12 19 10 23 9 17 1 14 5 16 11 29 8 16 4 22 14 22 | ||
9 20 6 29 1 19 7 14 12 33 4 30 0 32 5 21 11 29 10 24 14 25 2 29 3 13 8 20 13 18 | ||
11 23 13 20 1 28 6 32 7 16 5 18 8 24 9 23 3 24 10 34 2 24 0 24 14 28 12 15 4 18 | ||
8 24 11 19 14 21 1 33 7 34 6 35 5 40 10 36 3 23 2 26 4 15 9 28 13 38 12 13 0 25 | ||
13 27 3 30 6 21 8 19 12 12 4 27 2 39 9 13 14 12 5 36 10 21 11 17 1 29 0 17 7 33 | ||
5 27 4 19 6 29 9 20 3 21 10 40 8 14 14 39 13 39 2 27 1 36 12 12 11 37 7 22 0 13 | ||
13 32 11 29 8 24 3 27 5 40 4 21 9 26 0 27 14 27 6 16 2 21 10 13 7 28 12 28 1 32 | ||
12 35 1 11 5 39 14 18 7 23 0 34 3 24 13 11 8 30 11 31 4 15 10 15 2 28 9 26 6 33 | ||
10 28 5 37 12 29 1 31 7 25 8 13 14 14 4 20 3 27 9 25 13 31 11 14 6 25 2 39 0 36 | ||
0 22 11 25 5 28 13 35 4 31 8 21 9 20 14 19 2 29 7 32 10 18 1 18 3 11 12 17 6 15 | ||
12 39 5 32 2 36 8 14 3 28 13 37 0 38 6 20 7 19 11 12 14 22 1 36 4 15 9 32 10 16 | ||
8 28 1 29 14 40 12 23 4 34 5 33 6 27 10 17 0 20 7 28 11 21 2 21 13 20 9 33 3 27 | ||
9 21 14 34 3 30 12 38 0 11 11 16 2 14 5 14 1 34 8 33 4 23 13 40 10 12 6 23 7 27 | ||
9 13 14 40 7 36 4 17 0 13 5 33 8 25 13 24 10 23 3 36 2 29 1 18 11 13 6 33 12 13 | ||
3 25 5 15 2 28 12 40 7 39 1 31 8 35 6 31 11 36 4 12 10 33 14 19 9 16 13 27 0 21 | ||
12 22 10 14 0 12 2 20 5 12 1 18 11 17 8 39 14 31 3 31 7 32 9 20 13 29 4 13 6 26 | ||
5 18 10 30 7 38 14 22 13 15 11 20 9 16 3 17 1 12 2 13 12 40 6 17 8 30 4 38 0 13 | ||
9 31 8 39 12 27 1 14 5 33 3 31 11 22 13 36 0 16 7 11 14 14 4 29 6 28 2 22 10 17 | ||
+++++++++++++++++++++++++++++ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
/** | ||
* Problem Instance | ||
* Data structure that will hold JSSP data type. | ||
* Follows open source JSSP format. | ||
*/ | ||
function JSSPProblemInstance(m,n){ | ||
this.m = m | ||
this.n = n; | ||
this.jobs = []; // list of lists. | ||
} | ||
|
||
const demoinstance = ` | ||
+++++++++++++++++++++++ | ||
A simple Demo | ||
4 5 | ||
0 10 1 20 2 20 3 40 4 10 | ||
1 20 0 10 3 30 2 50 4 30 | ||
2 30 1 20 4 12 3 40 0 10 | ||
4 50 3 30 2 15 0 20 1 15 | ||
++++++++++++++++++++++++ | ||
` | ||
const a = new JSSPProblemInstance(4,5) | ||
a.jobs.push([0,10,1,20,2,20,3,40,4,10]) | ||
a.jobs.push([1,20,0,10,3,30,2,50,4,30]) | ||
a.jobs.push([2,30,1,20,4,12,3,40,0,10]) | ||
a.jobs.push([4,50,3,30,2,15,0,20,1,15]) | ||
console.log(a) | ||
|
||
/** | ||
* SOlution Space | ||
* Solution Space for JSSP represents Gantt Chart to show what jobs to run on what machines and in what order. | ||
* Looks like follows: | ||
* [ | ||
* [] //Job ORder for Machine 1. | ||
* [] // Job order for Machine 2 and so on.... | ||
* ] | ||
*/ | ||
function JSSPGanttChartSolution(){ | ||
this.schedule = [] | ||
} | ||
|
||
/** | ||
* Calculates MakeSpan of an instance of a JSSP Gantt Chart Solution | ||
* In our definition of ganttChart, we choose last integer of each array if array>0. | ||
* and return max of them | ||
*/ | ||
function getMakeSpan(ganttChartSolution){ | ||
return Math.max(ganttChartSolution.map(arrForMachine => { | ||
if(arrForMachine.lenth > 0){ | ||
return arrForMachine[-1] | ||
} else { | ||
return 0 | ||
} | ||
})); | ||
} | ||
|
||
/** | ||
* Given a 1D solution, convert it into Gantt Chart Solution. | ||
*/ | ||
function JSSP1dToGantt(jobInstance, test1D){ | ||
//const test1D = [0,2,1,0,3,1,0,1,2,3,2,1,1,2,3,0,2,0,3,3] | ||
// const test1D =[0,0,0,0,0,1,1,1,1,1,2,2,2,2,2,3,3,3,3,3] | ||
const m = 5 // Number of Machines: 0,1,2,3,4,5 | ||
const n = 4 // Number of Jobs. 0,1,2,3 -> as denoted in the 1d strucutre. | ||
const ganttChart = [] | ||
for(let i = 0; i<m; i++){ | ||
ganttChart.push([]) | ||
} | ||
//console.log(ganttChart) | ||
|
||
// Next we fill the ganttChart with data based on test1D | ||
// We need access to the job instance so that we can look at | ||
|
||
// Keep Track of last time for each job. | ||
const lastJobTime = new Array(jobInstance.n).fill(0) | ||
// console.log("Last Job Time", lastJobTime) | ||
|
||
//console.log(jobInstance) | ||
test1D.forEach(jobNumber => { | ||
// job jobNumber is assigned to its respective first. | ||
const jobDef = jobInstance.jobs[jobNumber] | ||
// console.log("job def is", jobDef); | ||
// Get the first one out. | ||
const firstJob = jobDef.splice(0,2); | ||
// console.log(`Current Job for Job Number ${jobNumber} :` ,firstJob) | ||
const machine = firstJob[0]; | ||
const time = firstJob[1] | ||
|
||
// Now fill Gantt Chart | ||
const firstAvailableTimeOnMachine = ganttChart[machine].length === 0 ? 0 : ganttChart[machine][ganttChart[machine].length -1] | ||
// What is the last time of dependent job? We can find that out dependent jobs by looking at job instance from before... | ||
|
||
const _lastJobTime = lastJobTime[jobNumber] | ||
const firstAvailableTime = Math.max(_lastJobTime,firstAvailableTimeOnMachine) | ||
lastJobTime[jobNumber] = firstAvailableTime+time | ||
|
||
const ganttSchedule = [jobNumber,firstAvailableTime+1,firstAvailableTime+time ] | ||
ganttChart[machine] = [...ganttChart[machine], ...ganttSchedule] | ||
}) | ||
|
||
//console.log(ganttChart) | ||
|
||
|
||
return ganttChart | ||
} | ||
/** | ||
* Generating MakeSpan is basically calculating Max of the end index of all times from all machines | ||
* @param {*} ganttChart | ||
*/ | ||
function getMakeSpan(ganttChart){ | ||
return Math.max(...ganttChart.map(machineInfo => machineInfo[machineInfo.length -1 ])); | ||
} | ||
|
||
function FishesYatesShuffle(array) { | ||
var currentIndex = array.length, temporaryValue, randomIndex; | ||
|
||
// While there remain elements to shuffle... | ||
while (0 !== currentIndex) { | ||
|
||
// Pick a remaining element... | ||
randomIndex = Math.floor(Math.random() * currentIndex); | ||
currentIndex -= 1; | ||
|
||
// And swap it with the current element. | ||
temporaryValue = array[currentIndex]; | ||
array[currentIndex] = array[randomIndex]; | ||
array[randomIndex] = temporaryValue; | ||
} | ||
|
||
return array; | ||
} | ||
|
||
|
||
/** | ||
* Our Random Algorithm will | ||
*/ | ||
console.log("running optimization algo") | ||
function runOptimizationAlgo(m,n){ | ||
const startingInput = [0,0,0,0,0,1,1,1,1,1,2,2,2,2,2,3,3,3,3,3] | ||
let gantt = [] | ||
let makeSpan = Infinity | ||
const times = 100 | ||
for(let i = 0; i < times; i ++){ | ||
// Create new Job Shop Instance every time. | ||
const a = new JSSPProblemInstance(4,5) | ||
a.jobs.push([0,10,1,20,2,20,3,40,4,10]) | ||
a.jobs.push([1,20,0,10,3,30,2,50,4,30]) | ||
a.jobs.push([2,30,1,20,4,12,3,40,0,10]) | ||
a.jobs.push([4,50,3,30,2,15,0,20,1,15]) | ||
//console.log(a) | ||
//console.log("running once") | ||
const randomizedInput = FishesYatesShuffle(startingInput) | ||
//console.log("randomized input " , randomizedInput) | ||
const gantFromRandInput = JSSP1dToGantt(a, randomizedInput); | ||
const newMakeSpan = getMakeSpan(gantFromRandInput); | ||
if(newMakeSpan < makeSpan){ | ||
makeSpan = newMakeSpan | ||
gantt = gantFromRandInput | ||
console.log("Found Better") | ||
console.log(gantt) | ||
console.log("============") | ||
} | ||
} | ||
return gantt | ||
console.log(gantt) | ||
} | ||
|
||
const best = runOptimizationAlgo() | ||
console.log("Best Gantt Chart is ") | ||
console.log(best) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
+++++++++++++++++++++++ | ||
A simple Demo | ||
4 5 | ||
0 10 1 20 2 20 3 40 4 10 | ||
1 20 0 10 3 30 2 50 4 30 | ||
2 30 1 20 4 12 3 40 0 10 | ||
4 50 3 30 2 15 0 20 1 15 | ||
++++++++++++++++++++++++ |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
const JSSPProblemInstance = require('./definitions/JobShopProblemInstance'); | ||
const JSSPGanttChartSolution = require('./definitions/JSSPSolution'); | ||
const JSSP1dToGantt = require('./definitions/JSSPSolution'); | ||
const generateRandom1D = require('./definitions/helpers'); | ||
|
||
// Parameters for algorithm. Problem is defined in a problem definition file. | ||
const PROBLEM_INSTANCE_FILE = "demo.txt" | ||
const ALGORITHM_REPETITION = 1000000000000 | ||
const ALGORITHM_MAX_TIME_SECONDS = 1 //Max time we want the algo to run. TODO use timelimit | ||
|
||
// Step 1: Create a new instance of JSSPProblemInstance from file. | ||
const problem = new JSSPProblemInstance() // Instantiate with no data. | ||
problem.generateJSSPFromTextFile(PROBLEM_INSTANCE_FILE) | ||
console.log(problem) | ||
// Step 2: Next, we run the algorithm for a set number of times. | ||
// console.log("running optimization algo") | ||
function runOptimizationAlgo(problem){ | ||
let gantt = [] | ||
let makeSpan = Infinity | ||
// const times = 100 | ||
const algoStartTime = (new Date).getTime(); | ||
const algoMaxEndTime = algoStartTime + (ALGORITHM_MAX_TIME_SECONDS * 1000) | ||
for(let i = 0; i < ALGORITHM_REPETITION; i ++){ | ||
if( (i%100==0) && (new Date).getTime() > algoMaxEndTime){ //Run time check every 100th run. | ||
console.log("Ending because of time limit") | ||
console.log("Ran times : " , i) | ||
break; | ||
} | ||
const randomizedInput = generateRandom1D(problem.numMachines, problem.numJobs) | ||
const problemCopy = Object.assign({}, problem) | ||
problemCopy.jobs = JSON.parse(JSON.stringify(problem.jobs)) | ||
|
||
const ganttFromRandInput = randomizedInput.JSSP1dToGantt(problemCopy) | ||
const newMakeSpan = ganttFromRandInput.getMakeSpan(); | ||
|
||
if(newMakeSpan < makeSpan){ | ||
makeSpan = newMakeSpan | ||
gantt = ganttFromRandInput | ||
// console.log("Found Better") | ||
console.log("New Make Span at index ", i, newMakeSpan) | ||
// console.log(gantt) | ||
// console.log("============") | ||
} | ||
} | ||
console.log("Shortest MakeSpan", makeSpan) | ||
return gantt | ||
} | ||
|
||
const best = runOptimizationAlgo(problem) | ||
console.log("Best Gantt Chart is ") | ||
console.log(best) |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
+++++++++++++++++++++++ | ||
A simple Demo | ||
4 5 | ||
0 10 1 20 2 20 3 40 4 10 | ||
1 20 0 10 3 30 2 50 4 30 | ||
2 30 1 20 4 12 3 40 0 10 | ||
4 50 3 30 2 15 0 20 1 15 | ||
++++++++++++++++++++++++ |