/// <summary> /// Given a problem with precedence arcs as a DAG. Creates an assignment by iterating jobs over machines. Very naive. /// </summary> public void MakeRollingMachineAssignment() { AssignmentDescription = "Rolling Machine Assignment"; if (PrecedenceDAG.N <= 1) { throw new Exception("No DAG given. Cannot build schedule without problem instance"); } int NJobsAssigned = 0; int[] nParentsProcessed = new int[PrecedenceDAG.N + 1]; Queue <Job> AllPredDone = new Queue <Job>(); // The jobs that will no longer change Rj are those for which all Parents have been considered. foreach (Job j in PrecedenceDAG.Jobs) //All jobs without predecessors can know their final Rj (it is equal to their own rj). { if (j.Predecessors.Count == 0) { AllPredDone.Enqueue(j); } } int CandidateMachineID = 0; while (AllPredDone.Count > 0) { bool DebugAssignmentSuccess = false; CandidateMachineID++; if (CandidateMachineID >= Machines.Count + 1) { CandidateMachineID = 1; } Job CurrentJob = AllPredDone.Dequeue(); for (int i = 0; i < Machines.Count; i++) { if (!IsFeasibleAssignment(CurrentJob, GetMachineByID(CandidateMachineID))) { // try the next machine: CandidateMachineID++; if (CandidateMachineID >= Machines.Count) { CandidateMachineID = 0; } } else { // assign to that machine //IMPORTANT: Update the Queue before adding any arcs, or things may be added to the queue twice: foreach (Job Succ in CurrentJob.Successors) { nParentsProcessed[Succ.ID]++; if (nParentsProcessed[Succ.ID] == Succ.Predecessors.Count) { AllPredDone.Enqueue(Succ); } } //IMPORTANT: Only do this after the queue has been updated. // if it is the first job on the machine, no precedence arc is needed: if (GetMachineByID(CandidateMachineID).AssignedJobs.Count > 0) { PrecedenceDAG.AddArc(GetMachineByID(CandidateMachineID).LastJob(), CurrentJob); } //IMPORTANT: Only do this after the queue has been updated and after machine arcs have been updated AssignJobToMachine(CurrentJob, GetMachineByID(CandidateMachineID)); DebugAssignmentSuccess = true; break; } } if (!DebugAssignmentSuccess) { throw new Exception("Schedulde.Build was unable to create a feasible schedule: the algorithm is bugged."); } NJobsAssigned++; } if (NJobsAssigned < PrecedenceDAG.N) { throw new Exception("Not all jobs assigned"); } }