Exemplo n.º 1
0
    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);
        }
    }