src/algorithms/vahy/index.js
fe944750
 import {
   find,
   map,
   reduce,
   sort,
   filter,
   flatten,
   reject,
   contains,
   omit,
b681b265
   forEach, all
fe944750
 } from 'rambda';
 import type { JobId } from '../../types';
b681b265
 import { groupBy } from 'ramda';
fe944750
 import { updateCTime } from '../mcnaught';
 
 type JobTime = {
   jobId: JobId,
   t: number,
8c7841d1
   name: string,
fe944750
   anc: JobId[]
 };
 
 const noSuccJobs = (jobTimes: JobTime[]) => {
   const allAnc = flatten(map(jobTime => jobTime.ignore ? [] : jobTime.anc, jobTimes));
   return reject(jobTime => jobTime.ignore || contains(jobTime.jobId, allAnc), jobTimes);
 };
 
 const successors = (id: JobId, jobTimes: JobTime[]) =>
   filter(({ anc }) => contains(id, anc), jobTimes);
 
b681b265
 const fillCorrupted = (jobs: JobTime[]) => map(
   ({ anc, ...rest }) => ({ ...rest, anc: anc || [] }),
   jobs);
 
fe944750
 export const createSchedule = (jobTimes: JobTime[], m: number) => {
b681b265
   jobTimes = fillCorrupted(jobTimes);
 
fe944750
   let T = reduce((acc, jobTime) => acc + jobTime.t, 0, jobTimes);
 
   let noSucc = noSuccJobs(jobTimes);
 
   noSucc[0].w = reduce((acc, job) => acc + job.w, 0, noSucc[0].anc) + noSucc[0].t;
 
   forEach((jobTime: JobTime) => {
     jobTime.wCalc = () =>
       jobTime.t + reduce((acc, aJob) => acc + aJob.wCalc(), 0, successors(jobTime.jobId, jobTimes))
   }, jobTimes);
 
   forEach((jobTime: JobTime) => {
     jobTime.w = jobTime.wCalc()
   }, jobTimes);
 
   let c = Math.floor(T / m) + Math.sign(T - m * Math.floor(T / m));
   let assignedIds;
   let jobTimesSorted = sort((a, b) => b.w - a.w, jobTimes);
 
   while (c <= T) {
     assignedIds = [];
     let activeProcessor = 1;
     // console.log('procesor', activeProcessor);
 
     while (activeProcessor <= m) {
       let restC = c;
       let lastActiveProcessor = activeProcessor;
 
       forEach(withMaxW => {
         if (contains(withMaxW.jobId, assignedIds)) {
           // console.log('already assigned', withMaxW.jobId);
           return;
         }
 
         let wereAllAncAssigned = all(jobId => contains(jobId, assignedIds), withMaxW.anc);
 
         if (!wereAllAncAssigned) {
           // console.log('nemozem priradit', withMaxW.jobId);
           return;
         }
 
         if (withMaxW.t <= restC) {
           withMaxW.processor = activeProcessor;
           assignedIds.push(withMaxW.jobId);
           restC -= withMaxW.t;
           // console.log('priradil som', withMaxW.jobId);
         } else {
           // console.log('nezmesti sa', withMaxW.jobId);
         }
       }, jobTimesSorted);
 
       if (!restC || find(jobTime => jobTime.t <= restC && !contains(jobTime.jobId, assignedIds), jobTimesSorted)) {
         activeProcessor++;
         // console.log('dalsi procesor', activeProcessor);
       }
 
       if (activeProcessor === lastActiveProcessor) {
         // console.log('zvys takt');
         break;
       }
     }
 
     if (assignedIds.length === jobTimesSorted.length) {
       break;
     }
 
     // console.log('dalsi takt', c+1);
     c++;
   }
 
   if (assignedIds.length !== jobTimesSorted.length) {
     return null;
   }
 
   return updateCTime(
     map(omit(['wCalc', 'anc', 'w']), jobTimesSorted)
   );
 };
 
 export default (jobTimes: JobTime[], processorsCount: number) => {
   const schedule = createSchedule(jobTimes, processorsCount);
 
b681b265
   if (!schedule) return null;
 
fe944750
   const grouped = Object.values(groupBy(jobTime => jobTime.processor, schedule));
 
   return map(map(job => ({
     processor: job.processor,
     startTime: job.c - job.t,
8c7841d1
     endTime: job.c,
     name: job.name
fe944750
   })), grouped);
 };