diff --git a/README.md b/README.md index b646474..fe94d28 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![process-scheduling-solver](https://user-images.githubusercontent.com/19908657/120210473-6874ca00-c262-11eb-96a2-5c4742fea816.png)](https://boonsuen.com/process-scheduling-solver) -Get it here: [process-scheduling-solver.boonsuen.com](https://process-scheduling-solver.boonsuen.com) +Get it here: [https://process-scheduling-solver-two.vercel.app](https://process-scheduling-solver-two.vercel.app) ## Supported algorithms diff --git a/src/algorithms/fcfs.ts b/src/algorithms/fcfs.ts index a48d2ae..627a37f 100644 --- a/src/algorithms/fcfs.ts +++ b/src/algorithms/fcfs.ts @@ -1,58 +1,51 @@ -import { ganttChartInfoType } from '.'; +import { GanttChartInfoType } from '.'; export const fcfs = (arrivalTime: number[], burstTime: number[]) => { - const processesInfo = arrivalTime - .map((item, index) => { - const job = - arrivalTime.length > 26 - ? `P${index + 1}` - : (index + 10).toString(36).toUpperCase(); - - return { - job, - at: item, - bt: burstTime[index], - }; - }) - .sort((obj1, obj2) => { - if (obj1.at > obj2.at) { - return 1; - } - if (obj1.at < obj2.at) { - return -1; - } - return 0; + const processesInfo = arrivalTime + .map((item, index) => ({ + job: index, + at: item, + bt: burstTime[index], + })) + .sort((obj1, obj2) => { + if (obj1.at > obj2.at) { + return 1; + } + if (obj1.at < obj2.at) { + return -1; + } + return 0; + }); + + const finishTime: number[] = []; + const ganttChartInfo: GanttChartInfoType = []; + + const solvedProcessesInfo = processesInfo.map((process, index) => { + if (index === 0 || process.at > finishTime[index - 1]) { + finishTime[index] = process.at + process.bt; + + ganttChartInfo.push({ + job: process.job, + start: process.at, + stop: finishTime[index], + }); + } else { + finishTime[index] = finishTime[index - 1] + process.bt; + + ganttChartInfo.push({ + job: process.job, + start: finishTime[index - 1], + stop: finishTime[index], + }); + } + + return { + ...process, + ft: finishTime[index], + tat: finishTime[index] - process.at, + wat: finishTime[index] - process.at - process.bt, + }; }); - let finishTime: number[] = []; - let ganttChartInfo: ganttChartInfoType = []; - - const solvedProcessesInfo = processesInfo.map((process, index) => { - if (index === 0 || process.at > finishTime[index - 1]) { - finishTime[index] = process.at + process.bt; - - ganttChartInfo.push({ - job: process.job, - start: process.at, - stop: finishTime[index], - }); - } else { - finishTime[index] = finishTime[index - 1] + process.bt; - - ganttChartInfo.push({ - job: process.job, - start: finishTime[index - 1], - stop: finishTime[index], - }); - } - - return { - ...process, - ft: finishTime[index], - tat: finishTime[index] - process.at, - wat: finishTime[index] - process.at - process.bt, - }; - }); - - return { solvedProcessesInfo, ganttChartInfo }; + return { solvedProcessesInfo, ganttChartInfo }; }; diff --git a/src/algorithms/index.ts b/src/algorithms/index.ts index bf2686d..c9100f5 100644 --- a/src/algorithms/index.ts +++ b/src/algorithms/index.ts @@ -6,42 +6,42 @@ import { npp } from './npp'; import { pp } from './pp'; import { AlgoType } from '../components/Input/AlgoSelect'; -export type ganttChartInfoType = { - job: string; - start: number; - stop: number; +export type GanttChartInfoType = { + job: number; + start: number; + stop: number; }[]; -export type solvedProcessesInfoType = { - job: string; - at: number; - bt: number; - ft: number; - tat: number; - wat: number; +export type SolvedProcessesInfoType = { + job: number; + at: number; + bt: number; + ft: number; + tat: number; + wat: number; }[]; export const solve = ( - algo: AlgoType, - arrivalTime: number[], - burstTime: number[], - timeQuantum: number, - priorities: number[] + algo: AlgoType, + arrivalTime: number[], + burstTime: number[], + timeQuantum: number, + priorities: number[] ) => { - switch (algo) { - case 'FCFS': - return fcfs(arrivalTime, burstTime); - case 'SJF': - return sjf(arrivalTime, burstTime); - case 'SRTF': - return srtf(arrivalTime, burstTime); - case 'RR': - return rr(arrivalTime, burstTime, timeQuantum); - case 'NPP': - return npp(arrivalTime, burstTime, priorities); - case 'PP': - return pp(arrivalTime, burstTime, priorities); - default: - break; - } + switch (algo) { + case 'FCFS': + return fcfs(arrivalTime, burstTime); + case 'SJF': + return sjf(arrivalTime, burstTime); + case 'SRTF': + return srtf(arrivalTime, burstTime); + case 'RR': + return rr(arrivalTime, burstTime, timeQuantum); + case 'NPP': + return npp(arrivalTime, burstTime, priorities); + case 'PP': + return pp(arrivalTime, burstTime, priorities); + default: + break; + } }; diff --git a/src/algorithms/npp.ts b/src/algorithms/npp.ts index 35e5fad..13a8577 100644 --- a/src/algorithms/npp.ts +++ b/src/algorithms/npp.ts @@ -1,150 +1,143 @@ -import { ganttChartInfoType } from '.'; +import { GanttChartInfoType } from '.'; export const npp = ( - arrivalTime: number[], - burstTime: number[], - priorities: number[] + arrivalTime: number[], + burstTime: number[], + priorities: number[] ) => { - const processesInfo = arrivalTime - .map((item, index) => { - const job = - arrivalTime.length > 26 - ? `P${index + 1}` - : (index + 10).toString(36).toUpperCase(); - - return { - job, - at: item, - bt: burstTime[index], - priority: priorities[index], - }; - }) - .sort((process1, process2) => { - if (process1.at > process2.at) return 1; - if (process1.at < process2.at) return -1; - if (process1.priority > process2.priority) return 1; - if (process1.priority < process2.priority) return -1; - return 0; - }); - - let finishTime: number[] = []; - let ganttChartInfo: ganttChartInfoType = []; - - const solvedProcessesInfo = []; - const readyQueue = []; - const finishedJobs = []; - - for (let i = 0; i < processesInfo.length; i++) { - if (i === 0) { - readyQueue.push(processesInfo[0]); - finishTime.push(processesInfo[0].at + processesInfo[0].bt); - solvedProcessesInfo.push({ - ...processesInfo[0], - ft: finishTime[0], - tat: finishTime[0] - processesInfo[0].at, - wat: finishTime[0] - processesInfo[0].at - processesInfo[0].bt, - }); - - processesInfo.forEach((p) => { - if (p.at <= finishTime[0] && !readyQueue.includes(p)) { - readyQueue.push(p); - } - }); - - readyQueue.shift(); - finishedJobs.push(processesInfo[0]); - - ganttChartInfo.push({ - job: processesInfo[0].job, - start: processesInfo[0].at, - stop: finishTime[0], - }); - } else { - if ( - readyQueue.length === 0 && - finishedJobs.length !== processesInfo.length - ) { - const unfinishedJobs = processesInfo - .filter((p) => { - return !finishedJobs.includes(p); - }) - .sort((a, b) => { - if (a.at > b.at) return 1; - if (a.at < b.at) return -1; - if (a.priority > b.priority) return 1; - if (a.priority < a.priority) return -1; + const processesInfo = arrivalTime + .map((item, index) => ({ + job: index, + at: item, + bt: burstTime[index], + priority: priorities[index], + })) + .sort((process1, process2) => { + if (process1.at > process2.at) return 1; + if (process1.at < process2.at) return -1; + if (process1.priority > process2.priority) return 1; + if (process1.priority < process2.priority) return -1; return 0; - }); - readyQueue.push(unfinishedJobs[0]); - } - - // Equal-priority processes are scheduled in FCFS order. - const rqSortedByPriority = [...readyQueue].sort((a, b) => { - if (a.priority > b.priority) return 1; - if (a.priority < b.priority) return -1; - if (a.at > b.at) return 1; - if (a.at < b.at) return -1; - return 0; - }); - - const processToExecute = rqSortedByPriority[0]; - - const previousFinishTime = finishTime[finishTime.length - 1]; - - if (processToExecute.at > previousFinishTime) { - finishTime.push(processToExecute.at + processToExecute.bt); - const newestFinishTime = finishTime[finishTime.length - 1]; - ganttChartInfo.push({ - job: processToExecute.job, - start: processToExecute.at, - stop: newestFinishTime, }); - } else { - finishTime.push(previousFinishTime + processToExecute.bt); - const newestFinishTime = finishTime[finishTime.length - 1]; - ganttChartInfo.push({ - job: processToExecute.job, - start: previousFinishTime, - stop: newestFinishTime, - }); - } - - const newestFinishTime = finishTime[finishTime.length - 1]; - - solvedProcessesInfo.push({ - ...processToExecute, - ft: newestFinishTime, - tat: newestFinishTime - processToExecute.at, - wat: newestFinishTime - processToExecute.at - processToExecute.bt, - }); - - processesInfo.forEach((p) => { - if ( - p.at <= newestFinishTime && - !readyQueue.includes(p) && - !finishedJobs.includes(p) - ) { - readyQueue.push(p); + + const finishTime: number[] = []; + const ganttChartInfo: GanttChartInfoType = []; + + const solvedProcessesInfo = []; + const readyQueue = []; + const finishedJobs = []; + + for (let i = 0; i < processesInfo.length; i++) { + if (i === 0) { + readyQueue.push(processesInfo[0]); + finishTime.push(processesInfo[0].at + processesInfo[0].bt); + solvedProcessesInfo.push({ + ...processesInfo[0], + ft: finishTime[0], + tat: finishTime[0] - processesInfo[0].at, + wat: finishTime[0] - processesInfo[0].at - processesInfo[0].bt, + }); + + processesInfo.forEach((p) => { + if (p.at <= finishTime[0] && !readyQueue.includes(p)) { + readyQueue.push(p); + } + }); + + readyQueue.shift(); + finishedJobs.push(processesInfo[0]); + + ganttChartInfo.push({ + job: processesInfo[0].job, + start: processesInfo[0].at, + stop: finishTime[0], + }); + } else { + if ( + readyQueue.length === 0 && + finishedJobs.length !== processesInfo.length + ) { + const unfinishedJobs = processesInfo + .filter((p) => { + return !finishedJobs.includes(p); + }) + .sort((a, b) => { + if (a.at > b.at) return 1; + if (a.at < b.at) return -1; + if (a.priority > b.priority) return 1; + if (a.priority < a.priority) return -1; + return 0; + }); + readyQueue.push(unfinishedJobs[0]); + } + + // Equal-priority processes are scheduled in FCFS order. + const rqSortedByPriority = [...readyQueue].sort((a, b) => { + if (a.priority > b.priority) return 1; + if (a.priority < b.priority) return -1; + if (a.at > b.at) return 1; + if (a.at < b.at) return -1; + return 0; + }); + + const processToExecute = rqSortedByPriority[0]; + + const previousFinishTime = finishTime[finishTime.length - 1]; + + if (processToExecute.at > previousFinishTime) { + finishTime.push(processToExecute.at + processToExecute.bt); + const newestFinishTime = finishTime[finishTime.length - 1]; + ganttChartInfo.push({ + job: processToExecute.job, + start: processToExecute.at, + stop: newestFinishTime, + }); + } else { + finishTime.push(previousFinishTime + processToExecute.bt); + const newestFinishTime = finishTime[finishTime.length - 1]; + ganttChartInfo.push({ + job: processToExecute.job, + start: previousFinishTime, + stop: newestFinishTime, + }); + } + + const newestFinishTime = finishTime[finishTime.length - 1]; + + solvedProcessesInfo.push({ + ...processToExecute, + ft: newestFinishTime, + tat: newestFinishTime - processToExecute.at, + wat: newestFinishTime - processToExecute.at - processToExecute.bt, + }); + + processesInfo.forEach((p) => { + if ( + p.at <= newestFinishTime && + !readyQueue.includes(p) && + !finishedJobs.includes(p) + ) { + readyQueue.push(p); + } + }); + + const indexToRemove = readyQueue.indexOf(processToExecute); + if (indexToRemove > -1) { + readyQueue.splice(indexToRemove, 1); + } + + finishedJobs.push(processToExecute); } - }); + } - const indexToRemove = readyQueue.indexOf(processToExecute); - if (indexToRemove > -1) { - readyQueue.splice(indexToRemove, 1); - } + // Sort the processes by job name within arrival time + solvedProcessesInfo.sort((obj1, obj2) => { + if (obj1.at > obj2.at) return 1; + if (obj1.at < obj2.at) return -1; + if (obj1.job > obj2.job) return 1; + if (obj1.job < obj2.job) return -1; + return 0; + }); - finishedJobs.push(processToExecute); - } - } - - // Sort the processes by job name within arrival time - solvedProcessesInfo.sort((obj1, obj2) => { - if (obj1.at > obj2.at) return 1; - if (obj1.at < obj2.at) return -1; - if (obj1.job > obj2.job) return 1; - if (obj1.job < obj2.job) return -1; - return 0; - }); - - return { solvedProcessesInfo, ganttChartInfo }; + return { solvedProcessesInfo, ganttChartInfo }; }; diff --git a/src/algorithms/pp.ts b/src/algorithms/pp.ts index f08163c..2402dea 100644 --- a/src/algorithms/pp.ts +++ b/src/algorithms/pp.ts @@ -1,190 +1,183 @@ -import { solvedProcessesInfoType, ganttChartInfoType } from '.'; +import { SolvedProcessesInfoType, GanttChartInfoType } from '.'; export const pp = ( - arrivalTime: number[], - burstTime: number[], - priorities: number[] + arrivalTime: number[], + burstTime: number[], + priorities: number[] ) => { - const processesInfo = arrivalTime - .map((item, index) => { - const job = - arrivalTime.length > 26 - ? `P${index + 1}` - : (index + 10).toString(36).toUpperCase(); - - return { - job, - at: item, - bt: burstTime[index], - priority: priorities[index], - }; - }) - .sort((process1, process2) => { - if (process1.at > process2.at) return 1; - if (process1.at < process2.at) return -1; - if (process1.priority > process2.priority) return 1; - if (process1.priority < process2.priority) return -1; - return 0; - }); - - const solvedProcessesInfo: solvedProcessesInfoType = []; - const ganttChartInfo: ganttChartInfoType = []; - - const readyQueue: { - job: string; - at: number; - bt: number; - priority: number; - }[] = []; - let currentTime = processesInfo[0].at; - const unfinishedJobs = [...processesInfo]; - - const remainingTime = processesInfo.reduce((acc, process) => { - acc[process.job] = process.bt; - return acc; - }, {}); - - readyQueue.push(unfinishedJobs[0]); - while ( - Object.values(remainingTime).reduce((acc: number, cur: number) => { - return acc + cur; - }, 0) && - unfinishedJobs.length > 0 - ) { - let prevIdle = false; - if (readyQueue.length === 0 && unfinishedJobs.length > 0) { - prevIdle = true; - readyQueue.push(unfinishedJobs[0]); - } - - readyQueue.sort((a, b) => { - // Equal-priority processes are scheduled in FCFS order. - if (a.priority > b.priority) return 1; - if (a.priority < b.priority) return -1; - return 0; - }); - - const processToExecute = readyQueue[0]; - - const processATLessThanBT = processesInfo.filter((p) => { - let curr: number = currentTime; - if (prevIdle) { - curr = processToExecute.at; - } + const processesInfo = arrivalTime + .map((item, index) => ({ + job: index, + at: item, + bt: burstTime[index], + priority: priorities[index], + })) + .sort((process1, process2) => { + if (process1.at > process2.at) return 1; + if (process1.at < process2.at) return -1; + if (process1.priority > process2.priority) return 1; + if (process1.priority < process2.priority) return -1; + return 0; + }); - return ( - p.at <= remainingTime[processToExecute.job] + curr && - p !== processToExecute && - !readyQueue.includes(p) && - unfinishedJobs.includes(p) - ); - }); - let gotInterruption = false; - processATLessThanBT.some((p) => { - if (prevIdle) { - currentTime = processToExecute.at; - } - - const amount = p.at - currentTime; - - if (currentTime >= p.at) { - readyQueue.push(p); - } - - if (p.priority < processToExecute.priority) { - remainingTime[processToExecute.job] -= amount; - readyQueue.push(p); - const prevCurrentTime = currentTime; - currentTime += amount; - ganttChartInfo.push({ - job: processToExecute.job, - start: prevCurrentTime, - stop: currentTime, + const solvedProcessesInfo: SolvedProcessesInfoType = []; + const ganttChartInfo: GanttChartInfoType = []; + + const readyQueue: { + job: number; + at: number; + bt: number; + priority: number; + }[] = []; + let currentTime = processesInfo[0].at; + const unfinishedJobs = [...processesInfo]; + + const remainingTime = processesInfo.reduce((acc, process) => { + acc[process.job] = process.bt; + return acc; + }, {}); + + readyQueue.push(unfinishedJobs[0]); + while ( + Object.values(remainingTime).reduce((acc: number, cur: number) => { + return acc + cur; + }, 0) && + unfinishedJobs.length > 0 + ) { + let prevIdle = false; + if (readyQueue.length === 0 && unfinishedJobs.length > 0) { + prevIdle = true; + readyQueue.push(unfinishedJobs[0]); + } + + readyQueue.sort((a, b) => { + // Equal-priority processes are scheduled in FCFS order. + if (a.priority > b.priority) return 1; + if (a.priority < b.priority) return -1; + return 0; }); - gotInterruption = true; - return true; - } - }); - const processToArrive = processesInfo.filter((p) => { - return ( - p.at <= currentTime && - p !== processToExecute && - !readyQueue.includes(p) && - unfinishedJobs.includes(p) - ); - }); - // Push new processes to readyQueue - readyQueue.push(...processToArrive); + const processToExecute = readyQueue[0]; - if (!gotInterruption) { - if (prevIdle) { - const remainingT = remainingTime[processToExecute.job]; - remainingTime[processToExecute.job] -= remainingT; - currentTime = processToExecute.at + remainingT; + const processATLessThanBT = processesInfo.filter((p) => { + let curr: number = currentTime; + if (prevIdle) { + curr = processToExecute.at; + } - processATLessThanBT.forEach((p) => { - if (currentTime >= p.at) { - readyQueue.push(p); - } + return ( + p.at <= remainingTime[processToExecute.job] + curr && + p !== processToExecute && + !readyQueue.includes(p) && + unfinishedJobs.includes(p) + ); }); - - ganttChartInfo.push({ - job: processToExecute.job, - start: processToExecute.at, - stop: currentTime, + let gotInterruption = false; + processATLessThanBT.some((p) => { + if (prevIdle) { + currentTime = processToExecute.at; + } + + const amount = p.at - currentTime; + + if (currentTime >= p.at) { + readyQueue.push(p); + } + + if (p.priority < processToExecute.priority) { + remainingTime[processToExecute.job] -= amount; + readyQueue.push(p); + const prevCurrentTime = currentTime; + currentTime += amount; + ganttChartInfo.push({ + job: processToExecute.job, + start: prevCurrentTime, + stop: currentTime, + }); + gotInterruption = true; + return true; + } }); - } else { - const remainingT = remainingTime[processToExecute.job]; - remainingTime[processToExecute.job] -= remainingT; - const prevCurrentTime = currentTime; - currentTime += remainingT; - - processATLessThanBT.forEach((p) => { - if (currentTime >= p.at && !readyQueue.includes(p)) { - readyQueue.push(p); - } + const processToArrive = processesInfo.filter((p) => { + return ( + p.at <= currentTime && + p !== processToExecute && + !readyQueue.includes(p) && + unfinishedJobs.includes(p) + ); }); - ganttChartInfo.push({ - job: processToExecute.job, - start: prevCurrentTime, - stop: currentTime, - }); - } + // Push new processes to readyQueue + readyQueue.push(...processToArrive); + + if (!gotInterruption) { + if (prevIdle) { + const remainingT = remainingTime[processToExecute.job]; + remainingTime[processToExecute.job] -= remainingT; + currentTime = processToExecute.at + remainingT; + + processATLessThanBT.forEach((p) => { + if (currentTime >= p.at) { + readyQueue.push(p); + } + }); + + ganttChartInfo.push({ + job: processToExecute.job, + start: processToExecute.at, + stop: currentTime, + }); + } else { + const remainingT = remainingTime[processToExecute.job]; + remainingTime[processToExecute.job] -= remainingT; + const prevCurrentTime = currentTime; + currentTime += remainingT; + + processATLessThanBT.forEach((p) => { + if (currentTime >= p.at && !readyQueue.includes(p)) { + readyQueue.push(p); + } + }); + + ganttChartInfo.push({ + job: processToExecute.job, + start: prevCurrentTime, + stop: currentTime, + }); + } + } + + // Requeueing (move head/first item to tail/last) + readyQueue.push(readyQueue.shift()); + + // When the process finished executing + if (remainingTime[processToExecute.job] === 0) { + const indexToRemoveUJ = unfinishedJobs.indexOf(processToExecute); + if (indexToRemoveUJ > -1) { + unfinishedJobs.splice(indexToRemoveUJ, 1); + } + const indexToRemoveRQ = readyQueue.indexOf(processToExecute); + if (indexToRemoveRQ > -1) { + readyQueue.splice(indexToRemoveRQ, 1); + } + + solvedProcessesInfo.push({ + ...processToExecute, + ft: currentTime, + tat: currentTime - processToExecute.at, + wat: currentTime - processToExecute.at - processToExecute.bt, + }); + } } - // Requeueing (move head/first item to tail/last) - readyQueue.push(readyQueue.shift()); - - // When the process finished executing - if (remainingTime[processToExecute.job] === 0) { - const indexToRemoveUJ = unfinishedJobs.indexOf(processToExecute); - if (indexToRemoveUJ > -1) { - unfinishedJobs.splice(indexToRemoveUJ, 1); - } - const indexToRemoveRQ = readyQueue.indexOf(processToExecute); - if (indexToRemoveRQ > -1) { - readyQueue.splice(indexToRemoveRQ, 1); - } - - solvedProcessesInfo.push({ - ...processToExecute, - ft: currentTime, - tat: currentTime - processToExecute.at, - wat: currentTime - processToExecute.at - processToExecute.bt, - }); - } - } - - // Sort the processes by job name within arrival time - solvedProcessesInfo.sort((process1, process2) => { - if (process1.at > process2.at) return 1; - if (process1.at < process2.at) return -1; - if (process1.job > process2.job) return 1; - if (process1.job < process2.job) return -1; - return 0; - }); - - return { solvedProcessesInfo, ganttChartInfo }; + // Sort the processes by job name within arrival time + solvedProcessesInfo.sort((process1, process2) => { + if (process1.at > process2.at) return 1; + if (process1.at < process2.at) return -1; + if (process1.job > process2.job) return 1; + if (process1.job < process2.job) return -1; + return 0; + }); + + return { solvedProcessesInfo, ganttChartInfo }; }; diff --git a/src/algorithms/rr.ts b/src/algorithms/rr.ts index d6d636c..b149af9 100644 --- a/src/algorithms/rr.ts +++ b/src/algorithms/rr.ts @@ -1,126 +1,119 @@ -import { ganttChartInfoType } from '.'; +import { GanttChartInfoType } from '.'; export const rr = ( - arrivalTime: number[], - burstTime: number[], - timeQuantum: number + arrivalTime: number[], + burstTime: number[], + timeQuantum: number ) => { - const processesInfo = arrivalTime - .map((item, index) => { - const job = - arrivalTime.length > 26 - ? `P${index + 1}` - : (index + 10).toString(36).toUpperCase(); - - return { - job, - at: item, - bt: burstTime[index], - }; - }) - .sort((obj1, obj2) => { - if (obj1.at > obj2.at) return 1; - if (obj1.at < obj2.at) return -1; - return 0; - }); - - const solvedProcessesInfo = []; - const ganttChartInfo: ganttChartInfoType = []; - - const readyQueue: { - job: string; - at: number; - bt: number; - }[] = []; - let currentTime = processesInfo[0].at; - const unfinishedJobs = [...processesInfo]; - - const remainingTime = processesInfo.reduce((acc, process) => { - acc[process.job] = process.bt; - return acc; - }, {}); - - readyQueue.push(unfinishedJobs[0]); - while ( - Object.values(remainingTime).reduce((acc: number, cur: number) => { - return acc + cur; - }, 0) && - unfinishedJobs.length > 0 - ) { - if (readyQueue.length === 0 && unfinishedJobs.length > 0) { - // Previously idle - readyQueue.push(unfinishedJobs[0]); - currentTime = readyQueue[0].at; + const processesInfo = arrivalTime + .map((item, index) => ({ + job: index, + at: item, + bt: burstTime[index], + })) + .sort((obj1, obj2) => { + if (obj1.at > obj2.at) return 1; + if (obj1.at < obj2.at) return -1; + return 0; + }); + + const solvedProcessesInfo = []; + const ganttChartInfo: GanttChartInfoType = []; + + const readyQueue: { + job: number; + at: number; + bt: number; + }[] = []; + let currentTime = processesInfo[0].at; + const unfinishedJobs = [...processesInfo]; + + const remainingTime = processesInfo.reduce((acc, process) => { + acc[process.job] = process.bt; + return acc; + }, {}); + + readyQueue.push(unfinishedJobs[0]); + while ( + Object.values(remainingTime).reduce((acc: number, cur: number) => { + return acc + cur; + }, 0) && + unfinishedJobs.length > 0 + ) { + if (readyQueue.length === 0 && unfinishedJobs.length > 0) { + // Previously idle + readyQueue.push(unfinishedJobs[0]); + currentTime = readyQueue[0].at; + } + + const processToExecute = readyQueue[0]; + + if (remainingTime[processToExecute.job] <= timeQuantum) { + // Burst time less than or equal to time quantum, execute until finished + const remainingT = remainingTime[processToExecute.job]; + remainingTime[processToExecute.job] -= remainingT; + const prevCurrentTime = currentTime; + currentTime += remainingT; + + ganttChartInfo.push({ + job: processToExecute.job, + start: prevCurrentTime, + stop: currentTime, + }); + } else { + remainingTime[processToExecute.job] -= timeQuantum; + const prevCurrentTime = currentTime; + currentTime += timeQuantum; + + ganttChartInfo.push({ + job: processToExecute.job, + start: prevCurrentTime, + stop: currentTime, + }); + } + const processToArriveInThisCycle = processesInfo.filter((p) => { + return ( + p.at <= currentTime && + p !== processToExecute && + !readyQueue.includes(p) && + unfinishedJobs.includes(p) + ); + }); + + // Push new processes to readyQueue + readyQueue.push(...processToArriveInThisCycle); + + // Requeueing (move head/first item to tail/last) + readyQueue.push(readyQueue.shift()); + + // When the process finished executing + if (remainingTime[processToExecute.job] === 0) { + const indexToRemoveUJ = unfinishedJobs.indexOf(processToExecute); + if (indexToRemoveUJ > -1) { + unfinishedJobs.splice(indexToRemoveUJ, 1); + } + const indexToRemoveRQ = readyQueue.indexOf(processToExecute); + if (indexToRemoveRQ > -1) { + readyQueue.splice(indexToRemoveRQ, 1); + } + + solvedProcessesInfo.push({ + ...processToExecute, + ft: currentTime, + tat: currentTime - processToExecute.at, + wat: currentTime - processToExecute.at - processToExecute.bt, + }); + } } - const processToExecute = readyQueue[0]; - - if (remainingTime[processToExecute.job] <= timeQuantum) { - // Burst time less than or equal to time quantum, execute until finished - const remainingT = remainingTime[processToExecute.job]; - remainingTime[processToExecute.job] -= remainingT; - const prevCurrentTime = currentTime; - currentTime += remainingT; - - ganttChartInfo.push({ - job: processToExecute.job, - start: prevCurrentTime, - stop: currentTime, - }); - } else { - remainingTime[processToExecute.job] -= timeQuantum; - const prevCurrentTime = currentTime; - currentTime += timeQuantum; - - ganttChartInfo.push({ - job: processToExecute.job, - start: prevCurrentTime, - stop: currentTime, - }); - } - const processToArriveInThisCycle = processesInfo.filter((p) => { - return ( - p.at <= currentTime && - p !== processToExecute && - !readyQueue.includes(p) && - unfinishedJobs.includes(p) - ); + // Sort the processes arrival time and then by job name + solvedProcessesInfo.sort((obj1, obj2) => { + if (obj1.at > obj2.at) return 1; + if (obj1.at < obj2.at) return -1; + if (obj1.job > obj2.job) return 1; + if (obj1.job < obj2.job) return -1; + return 0; }); - // Push new processes to readyQueue - readyQueue.push(...processToArriveInThisCycle); - - // Requeueing (move head/first item to tail/last) - readyQueue.push(readyQueue.shift()); - - // When the process finished executing - if (remainingTime[processToExecute.job] === 0) { - const indexToRemoveUJ = unfinishedJobs.indexOf(processToExecute); - if (indexToRemoveUJ > -1) { - unfinishedJobs.splice(indexToRemoveUJ, 1); - } - const indexToRemoveRQ = readyQueue.indexOf(processToExecute); - if (indexToRemoveRQ > -1) { - readyQueue.splice(indexToRemoveRQ, 1); - } - - solvedProcessesInfo.push({ - ...processToExecute, - ft: currentTime, - tat: currentTime - processToExecute.at, - wat: currentTime - processToExecute.at - processToExecute.bt, - }); - } - } - - // Sort the processes arrival time and then by job name - solvedProcessesInfo.sort((obj1, obj2) => { - if (obj1.at > obj2.at) return 1; - if (obj1.at < obj2.at) return -1; - if (obj1.job > obj2.job) return 1; - if (obj1.job < obj2.job) return -1; - return 0; - }); - - return { solvedProcessesInfo, ganttChartInfo }; + return { solvedProcessesInfo, ganttChartInfo }; }; diff --git a/src/algorithms/sjf.ts b/src/algorithms/sjf.ts index 14f6908..b042083 100644 --- a/src/algorithms/sjf.ts +++ b/src/algorithms/sjf.ts @@ -1,144 +1,137 @@ -import { ganttChartInfoType } from '.'; +import { GanttChartInfoType } from '.'; export const sjf = (arrivalTime: number[], burstTime: number[]) => { - const processesInfo = arrivalTime - .map((item, index) => { - const job = - arrivalTime.length > 26 - ? `P${index + 1}` - : (index + 10).toString(36).toUpperCase(); - - return { - job, - at: item, - bt: burstTime[index], - }; - }) - .sort((obj1, obj2) => { - if (obj1.at > obj2.at) return 1; - if (obj1.at < obj2.at) return -1; - if (obj1.bt > obj2.bt) return 1; - if (obj1.bt < obj2.bt) return -1; - return 0; - }); - - let finishTime: number[] = []; - let ganttChartInfo: ganttChartInfoType = []; - - const solvedProcessesInfo = []; - const readyQueue = []; - const finishedJobs = []; - - for (let i = 0; i < processesInfo.length; i++) { - if (i === 0) { - readyQueue.push(processesInfo[0]); - finishTime.push(processesInfo[0].at + processesInfo[0].bt); - solvedProcessesInfo.push({ - ...processesInfo[0], - ft: finishTime[0], - tat: finishTime[0] - processesInfo[0].at, - wat: finishTime[0] - processesInfo[0].at - processesInfo[0].bt, - }); - - processesInfo.forEach((p) => { - if (p.at <= finishTime[0] && !readyQueue.includes(p)) { - readyQueue.push(p); - } - }); - - readyQueue.shift(); - finishedJobs.push(processesInfo[0]); - - ganttChartInfo.push({ - job: processesInfo[0].job, - start: processesInfo[0].at, - stop: finishTime[0], - }); - } else { - if ( - readyQueue.length === 0 && - finishedJobs.length !== processesInfo.length - ) { - const unfinishedJobs = processesInfo - .filter((p) => { - return !finishedJobs.includes(p); - }) - .sort((a, b) => { - if (a.at > b.at) return 1; - if (a.at < b.at) return -1; - if (a.bt > b.bt) return 1; - if (a.bt < a.bt) return -1; + const processesInfo = arrivalTime + .map((item, index) => ({ + job: index, + at: item, + bt: burstTime[index], + })) + .sort((obj1, obj2) => { + if (obj1.at > obj2.at) return 1; + if (obj1.at < obj2.at) return -1; + if (obj1.bt > obj2.bt) return 1; + if (obj1.bt < obj2.bt) return -1; return 0; - }); - readyQueue.push(unfinishedJobs[0]); - } - - const rqSortedByBT = [...readyQueue].sort((a, b) => { - if (a.bt > b.bt) return 1; - if (a.bt < b.bt) return -1; - if (a.at > b.at) return 1; - if (a.at < b.at) return -1; - return 0; - }); - - const processToExecute = rqSortedByBT[0]; - - const previousFinishTime = finishTime[finishTime.length - 1]; - - if (processToExecute.at > previousFinishTime) { - finishTime.push(processToExecute.at + processToExecute.bt); - const newestFinishTime = finishTime[finishTime.length - 1]; - ganttChartInfo.push({ - job: processToExecute.job, - start: processToExecute.at, - stop: newestFinishTime, }); - } else { - finishTime.push(previousFinishTime + processToExecute.bt); - const newestFinishTime = finishTime[finishTime.length - 1]; - ganttChartInfo.push({ - job: processToExecute.job, - start: previousFinishTime, - stop: newestFinishTime, - }); - } - - const newestFinishTime = finishTime[finishTime.length - 1]; - - solvedProcessesInfo.push({ - ...processToExecute, - ft: newestFinishTime, - tat: newestFinishTime - processToExecute.at, - wat: newestFinishTime - processToExecute.at - processToExecute.bt, - }); - - processesInfo.forEach((p) => { - if ( - p.at <= newestFinishTime && - !readyQueue.includes(p) && - !finishedJobs.includes(p) - ) { - readyQueue.push(p); + + const finishTime: number[] = []; + const ganttChartInfo: GanttChartInfoType = []; + + const solvedProcessesInfo = []; + const readyQueue = []; + const finishedJobs = []; + + for (let i = 0; i < processesInfo.length; i++) { + if (i === 0) { + readyQueue.push(processesInfo[0]); + finishTime.push(processesInfo[0].at + processesInfo[0].bt); + solvedProcessesInfo.push({ + ...processesInfo[0], + ft: finishTime[0], + tat: finishTime[0] - processesInfo[0].at, + wat: finishTime[0] - processesInfo[0].at - processesInfo[0].bt, + }); + + processesInfo.forEach((p) => { + if (p.at <= finishTime[0] && !readyQueue.includes(p)) { + readyQueue.push(p); + } + }); + + readyQueue.shift(); + finishedJobs.push(processesInfo[0]); + + ganttChartInfo.push({ + job: processesInfo[0].job, + start: processesInfo[0].at, + stop: finishTime[0], + }); + } else { + if ( + readyQueue.length === 0 && + finishedJobs.length !== processesInfo.length + ) { + const unfinishedJobs = processesInfo + .filter((p) => { + return !finishedJobs.includes(p); + }) + .sort((a, b) => { + if (a.at > b.at) return 1; + if (a.at < b.at) return -1; + if (a.bt > b.bt) return 1; + if (a.bt < a.bt) return -1; + return 0; + }); + readyQueue.push(unfinishedJobs[0]); + } + + const rqSortedByBT = [...readyQueue].sort((a, b) => { + if (a.bt > b.bt) return 1; + if (a.bt < b.bt) return -1; + if (a.at > b.at) return 1; + if (a.at < b.at) return -1; + return 0; + }); + + const processToExecute = rqSortedByBT[0]; + + const previousFinishTime = finishTime[finishTime.length - 1]; + + if (processToExecute.at > previousFinishTime) { + finishTime.push(processToExecute.at + processToExecute.bt); + const newestFinishTime = finishTime[finishTime.length - 1]; + ganttChartInfo.push({ + job: processToExecute.job, + start: processToExecute.at, + stop: newestFinishTime, + }); + } else { + finishTime.push(previousFinishTime + processToExecute.bt); + const newestFinishTime = finishTime[finishTime.length - 1]; + ganttChartInfo.push({ + job: processToExecute.job, + start: previousFinishTime, + stop: newestFinishTime, + }); + } + + const newestFinishTime = finishTime[finishTime.length - 1]; + + solvedProcessesInfo.push({ + ...processToExecute, + ft: newestFinishTime, + tat: newestFinishTime - processToExecute.at, + wat: newestFinishTime - processToExecute.at - processToExecute.bt, + }); + + processesInfo.forEach((p) => { + if ( + p.at <= newestFinishTime && + !readyQueue.includes(p) && + !finishedJobs.includes(p) + ) { + readyQueue.push(p); + } + }); + + const indexToRemove = readyQueue.indexOf(processToExecute); + if (indexToRemove > -1) { + readyQueue.splice(indexToRemove, 1); + } + + finishedJobs.push(processToExecute); } - }); + } - const indexToRemove = readyQueue.indexOf(processToExecute); - if (indexToRemove > -1) { - readyQueue.splice(indexToRemove, 1); - } + // Sort the processes by job name within arrival time + solvedProcessesInfo.sort((obj1, obj2) => { + if (obj1.at > obj2.at) return 1; + if (obj1.at < obj2.at) return -1; + if (obj1.job > obj2.job) return 1; + if (obj1.job < obj2.job) return -1; + return 0; + }); - finishedJobs.push(processToExecute); - } - } - - // Sort the processes by job name within arrival time - solvedProcessesInfo.sort((obj1, obj2) => { - if (obj1.at > obj2.at) return 1; - if (obj1.at < obj2.at) return -1; - if (obj1.job > obj2.job) return 1; - if (obj1.job < obj2.job) return -1; - return 0; - }); - - return { solvedProcessesInfo, ganttChartInfo }; + return { solvedProcessesInfo, ganttChartInfo }; }; diff --git a/src/algorithms/srtf.ts b/src/algorithms/srtf.ts index 16da942..83fab70 100644 --- a/src/algorithms/srtf.ts +++ b/src/algorithms/srtf.ts @@ -1,182 +1,176 @@ -import { ganttChartInfoType } from '.'; +import { GanttChartInfoType } from '.'; export const srtf = (arrivalTime: number[], burstTime: number[]) => { - const processesInfo = arrivalTime - .map((item, index) => { - const job = - arrivalTime.length > 26 - ? `P${index + 1}` - : (index + 10).toString(36).toUpperCase(); - - return { - job, - at: item, - bt: burstTime[index], - }; - }) - .sort((obj1, obj2) => { - if (obj1.at > obj2.at) return 1; - if (obj1.at < obj2.at) return -1; - if (obj1.bt > obj2.bt) return 1; - if (obj1.bt < obj2.bt) return -1; - return 0; - }); - - const solvedProcessesInfo = []; - const ganttChartInfo: ganttChartInfoType = []; - - const readyQueue = []; - let currentTime = processesInfo[0].at; - const unfinishedJobs = [...processesInfo]; - - const remainingTime = processesInfo.reduce((acc, process) => { - acc[process.job] = process.bt; - return acc; - }, {}); - - readyQueue.push(unfinishedJobs[0]); - while ( - Object.values(remainingTime).reduce((acc: number, cur: number) => { - return acc + cur; - }, 0) && - unfinishedJobs.length > 0 - ) { - let prevIdle = false; - if (readyQueue.length === 0 && unfinishedJobs.length > 0) { - prevIdle = true; - readyQueue.push(unfinishedJobs[0]); - } - - readyQueue.sort((a, b) => { - // Equal-priority processes are scheduled in FCFS order. - if (remainingTime[a.job] > remainingTime[b.job]) return 1; - if (remainingTime[a.job] < remainingTime[b.job]) return -1; - return 0; - }); - - const processToExecute = readyQueue[0]; - - const processATLessThanBT = processesInfo.filter((p) => { - let curr: number = currentTime; - if (prevIdle) { - curr = processToExecute.at; - } - - return ( - p.at <= remainingTime[processToExecute.job] + curr && - p !== processToExecute && - !readyQueue.includes(p) && - unfinishedJobs.includes(p) - ); - }); - - let gotInterruption = false; - processATLessThanBT.some((p) => { - if (prevIdle) { - currentTime = processToExecute.at; - } - - const amount = p.at - currentTime; - - if (currentTime >= p.at) { - readyQueue.push(p); - } - - if (p.bt < remainingTime[processToExecute.job] - amount) { - remainingTime[processToExecute.job] -= amount; - readyQueue.push(p); - const prevCurrentTime = currentTime; - currentTime += amount; - ganttChartInfo.push({ - job: processToExecute.job, - start: prevCurrentTime, - stop: currentTime, + const processesInfo = arrivalTime + .map((item, index) => ({ + job: index, + at: item, + bt: burstTime[index], + }) + ) + .sort((obj1, obj2) => { + if (obj1.at > obj2.at) return 1; + if (obj1.at < obj2.at) return -1; + if (obj1.bt > obj2.bt) return 1; + if (obj1.bt < obj2.bt) return -1; + return 0; }); - gotInterruption = true; - return true; - } - }); - const processToArrive = processesInfo.filter((p) => { - return ( - p.at <= currentTime && - p !== processToExecute && - !readyQueue.includes(p) && - unfinishedJobs.includes(p) - ); - }); + const solvedProcessesInfo = []; + const ganttChartInfo: GanttChartInfoType = []; + + const readyQueue = []; + let currentTime = processesInfo[0].at; + const unfinishedJobs = [...processesInfo]; + + const remainingTime = processesInfo.reduce((acc, process) => { + acc[process.job] = process.bt; + return acc; + }, {}); + + readyQueue.push(unfinishedJobs[0]); + while ( + Object.values(remainingTime).reduce((acc: number, cur: number) => { + return acc + cur; + }, 0) && + unfinishedJobs.length > 0 + ) { + let prevIdle = false; + if (readyQueue.length === 0 && unfinishedJobs.length > 0) { + prevIdle = true; + readyQueue.push(unfinishedJobs[0]); + } + + readyQueue.sort((a, b) => { + // Equal-priority processes are scheduled in FCFS order. + if (remainingTime[a.job] > remainingTime[b.job]) return 1; + if (remainingTime[a.job] < remainingTime[b.job]) return -1; + return 0; + }); - // Push new processes to readyQueue - readyQueue.push(...processToArrive); + const processToExecute = readyQueue[0]; - if (!gotInterruption) { - if (prevIdle) { - const remainingT = remainingTime[processToExecute.job]; - remainingTime[processToExecute.job] -= remainingT; - currentTime = processToExecute.at + remainingT; + const processATLessThanBT = processesInfo.filter((p) => { + let curr: number = currentTime; + if (prevIdle) { + curr = processToExecute.at; + } - processATLessThanBT.forEach((p) => { - if (currentTime >= p.at && !readyQueue.includes(p)) { - readyQueue.push(p); - } + return ( + p.at <= remainingTime[processToExecute.job] + curr && + p !== processToExecute && + !readyQueue.includes(p) && + unfinishedJobs.includes(p) + ); }); - ganttChartInfo.push({ - job: processToExecute.job, - start: processToExecute.at, - stop: currentTime, + let gotInterruption = false; + processATLessThanBT.some((p) => { + if (prevIdle) { + currentTime = processToExecute.at; + } + + const amount = p.at - currentTime; + + if (currentTime >= p.at) { + readyQueue.push(p); + } + + if (p.bt < remainingTime[processToExecute.job] - amount) { + remainingTime[processToExecute.job] -= amount; + readyQueue.push(p); + const prevCurrentTime = currentTime; + currentTime += amount; + ganttChartInfo.push({ + job: processToExecute.job, + start: prevCurrentTime, + stop: currentTime, + }); + + gotInterruption = true; + return true; + } }); - } else { - const remainingT = remainingTime[processToExecute.job]; - remainingTime[processToExecute.job] -= remainingT; - const prevCurrentTime = currentTime; - currentTime += remainingT; - - processATLessThanBT.forEach((p) => { - if (currentTime >= p.at && !readyQueue.includes(p)) { - readyQueue.push(p); - } + const processToArrive = processesInfo.filter((p) => { + return ( + p.at <= currentTime && + p !== processToExecute && + !readyQueue.includes(p) && + unfinishedJobs.includes(p) + ); }); - ganttChartInfo.push({ - job: processToExecute.job, - start: prevCurrentTime, - stop: currentTime, - }); - } + // Push new processes to readyQueue + readyQueue.push(...processToArrive); + + if (!gotInterruption) { + if (prevIdle) { + const remainingT = remainingTime[processToExecute.job]; + remainingTime[processToExecute.job] -= remainingT; + currentTime = processToExecute.at + remainingT; + + processATLessThanBT.forEach((p) => { + if (currentTime >= p.at && !readyQueue.includes(p)) { + readyQueue.push(p); + } + }); + + ganttChartInfo.push({ + job: processToExecute.job, + start: processToExecute.at, + stop: currentTime, + }); + } else { + const remainingT = remainingTime[processToExecute.job]; + remainingTime[processToExecute.job] -= remainingT; + const prevCurrentTime = currentTime; + currentTime += remainingT; + + processATLessThanBT.forEach((p) => { + if (currentTime >= p.at && !readyQueue.includes(p)) { + readyQueue.push(p); + } + }); + + ganttChartInfo.push({ + job: processToExecute.job, + start: prevCurrentTime, + stop: currentTime, + }); + } + } + + // Requeueing (move head/first item to tail/last) + readyQueue.push(readyQueue.shift()); + + // When the process finished executing + if (remainingTime[processToExecute.job] === 0) { + const indexToRemoveUJ = unfinishedJobs.indexOf(processToExecute); + if (indexToRemoveUJ > -1) { + unfinishedJobs.splice(indexToRemoveUJ, 1); + } + const indexToRemoveRQ = readyQueue.indexOf(processToExecute); + if (indexToRemoveRQ > -1) { + readyQueue.splice(indexToRemoveRQ, 1); + } + + solvedProcessesInfo.push({ + ...processToExecute, + ft: currentTime, + tat: currentTime - processToExecute.at, + wat: currentTime - processToExecute.at - processToExecute.bt, + }); + } } - // Requeueing (move head/first item to tail/last) - readyQueue.push(readyQueue.shift()); - - // When the process finished executing - if (remainingTime[processToExecute.job] === 0) { - const indexToRemoveUJ = unfinishedJobs.indexOf(processToExecute); - if (indexToRemoveUJ > -1) { - unfinishedJobs.splice(indexToRemoveUJ, 1); - } - const indexToRemoveRQ = readyQueue.indexOf(processToExecute); - if (indexToRemoveRQ > -1) { - readyQueue.splice(indexToRemoveRQ, 1); - } - - solvedProcessesInfo.push({ - ...processToExecute, - ft: currentTime, - tat: currentTime - processToExecute.at, - wat: currentTime - processToExecute.at - processToExecute.bt, - }); - } - } - - // Sort the processes by job name within arrival time - solvedProcessesInfo.sort((obj1, obj2) => { - if (obj1.at > obj2.at) return 1; - if (obj1.at < obj2.at) return -1; - if (obj1.job > obj2.job) return 1; - if (obj1.job < obj2.job) return -1; - return 0; - }); - - return { solvedProcessesInfo, ganttChartInfo }; + // Sort the processes by job name within arrival time + solvedProcessesInfo.sort((obj1, obj2) => { + if (obj1.at > obj2.at) return 1; + if (obj1.at < obj2.at) return -1; + if (obj1.job > obj2.job) return 1; + if (obj1.job < obj2.job) return -1; + return 0; + }); + + return { solvedProcessesInfo, ganttChartInfo }; }; diff --git a/src/components/Output/GanttChart.tsx b/src/components/Output/GanttChart.tsx index 8e7702f..bcc8f44 100644 --- a/src/components/Output/GanttChart.tsx +++ b/src/components/Output/GanttChart.tsx @@ -1,5 +1,5 @@ import { useLayoutEffect, useRef, useState } from 'react'; -import { ganttChartInfoType } from '../../algorithms'; +import { GanttChartInfoType } from '../../algorithms'; import styled from 'styled-components'; import { media } from '../GlobalStyle.css'; @@ -17,7 +17,7 @@ const Title = styled.h2` font-size: 18px; ${media['600']`font-size: 16px;`} margin: 0 0 0.5rem 0; - color: #424242; + backgroundColor: #424242; `; const JobContainer = styled.div` @@ -28,8 +28,8 @@ const Job = styled.div` width: 40px; height: 35px; border: 1px solid #8da6ff; - background-color: #edf4ff; - color: #424242; + background-backgroundColor: #edf4ff; + backgroundColor: #424242; ${media['600']` width: 32px; height: 27px; @@ -54,7 +54,7 @@ const Time = styled.div` font-size: 14px; `} border: 1px solid #fff; - color: #444e5c; + backgroundColor: #444e5c; &:not(:last-child) { margin-right: -1px; @@ -73,183 +73,221 @@ const MultilineContainer = styled.div` `; type GanttChartProps = { - ganttChartInfo: ganttChartInfoType; + ganttChartInfo: GanttChartInfoType; }; const GanttChart = ({ ganttChartInfo }: GanttChartProps) => { - const containerEl = useRef(null); - const [windowWidth, setWindowWidth] = useState(null); - const [containerWidth, setContainerWidth] = useState(null); - - const job: string[] = []; - const time: number[] = []; - ganttChartInfo.forEach((item, index) => { - if (index === 0) { - job.push(item.job); - time.push(item.start, item.stop); - } else if (time.slice(-1)[0] === item.start) { - job.push(item.job); - time.push(item.stop); - } else if (time.slice(-1)[0] !== item.start) { - job.push('_', item.job); - time.push(item.start, item.stop); - } - }); + const containerEl = useRef(null); + const [windowWidth, setWindowWidth] = useState(null); + const [containerWidth, setContainerWidth] = useState(null); + + const jobs: number[] = []; + const lastJobIndex: { [key: number]: number } = {}; + + const time: number[] = []; + const BLANK_CELL = -1 + lastJobIndex[BLANK_CELL] = 9999 + + ganttChartInfo.forEach((item, index) => { + if (index === 0) { + jobs.push(item.job); + time.push(item.start, item.stop); + lastJobIndex[item.job] = (lastJobIndex[item.job] || 0) + 1; + } else if (time.slice(-1)[0] === item.start) { + jobs.push(item.job); + time.push(item.stop); + lastJobIndex[item.job] = (lastJobIndex[item.job] || 0) + 1; + } else if (time.slice(-1)[0] !== item.start) { + jobs.push(BLANK_CELL, item.job); + time.push(item.start, item.stop); + } + }); + + useLayoutEffect(() => { + function updateSize() { + setWindowWidth(window.innerWidth); + setContainerWidth(containerEl.current.offsetWidth); + } + window.addEventListener('resize', updateSize); + updateSize(); + return () => window.removeEventListener('resize', updateSize); + }, []); - useLayoutEffect(() => { - function updateSize() { - setWindowWidth(window.innerWidth); - setContainerWidth(containerEl.current.offsetWidth); + let itemWidth = 0; + if (windowWidth <= 600) { + itemWidth = 32; + } else { + itemWidth = 40; } - window.addEventListener('resize', updateSize); - updateSize(); - return () => window.removeEventListener('resize', updateSize); - }, []); - - let itemWidth = 0; - if (windowWidth <= 600) { - itemWidth = 32; - } else { - itemWidth = 40; - } - const timeContainerWidth = time.length * itemWidth - (time.length - 1); + const timeContainerWidth = time.length * itemWidth - (time.length - 1); - let maxTimeItemCount = ~~(containerWidth / itemWidth); + let maxTimeItemCount = ~~(containerWidth / itemWidth); - let numberOfLines = 0; - let acc = 0; - while (true) { - if (containerWidth === null) { - break; + let numberOfLines = 0; + let acc = 0; + while (true) { + if (containerWidth === null) { + break; + } + acc += maxTimeItemCount - 1; + numberOfLines++; + if (acc >= time.length) { + acc -= maxTimeItemCount - 1; + break; + } } - acc += maxTimeItemCount - 1; - numberOfLines++; - if (acc >= time.length) { - acc -= maxTimeItemCount - 1; - break; + + // If index of last time item equal to acc + let lastLineItemCount: number; + if (time.length - 1 === acc) { + lastLineItemCount = 0; + numberOfLines--; + } else { + lastLineItemCount = time.length - acc; } - } - // If index of last time item equal to acc - let lastLineItemCount: number; - if (time.length - 1 === acc) { - lastLineItemCount = 0; - numberOfLines--; - } else { - lastLineItemCount = time.length - acc; - } + let timeCounter = 0; + let jobCounter = 0; - let timeCounter = 0; - let jobCounter = 0; - - return ( - - Gantt Chart - {containerWidth !== null && containerWidth <= timeContainerWidth && ( - <> - {Array.from({ length: numberOfLines }).map((_, ind) => { - if (ind === numberOfLines - 1 && lastLineItemCount !== 0) { - return ( - - - {Array.from({ - length: lastLineItemCount - 1, - }).map((_, i) => ( - - {job[jobCounter + 1 + i]} - - ))} - - - {Array.from({ - length: lastLineItemCount, - }).map((_, i) => ( - - ))} - - - ); - } else if (ind == 0) { - timeCounter += maxTimeItemCount - 1; - jobCounter += timeCounter - 1; - return ( - - - {Array.from({ length: jobCounter + 1 }).map((_, i) => ( - - {job[i]} - - ))} - - - {Array.from({ length: timeCounter + ind + 1 }).map( - (_, i) => ( - - ) - )} - - - ); - } else { - let prevCounter = timeCounter; - timeCounter += maxTimeItemCount - 1; - let prevJobCounter = jobCounter; - jobCounter += maxTimeItemCount - 1; - return ( - - - {Array.from({ length: maxTimeItemCount - 1 }).map( - (_, i) => ( - - {job[prevJobCounter + i + 1]} - - ) - )} - - - {Array.from({ length: maxTimeItemCount }).map((_, i) => ( - - ))} - - - ); + return ( + + Gantt Chart + {containerWidth !== null && containerWidth <= timeContainerWidth && ( + <> + {Array.from({ length: numberOfLines }).map((_, ind) => { + if (ind === numberOfLines - 1 && lastLineItemCount !== 0) { + return ( + + + {Array.from({ + length: lastLineItemCount - 1, + }).map((_, i) => { + const index = jobCounter + 1 + i + const job = jobs[index] + const isLastJobIndex = !(--lastJobIndex[job]) + return ( + + {job == -1 ? "" : `P${job}`} + + ) + })} + + + {Array.from({ + length: lastLineItemCount, + }).map((_, i) => ( + + ))} + + + ); + } else if (ind == 0) { + timeCounter += maxTimeItemCount - 1; + jobCounter += timeCounter - 1; + return ( + + + {Array.from({ length: jobCounter + 1 }).map((_, i) => { + const job = jobs[i] + const isLastJobIndex = !(--lastJobIndex[job]) + return ( + + {job == -1 ? "" : `P${job}`} + + ) + })} + + + {Array.from({ length: timeCounter + ind + 1 }).map( + (_, i) => ( + + ) + )} + + + ); + } else { + let prevCounter = timeCounter; + timeCounter += maxTimeItemCount - 1; + let prevJobCounter = jobCounter; + jobCounter += maxTimeItemCount - 1; + return ( + + + {Array.from({ length: maxTimeItemCount - 1 }).map( + (_, i) => { + const index = prevJobCounter + i + 1 + const job = jobs[index] + const isLastJobIndex = !(--lastJobIndex[job]) + return ( + + {job == -1 ? "" : `P${job}`} + + ) + } + )} + + + {Array.from({ length: maxTimeItemCount }).map((_, i) => ( + + ))} + + + ); + } + })} + + ) + } + { + containerWidth !== null && containerWidth > timeContainerWidth && ( + <> + + {jobs.map((job, index) => { + const isLastJobIndex = !(--lastJobIndex[job]) + return ( + + {job == -1 ? "" : `P${job}`} + + ) + })} + + + {time.map((time, index) => ( + + ))} + + + ) } - })} - - )} - {containerWidth !== null && containerWidth > timeContainerWidth && ( - <> - - {job.map((job, index) => ( - - {job} - - ))} - - - {time.map((time, index) => ( - - ))} - - - )} - - ); + + ); }; export default GanttChart; diff --git a/src/components/Output/Table.tsx b/src/components/Output/Table.tsx index 1229bdb..459d116 100644 --- a/src/components/Output/Table.tsx +++ b/src/components/Output/Table.tsx @@ -58,76 +58,76 @@ const HeaderCell = styled.th` `; const precisionRound = (number: number, precision: number) => { - const factor = Math.pow(10, precision); - return Math.round(number * factor) / factor; + const factor = Math.pow(10, precision); + return Math.round(number * factor) / factor; }; type TableProps = { - solvedProcessesInfo: { - job: string; - at: number; - bt: number; - ft: number; - tat: number; - wat: number; - }[]; + solvedProcessesInfo: { + job: number; + at: number; + bt: number; + ft: number; + tat: number; + wat: number; + }[]; }; const Table = ({ solvedProcessesInfo }: TableProps) => { - const total = (array: number[]) => - array.reduce((acc, currentValue) => acc + currentValue, 0); + const total = (array: number[]) => + array.reduce((acc, currentValue) => acc + currentValue, 0); - const numberOfProcesses = solvedProcessesInfo.length; - const turnaoundTime = solvedProcessesInfo.map((process) => process.tat); - const waitingTime = solvedProcessesInfo.map((process) => process.wat); + const numberOfProcesses = solvedProcessesInfo.length; + const turnaoundTime = solvedProcessesInfo.map((process) => process.tat); + const waitingTime = solvedProcessesInfo.map((process) => process.wat); - const totalTAT = total(turnaoundTime); - const averageTAT = totalTAT / numberOfProcesses; + const totalTAT = total(turnaoundTime); + const averageTAT = totalTAT / numberOfProcesses; - const totalWAT = total(waitingTime); - const averageWAT = totalWAT / numberOfProcesses; + const totalWAT = total(waitingTime); + const averageWAT = totalWAT / numberOfProcesses; - return ( - - - - - Job - Arrival Time - Burst Time - Finish Time - Turnaround Time - Waiting Time - - - - {solvedProcessesInfo.map((item, index) => ( - - {item.job} - {item.at} - {item.bt} - {item.ft} - {item.tat} - {item.wat} - - ))} - { - - - Average - - - {totalTAT} / {numberOfProcesses} = {precisionRound(averageTAT, 3)} - - - {totalWAT} / {numberOfProcesses} = {precisionRound(averageWAT, 3)} - - - } - - - - ); + return ( + + + + + Job + Arrival Time + Burst Time + Finish Time + Turnaround Time + Waiting Time + + + + {solvedProcessesInfo.map((item, index) => ( + + P{item.job} + {item.at} + {item.bt} + {item.ft} + {item.tat} + {item.wat} + + ))} + { + + + Average + + + {totalTAT} / {numberOfProcesses} = {precisionRound(averageTAT, 3)} + + + {totalWAT} / {numberOfProcesses} = {precisionRound(averageWAT, 3)} + + + } + + + + ); }; export default Table; diff --git a/src/tests/fcfs.test.ts b/src/tests/fcfs.test.ts new file mode 100644 index 0000000..4ab15f3 --- /dev/null +++ b/src/tests/fcfs.test.ts @@ -0,0 +1,53 @@ +import { fcfs } from '../algorithms/fcfs'; + +test.each([ + [[0], [4], { + solvedProcessesInfo: [ + { job: 0, at: 0, bt: 4, ft: 4, tat: 4, wat: 0 }, + ], + ganttChartInfo: [ + { job: 0, start: 0, stop: 4 }, + ] + }], + [[1], [4], { + solvedProcessesInfo: [ + { job: 0, at: 1, bt: 4, ft: 5, tat: 4, wat: 0 }, + ], + ganttChartInfo: [ + { job: 0, start: 1, stop: 5 }, + ] + }], + [[0, 0, 0, 0], [4, 6, 2, 5], { + solvedProcessesInfo: [ + { job: 0, at: 0, bt: 4, ft: 4, tat: 4, wat: 0 }, + { job: 1, at: 0, bt: 6, ft: 10, tat: 10, wat: 4 }, + { job: 2, at: 0, bt: 2, ft: 12, tat: 12, wat: 10 }, + { job: 3, at: 0, bt: 5, ft: 17, tat: 17, wat: 12 } + ], + ganttChartInfo: [ + { job: 0, start: 0, stop: 4 }, + { job: 1, start: 4, stop: 10 }, + { job: 2, start: 10, stop: 12 }, + { job: 3, start: 12, stop: 17 } + ] + }], + [[0, 1, 2, 3, 4], [5, 3, 8, 6, 2], { + solvedProcessesInfo: [ + { job: 0, at: 0, bt: 5, ft: 5, tat: 5, wat: 0 }, + { job: 1, at: 1, bt: 3, ft: 8, tat: 7, wat: 4 }, + { job: 2, at: 2, bt: 8, ft: 16, tat: 14, wat: 6 }, + { job: 3, at: 3, bt: 6, ft: 22, tat: 19, wat: 13 }, + { job: 4, at: 4, bt: 2, ft: 24, tat: 20, wat: 18 }, + ], + ganttChartInfo: [ + { job: 0, start: 0, stop: 5 }, + { job: 1, start: 5, stop: 8 }, + { job: 2, start: 8, stop: 16 }, + { job: 3, start: 16, stop: 22 }, + { job: 4, start: 22, stop: 24 }, + ] + }], +])('FCFS test %#', (arrivalTime, burstTime, expected) => { + expect(fcfs(arrivalTime, burstTime)).toEqual(expected); +}); + diff --git a/src/tests/npp.test.ts b/src/tests/npp.test.ts new file mode 100644 index 0000000..ade28ba --- /dev/null +++ b/src/tests/npp.test.ts @@ -0,0 +1,25 @@ +import { npp } from '../algorithms/npp'; + +test.each([ + [ + [0, 1, 2, 3], // Arrival times + [5, 4, 2, 1], // Burst times + [2, 1, 3, 4], // Priorities (lower value = higher priority) + { + solvedProcessesInfo: [ + { job: 1, at: 1, bt: 4, ft: 5, tat: 4, wat: 0 }, + { job: 0, at: 0, bt: 5, ft: 10, tat: 10, wat: 5 }, + { job: 2, at: 2, bt: 2, ft: 12, tat: 10, wat: 8 }, + { job: 3, at: 3, bt: 1, ft: 13, tat: 10, wat: 9 } + ], + ganttChartInfo: [ + { job: 1, start: 1, stop: 5 }, + { job: 0, start: 5, stop: 10 }, + { job: 2, start: 10, stop: 12 }, + { job: 3, start: 12, stop: 13 } + ] + } + ] +])('NPP test %#', (arrivalTime, burstTime, priorities, expected) => { + expect(npp(arrivalTime, burstTime, priorities)).toEqual(expected); +}); diff --git a/src/tests/pp.test.ts b/src/tests/pp.test.ts new file mode 100644 index 0000000..eb322ac --- /dev/null +++ b/src/tests/pp.test.ts @@ -0,0 +1,25 @@ +import { pp } from '../algorithms/pp'; + +test.each([ + [ + [0, 1, 2, 3], // Arrival times + [5, 4, 2, 1], // Burst times + [2, 1, 3, 4], // Priorities + { + solvedProcessesInfo: [ + { job: 3, at: 3, bt: 1, priority: 4, ft: 4, tat: 1, wat: 0 }, + { job: 1, at: 1, bt: 4, priority: 1, ft: 8, tat: 7, wat: 3 }, + { job: 2, at: 2, bt: 2, priority: 3, ft: 10, tat: 8, wat: 6 }, + { job: 0, at: 0, bt: 5, priority: 2, ft: 15, tat: 15, wat: 10 } + ], + ganttChartInfo: [ + { job: 3, start: 3, stop: 4 }, + { job: 1, start: 4, stop: 8 }, + { job: 2, start: 8, stop: 10 }, + { job: 0, start: 10, stop: 15 } + ] + } + ] +])('PP test %#', (arrivalTime, burstTime, priorities, expected) => { + expect(pp(arrivalTime, burstTime, priorities)).toEqual(expected); +}); diff --git a/src/tests/rr.test.ts b/src/tests/rr.test.ts new file mode 100644 index 0000000..5786999 --- /dev/null +++ b/src/tests/rr.test.ts @@ -0,0 +1,52 @@ +import { rr } from '../algorithms/rr'; + +test.each([ + [[0], [4], 2, { + solvedProcessesInfo: [ + { job: 0, at: 0, bt: 4, ft: 4, tat: 4, wat: 0 }, + ], + ganttChartInfo: [ + { job: 0, start: 0, stop: 4 }, + ] + }], + [[1], [4], 2, { + solvedProcessesInfo: [ + { job: 0, at: 1, bt: 4, ft: 5, tat: 4, wat: 0 }, + ], + ganttChartInfo: [ + { job: 0, start: 1, stop: 5 }, + ] + }], + [[0, 0, 0, 0], [4, 6, 2, 5], 2, { + solvedProcessesInfo: [ + { job: 0, at: 0, bt: 4, ft: 6, tat: 6, wat: 2 }, + { job: 1, at: 0, bt: 6, ft: 17, tat: 17, wat: 11 }, + { job: 2, at: 0, bt: 2, ft: 2, tat: 2, wat: 0 }, + { job: 3, at: 0, bt: 5, ft: 11, tat: 11, wat: 6 }, + ], + ganttChartInfo: [ + { job: 0, start: 2, stop: 6 }, + { job: 1, start: 11, stop: 17 }, + { job: 2, start: 0, stop: 2 }, + { job: 3, start: 6, stop: 11 }, + ] + }], + [[0, 1, 2, 3, 4], [5, 3, 8, 6, 2], 2, { + solvedProcessesInfo: [ + { job: 0, at: 0, bt: 5, ft: 5, tat: 5, wat: 0 }, + { job: 1, at: 1, bt: 3, ft: 10, tat: 9, wat: 6 }, + { job: 2, at: 2, bt: 8, ft: 24, tat: 22, wat: 14 }, + { job: 3, at: 3, bt: 6, ft: 16, tat: 13, wat: 7 }, + { job: 4, at: 4, bt: 2, ft: 7, tat: 3, wat: 1 }, + ], + ganttChartInfo: [ + { job: 0, start: 0, stop: 5 }, + { job: 1, start: 7, stop: 10 }, + { job: 2, start: 16, stop: 24 }, + { job: 3, start: 10, stop: 16 }, + { job: 4, start: 5, stop: 7 }, + ] + }], +])('RR test %#', (arrivalTime, burstTime, timeQuantum, expected) => { + expect(rr(arrivalTime, burstTime, timeQuantum)).toEqual(expected); +}); diff --git a/src/tests/sjf.test.ts b/src/tests/sjf.test.ts new file mode 100644 index 0000000..fa4e999 --- /dev/null +++ b/src/tests/sjf.test.ts @@ -0,0 +1,53 @@ +import { sjf } from '../algorithms/sjf'; + +test.each([ + [[0], [4], { + solvedProcessesInfo: [ + { job: 0, at: 0, bt: 4, ft: 4, tat: 4, wat: 0 }, + ], + ganttChartInfo: [ + { job: 0, start: 0, stop: 4 }, + ] + }], + [[1], [4], { + solvedProcessesInfo: [ + { job: 0, at: 1, bt: 4, ft: 5, tat: 4, wat: 0 }, + ], + ganttChartInfo: [ + { job: 0, start: 1, stop: 5 }, + ] + }], + [[0, 0, 0, 0], [4, 6, 2, 5], { + solvedProcessesInfo: [ + { job: 0, at: 0, bt: 4, ft: 6, tat: 6, wat: 2 }, + { job: 1, at: 0, bt: 6, ft: 17, tat: 17, wat: 11 }, + { job: 2, at: 0, bt: 2, ft: 2, tat: 2, wat: 0 }, + { job: 3, at: 0, bt: 5, ft: 11, tat: 11, wat: 6 }, + ], + ganttChartInfo: [ + { job: 0, start: 2, stop: 6 }, + { job: 1, start: 11, stop: 17 }, + { job: 2, start: 0, stop: 2 }, + { job: 3, start: 6, stop: 11 }, + ] + }], + [[0, 1, 2, 3, 4], [5, 3, 8, 6, 2], { + solvedProcessesInfo: [ + { job: 0, at: 0, bt: 5, ft: 5, tat: 5, wat: 0 }, + { job: 1, at: 1, bt: 3, ft: 10, tat: 9, wat: 6 }, + { job: 2, at: 2, bt: 8, ft: 24, tat: 22, wat: 14 }, + { job: 3, at: 3, bt: 6, ft: 16, tat: 13, wat: 7 }, + { job: 4, at: 4, bt: 2, ft: 7, tat: 3, wat: 1 }, + ], + ganttChartInfo: [ + { job: 0, start: 0, stop: 5 }, + { job: 1, start: 7, stop: 10 }, + { job: 2, start: 16, stop: 24 }, + { job: 3, start: 10, stop: 16 }, + { job: 4, start: 5, stop: 7 }, + ] + }], +])('SJF test %#', (arrivalTime, burstTime, expected) => { + expect(sjf(arrivalTime, burstTime)).toEqual(expected); +}); + diff --git a/src/tests/srtf.test.ts b/src/tests/srtf.test.ts index 26952a7..4f2f7ce 100644 --- a/src/tests/srtf.test.ts +++ b/src/tests/srtf.test.ts @@ -1,325 +1,23 @@ import { srtf } from '../algorithms/srtf'; -test('SRTF test 1', () => { - const arrivalTime = [0, 1, 7, 9]; - const burstTime = [6, 4, 3, 1]; - expect(srtf(arrivalTime, burstTime)).toEqual({ - solvedProcessesInfo: [ - { - job: 'A', - at: 0, - bt: 6, - ft: 10, - tat: 10, - wat: 4, - }, - { - job: 'B', - at: 1, - bt: 4, - ft: 5, - tat: 4, - wat: 0, - }, - { - job: 'C', - at: 7, - bt: 3, - ft: 14, - tat: 7, - wat: 4, - }, - { - job: 'D', - at: 9, - bt: 1, - ft: 11, - tat: 2, - wat: 1, - }, - ], - ganttChartInfo: [ - { - job: 'A', - start: 0, - stop: 1, - }, - { - job: 'B', - start: 1, - stop: 5, - }, - { - job: 'A', - start: 5, - stop: 10, - }, - { - job: 'D', - start: 10, - stop: 11, - }, - { - job: 'C', - start: 11, - stop: 14, - }, - ], - }); +test.each([ + [ + [0, 0, 0], + [1, 2, 3], + { + solvedProcessesInfo: [ + { job: 0, at: 0, bt: 1, ft: 1, tat: 1, wat: 0 }, + { job: 1, at: 0, bt: 2, ft: 3, tat: 3, wat: 1 }, + { job: 2, at: 0, bt: 3, ft: 6, tat: 6, wat: 3 }, + ], + ganttChartInfo: [ + { job: 0, start: 0, stop: 1 }, + { job: 1, start: 1, stop: 3 }, + { job: 2, start: 3, stop: 6 }, + ] + } + ], +])('SRTF test %#', (arrivalTime, burstTime, expected) => { + expect(srtf(arrivalTime, burstTime)).toEqual(expected); }); -test('SRTF test 2', () => { - const arrivalTime = [0, 2, 2, 4]; - const burstTime = [7, 4, 5, 1]; - expect(srtf(arrivalTime, burstTime)).toEqual({ - solvedProcessesInfo: [ - { - job: 'A', - at: 0, - bt: 7, - ft: 17, - tat: 17, - wat: 10, - }, - { - job: 'B', - at: 2, - bt: 4, - ft: 7, - tat: 5, - wat: 1, - }, - { - job: 'C', - at: 2, - bt: 5, - ft: 12, - tat: 10, - wat: 5, - }, - { - job: 'D', - at: 4, - bt: 1, - ft: 5, - tat: 1, - wat: 0, - }, - ], - ganttChartInfo: [ - { - job: 'A', - start: 0, - stop: 2, - }, - { - job: 'B', - start: 2, - stop: 4, - }, - { - job: 'D', - start: 4, - stop: 5, - }, - { - job: 'B', - start: 5, - stop: 7, - }, - { - job: 'C', - start: 7, - stop: 12, - }, - { - job: 'A', - start: 12, - stop: 17, - }, - ], - }); -}); - -test('SRTF test 3', () => { - const arrivalTime = [31, 37, 21, 21, 11, 7, 7]; - const burstTime = [1, 6, 4, 6, 5, 3, 1]; - expect(srtf(arrivalTime, burstTime)).toEqual({ - solvedProcessesInfo: [ - { - job: 'F', - at: 7, - bt: 3, - ft: 11, - tat: 4, - wat: 1, - }, - { - job: 'G', - at: 7, - bt: 1, - ft: 8, - tat: 1, - wat: 0, - }, - { - job: 'E', - at: 11, - bt: 5, - ft: 16, - tat: 5, - wat: 0, - }, - { - job: 'C', - at: 21, - bt: 4, - ft: 25, - tat: 4, - wat: 0, - }, - { - job: 'D', - at: 21, - bt: 6, - ft: 31, - tat: 10, - wat: 4, - }, - { - job: 'A', - at: 31, - bt: 1, - ft: 32, - tat: 1, - wat: 0, - }, - { - job: 'B', - at: 37, - bt: 6, - ft: 43, - tat: 6, - wat: 0, - }, - ], - ganttChartInfo: [ - { - job: 'G', - start: 7, - stop: 8, - }, - { - job: 'F', - start: 8, - stop: 11, - }, - { - job: 'E', - start: 11, - stop: 16, - }, - { - job: 'C', - start: 21, - stop: 25, - }, - { - job: 'D', - start: 25, - stop: 31, - }, - { - job: 'A', - start: 31, - stop: 32, - }, - { - job: 'B', - start: 37, - stop: 43, - }, - ], - }); -}); - -test('SRTF test 4', () => { - const arrivalTime = [8, 2, 1, 3, 4]; - const burstTime = [3, 1, 3, 2, 4]; - expect(srtf(arrivalTime, burstTime)).toEqual({ - solvedProcessesInfo: [ - { - job: 'C', - at: 1, - bt: 3, - ft: 5, - tat: 4, - wat: 1, - }, - { - job: 'B', - at: 2, - bt: 1, - ft: 3, - tat: 1, - wat: 0, - }, - { - job: 'D', - at: 3, - bt: 2, - ft: 7, - tat: 4, - wat: 2, - }, - { - job: 'E', - at: 4, - bt: 4, - ft: 11, - tat: 7, - wat: 3, - }, - { - job: 'A', - at: 8, - bt: 3, - ft: 14, - tat: 6, - wat: 3, - }, - ], - ganttChartInfo: [ - { - job: 'C', - start: 1, - stop: 2, - }, - { - job: 'B', - start: 2, - stop: 3, - }, - { - job: 'C', - start: 3, - stop: 5, - }, - { - job: 'D', - start: 5, - stop: 7, - }, - { - job: 'E', - start: 7, - stop: 11, - }, - { - job: 'A', - start: 11, - stop: 14, - }, - ], - }); -});