static long WorkingSort <T>(HashSet <Tuple <T, int> > nodes, HashSet <Tuple <T, T> > edges, int workersCount) where T : IEquatable <T> { // Empty list that will contain the sorted elements long duration = -1; // Set of all nodes with no incoming edges var S = new HashSet <T>( nodes.Where(n => edges.All(e => e.Item2.Equals(n.Item1) == false)). Select(t => t.Item1)).OrderBy(t => t).ToList(); // while S is non-empty do Workers <T> workers = new Workers <T>(workersCount); while (true) { duration++; foreach (var worker in workers.Items) { if (worker.Finished(duration)) { foreach (var e in edges.Where(e => e.Item1.Equals(worker.Node)).ToList()) { var m = e.Item2; // remove edge e from the graph edges.Remove(e); // if m has no other incoming edges then if (edges.All(me => me.Item2.Equals(m) == false)) { // insert m into S S.Add(m); } } worker.Free(); } } if (S.Any()) { while (S.Any() && workers.GetFreeWorker() != null) { var n = S.First(); workers.GetFreeWorker().Start(n, nodes.First(t => t.Item1.Equals(n)).Item2, duration); S.Remove(n); } } else { if (workers.FreeCount == workersCount) { break; } } Debug.WriteLine($"{duration} - {workers.ToString()}"); } // if graph has edges then if (edges.Any()) { // return error (graph has at least one cycle) return(-1); } else { // return L (a topologically sorted order) return(duration); } }