import { addIndex, find, map, propEq, reduce, range, times, last } from 'rambda'; import type { JobId } from '../../types'; import { createSchedule as johnson, updateCTime } from '../johnson'; import { max } from 'ramda'; type JobOperations = { jobId: JobId, operations: Array<{ t: number }> }; type JobOperationsWithC = { jobId: JobId, operations: Array<{ t: number, c: number }> }; export const fillCorrupted = (jobsOperations: JobOperations[]) => { const maxOperationsCount = reduce((acc, { operations }) => max(operations.length, acc), 0, jobsOperations); return map( ({ operations, ...rest }) => { const fixedOperations = [...operations]; fixedOperations.length = maxOperationsCount; return { ...rest, operations: fixedOperations.fill({ t: 0 }, operations.length, maxOperationsCount) }; }, jobsOperations ) }; export const createSchedule = (jobsOperations: JobOperations[], processorsCount: number): JobOperationsWithC[] => { jobsOperations = fillCorrupted(jobsOperations); const allSchedules = map(k => { const jobsOperationsForK = map((jobsOperation: JobOperations) => { const t1 = reduce((acc, i) => acc + jobsOperation.operations[i].t, 0, range(0, k)); const t2 = reduce((acc, i) => acc + jobsOperation.operations[i].t, 0, range(processorsCount - k, processorsCount)); const operations = [ { t: t1 }, { t: t2 } ]; const newJobsOperations = { jobId: jobsOperation.jobId, operations }; return newJobsOperations; }, jobsOperations); const jobsOperationsOrderTemplate = johnson(jobsOperationsForK); const mapWithIndex = addIndex(map); const jobsOperationsReordered = mapWithIndex((jobOperationTemplate, i) => { const { operations } = find(propEq('jobId', jobOperationTemplate.jobId), jobsOperations); return { jobId: jobOperationTemplate.jobId, operations }; }, jobsOperationsOrderTemplate); const jobsOperationsReorderedWithC = updateCTime(jobsOperationsReordered, processorsCount); return jobsOperationsReorderedWithC; }, range(1, processorsCount)); const bestSchedule = reduce((acc, schedule) => { const cmaxAcc = last(last(acc).operations).c; const cmax = last(last(schedule).operations).c; return (cmax < cmaxAcc) ? schedule : acc; }, [{ operations: [{ c: Infinity }] }], allSchedules); return bestSchedule; }; export default (jobsOperations: JobOperations[], processorsCount: number) => { const schedule = createSchedule(jobsOperations, processorsCount); return times(i => map((jobTime: JobOperationsWithC) => ({ processor: i + 1, startTime: jobTime.operations[i].c - jobTime.operations[i].t, endTime: jobTime.operations[i].c, }), schedule) , processorsCount); };