private StagedHoudiniPlan ComputeBalancedStages()
        {
            Graph <ScheduledStage> Dependences = new Graph <ScheduledStage>();
            var done = new Dictionary <SCC <string>, ScheduledStage>();

            done[GetStartNodeOfStagesDAG()] = new ScheduledStage(0, new HashSet <string>());

            int maxStageSize = 200;

            for (int stageId = 1; done.Count() != StagesDAG.Nodes.Count(); stageId++)
            {
                int                     stageSize        = 0;
                ScheduledStage          Stage            = new ScheduledStage(stageId, new HashSet <string>());
                HashSet <SCC <string> > AddedToThisStage = new HashSet <SCC <string> >();

                foreach (var n in StagesDAG.Nodes.Where(Item => !done.ContainsKey(Item)))
                {
                    if (stageSize + n.Count() > maxStageSize)
                    {
                        continue;
                    }
                    if (StagesDAG.Successors(n).Where(Item => !done.ContainsKey(Item)).Count() == 0)
                    {
                        foreach (var c in n)
                        {
                            Stage.AddCandidate(c);
                            stageSize++;
                        }
                        foreach (var s in StagesDAG.Successors(n))
                        {
                            Dependences.AddEdge(Stage, done[s]);
                        }
                        AddedToThisStage.Add(n);
                    }
                }
                foreach (var n in AddedToThisStage)
                {
                    done[n] = Stage;
                }
                if (stageSize == 0)
                {
                    maxStageSize *= 2;
                }
            }
            return(new StagedHoudiniPlan(Dependences));
        }
        private StagedHoudiniPlan ComputeCoarseStages()
        {
            foreach (var n in StagesDAG.Nodes)
            {
                Debug.Assert(!StagesDAG.Successors(n).Contains(n));
            }

            Graph <ScheduledStage> Dependences = new Graph <ScheduledStage>();

            var done = new Dictionary <SCC <string>, ScheduledStage>();

            done[GetStartNodeOfStagesDAG()] = new ScheduledStage(0, new HashSet <string>());

            for (int stageId = 1; done.Count() != StagesDAG.Nodes.Count(); stageId++)
            {
                var Stage = new ScheduledStage(stageId, new HashSet <string>());
                HashSet <SCC <string> > AssignedToThisStage = new HashSet <SCC <string> >();

                foreach (var n in StagesDAG.Nodes.Where(Item => !done.ContainsKey(Item)))
                {
                    if (StagesDAG.Successors(n).Where(Item => !done.ContainsKey(Item)).Count() == 0)
                    {
                        foreach (var s in StagesDAG.Successors(n))
                        {
                            Debug.Assert(s != n);
                            Debug.Assert(Stage != done[s]);
                            Dependences.AddEdge(Stage, done[s]);
                        }
                        foreach (var c in n)
                        {
                            Stage.AddCandidate(c);
                        }
                        Console.Write(n.Count() + ", ");
                        AssignedToThisStage.Add(n);
                    }
                }

                Console.WriteLine("total: " + Stage.Count());

                foreach (var n in AssignedToThisStage)
                {
                    done[n] = Stage;
                }
            }
            return(new StagedHoudiniPlan(Dependences));
        }
        private StagedHoudiniPlan ComputeFineStages()
        {
            Graph <ScheduledStage> Dependences = new Graph <ScheduledStage>();
            var done = new Dictionary <SCC <string>, ScheduledStage>();

            List <SCC <string> > components = StagesDAG.TopologicalSort().ToList();

            components.Reverse();

            for (int i = 0; i < components.Count(); i++)
            {
                ScheduledStage Stage = new ScheduledStage(i, new HashSet <string>());
                done[components[i]] = Stage;
                foreach (var c in components[i])
                {
                    Stage.AddCandidate(c);
                }
                foreach (var s in StagesDAG.Successors(components[i]))
                {
                    Dependences.AddEdge(Stage, done[s]);
                }
            }
            return(new StagedHoudiniPlan(Dependences));
        }