/// Count up how many JobPaths have an earlier simulation start time and also share a fixture/face with the current job private static int CountEarlierConflicts(JobPlan jobToCheck, int proc1path, IEnumerable <JobPlan> jobs) { var startT = jobToCheck.GetSimulatedStartingTimeUTC(process: 1, path: proc1path); if (startT == DateTime.MinValue) { return(0); } // first, calculate the fixtures and faces used by the job to check var group = jobToCheck.GetPathGroup(process: 1, path: proc1path); var usedFixtureFaces = new HashSet <ValueTuple <string, string> >(); for (int proc = 1; proc <= jobToCheck.NumProcesses; proc++) { for (int path = 1; path <= jobToCheck.GetNumPaths(proc); path++) { if (jobToCheck.GetPathGroup(proc, path) != group) { continue; } var(plannedFix, plannedFace) = jobToCheck.PlannedFixture(proc, path); if (string.IsNullOrEmpty(plannedFix)) { continue; } usedFixtureFaces.Add((plannedFix, plannedFace.ToString())); } } int earlierConflicts = 0; // go through each other job and process 1 path foreach (var otherJob in jobs) { for (var otherProc1Path = 1; otherProc1Path <= otherJob.GetNumPaths(process: 1); otherProc1Path++) { if (otherJob.UniqueStr == jobToCheck.UniqueStr && proc1path == otherProc1Path) { continue; } // see if the process 1 starting time is later and if so skip the remaining checks var otherStart = otherJob.GetSimulatedStartingTimeUTC(process: 1, path: otherProc1Path); if (otherStart == DateTime.MinValue) { goto checkNextPath; } if (otherStart >= startT) { goto checkNextPath; } var otherGroup = otherJob.GetPathGroup(process: 1, path: otherProc1Path); //the job-path combo starts earlier than the job-path to check, but need to see if it conflicts. // go through all processes matching the path group and if a fixture face matches, // count it as a conflict. for (var otherProc = 1; otherProc <= otherJob.NumProcesses; otherProc++) { for (var otherPath = 1; otherPath <= otherJob.GetNumPaths(otherProc); otherPath++) { if (otherJob.GetPathGroup(otherProc, otherPath) != otherGroup) { continue; } var(otherFix, otherFace) = otherJob.PlannedFixture(otherProc, otherPath); if (usedFixtureFaces.Contains((otherFix, otherFace.ToString()))) { earlierConflicts += 1; goto checkNextPath; } } } checkNextPath :; } } return(earlierConflicts); }