import { findIndex, map, reduce, sort, concat, filter, reverse, equals, update, times } from 'rambda'; import type { JobId } from '../../types'; import { remove } from 'ramda'; import { fillCorrupted } from '../campbel'; type JobOperations = { jobId: JobId, operations: [{ t: number, name: string }, { t: number, name: string }] }; type JobOperationsWithC = { jobId: JobId, operations: [{ t: number, c: number, name: string }, { t: number, c: number, name: string }] }; const findMinT = (operations) => reduce( (t1, t2) => t1.t < t2.t ? t1 : t2, { t: Infinity }, operations ); const findMinJob = (jobsOperations: JobOperations[]): JobOperations => reduce( (minJob: JobOperations, jobOperations: JobOperations) => { const minJobT = findMinT(minJob.operations); const jobOperationsT = findMinT(jobOperations.operations); return minJobT.t < jobOperationsT.t ? minJob : jobOperations; }, { operations: [ { t: Infinity }, { t: Infinity } ] }, jobsOperations ); export const updateCTime = (jobsOperations: JobOperations[], processorCount: number): JobOperationsWithC[] => { let prev = 0; const cj = []; cj[0] = map((jobTime: JobOperations) => { prev += jobTime.operations[0].t; const operationC = { ...jobTime.operations[0], c: prev }; const operations = update(0, operationC, jobTime.operations); return { ...jobTime, operations }; }, jobsOperations); if (processorCount > 1) { times(i => { const processorI = i + 1; prev = cj[0][0].operations[0].c; cj[processorI] = map((jobTime: JobOperations) => { const conflicts = filter(({ c }) => prev < c, jobTime.operations); if (conflicts.length) { const maxConflict = sort((a, b) => b.c - a.c, conflicts)[0]; prev = maxConflict.c; } prev += jobTime.operations[processorI].t; const operationC = { ...jobTime.operations[processorI], c: prev }; const operations = update(processorI, operationC, jobTime.operations); return { ...jobTime, operations }; }, cj[i]); }, processorCount - 1); } return cj[processorCount - 1]; }; export const createSchedule = (jobsOperations: JobOperations[]): JobOperationsWithC[] => { jobsOperations = fillCorrupted(jobsOperations, 2); let I = jobsOperations; let L = [[], []]; while (I.length) { const minTJob = findMinJob(I); const { t: minT } = findMinT(minTJob.operations); const operationIndex = findIndex(o => o.t === minT, minTJob.operations); const minTJobIndex = findIndex(equals(minTJob), I); L[operationIndex].push(minTJob); I = remove(minTJobIndex, 1, I); } const LFinal = concat(L[0], reverse(L[1])); return updateCTime(LFinal, 2); }; export default (jobsOperations: JobOperations[]) => { const schedule = createSchedule(jobsOperations); return times(i => map((jobTime: JobOperationsWithC) => ({ processor: i + 1, startTime: jobTime.operations[i].c - jobTime.operations[i].t, endTime: jobTime.operations[i].c, name: jobTime.operations[i].name }), schedule) , 2); };