src/algorithms/lawler/index.js
fe944750
 import {
b681b265
   findIndex, map, propEq, reduce,
   reverse, prop, flatten, uniq, reject, contains, omit
fe944750
 } from 'rambda';
 import type { JobId } from '../../types';
b681b265
 import { max, remove } from 'ramda';
fe944750
 
 type JobTime = {
   jobId: JobId,
8c7841d1
   name: string,
fe944750
   t: number,
   d: number,
   w: number,
   anc: JobId[],
 };
 
 const findMinJob = (fi: number, jobTimes: JobTime[]) =>
   reduce(
     (minJob: JobTime, jobTime: JobTime) => {
       const minJobU = minJob.w * max(fi - minJob.d, 0);
       const jobTimeU = jobTime.w * max(fi - jobTime.d, 0);
 
       return minJobU < jobTimeU ? minJob : jobTime;
     },
     { w: Infinity },
     jobTimes
   );
 
 const updateCTime = (jobTimes: JobTime[]) => {
   let prev = 0;
 
   const cj = map((jobTime: JobTime) => {
     prev += jobTime.t;
 
     return { ...jobTime, c: prev };
   }, jobTimes);
 
   return cj;
 };
 
b681b265
 const fillCorrupted = (jobs: JobTime[]) => map(
   ({ d, w, anc, ...rest }) => ({ ...rest, d: d || 1000, w: w || 1, anc: anc || [] }),
   jobs);
 
fe944750
 export const createSchedule = (jobs: JobTime[]) => {
b681b265
   jobs = fillCorrupted(jobs);
 
fe944750
   let fi = reduce((sum, job: JobTime) => sum + job.t, 0, jobs);
   let jobsD = jobs;
   let R = [];
 
   while (fi > 0) {
     const allAcc = uniq(flatten(
       map(prop('anc'), jobsD)
     ));
 
     const G = reject((jobTime: JobTime) => contains(jobTime.jobId, allAcc), jobsD);
 
     if (!G.length) return null;
 
     const minJob = findMinJob(fi, G);
     const minJobIndex = findIndex(propEq('jobId', minJob.jobId), jobsD);
 
     jobsD = remove(minJobIndex, 1, jobsD);
     fi -= minJob.t;
 
     R.push(minJob);
   }
 
   const withC = updateCTime(reverse(R));
 
   return map(omit(['w', 'anc']), withC);
 };
 
 export default (jobs: JobTime[]) => {
   const schedule = createSchedule(jobs);
 
b681b265
   if (!schedule) return null;
 
fe944750
   const normalizedSchedule = map((jobTime: JobTime) => ({
     processor: 1,
     startTime: jobTime.c - jobTime.t,
     endTime: jobTime.c,
8c7841d1
     delayed: max(0, jobTime.c - jobTime.d),
     name: jobTime.name
fe944750
   }), schedule);
 
   return [normalizedSchedule];
 };