Example #1
0
        public StrongComponentChecker(IDirectedGraph <NodeType, EdgeType> graph)
        {
            this.graph = graph;
            dfs        = new DepthFirstSearch <NodeType, EdgeType>(graph);
            CanCreateNodeData <NodeType> data = (CanCreateNodeData <NodeType>)graph;

            DiscoverTime      = data.CreateNodeData <int>(0);
            RootDiscoverTime  = data.CreateNodeData <int>(0);
            dfs.DiscoverNode += delegate(NodeType node)
            {
                DiscoverTime[node]     = time;
                RootDiscoverTime[node] = time;
                time++;
            };
            dfs.BackEdge       += ProcessEdge2;
            dfs.CrossEdge      += ProcessEdge2;
            dfs.FinishTreeEdge += ProcessEdge;
            dfs.FinishNode     += delegate(NodeType node)
            {
                int thisRootDiscoverTime = RootDiscoverTime[node];
                if (thisRootDiscoverTime < DiscoverTime[node])
                {
                    // not a root
                }
                else
                {
                    // root of a component
                    if (thisRootDiscoverTime != 0)
                    {
                        IsStrong = false;
                    }
                }
            };
        }
Example #2
0
 public StrongComponents2(Converter <NodeType, IEnumerable <NodeType> > successors, CanCreateNodeData <NodeType> data)
 {
     dfs               = new DepthFirstSearch <NodeType>(successors, data);
     finished          = new Stack <NodeType>();
     DiscoverTime      = data.CreateNodeData <int>(0);
     RootDiscoverTime  = data.CreateNodeData <int>(0);
     dfs.DiscoverNode += delegate(NodeType node)
     {
         DiscoverTime[node]     = time;
         RootDiscoverTime[node] = time;
         time++;
     };
     dfs.BackEdge += delegate(Edge <NodeType> edge)
     {
         if (RootDiscoverTime[edge.Target] < RootDiscoverTime[edge.Source])
         {
             RootDiscoverTime[edge.Source] = RootDiscoverTime[edge.Target];
         }
     };
     dfs.CrossEdge += delegate(Edge <NodeType> edge)
     {
         if (RootDiscoverTime[edge.Target] < RootDiscoverTime[edge.Source])
         {
             RootDiscoverTime[edge.Source] = RootDiscoverTime[edge.Target];
         }
     };
     dfs.FinishTreeEdge += delegate(Edge <NodeType> edge)
     {
         if (RootDiscoverTime[edge.Target] < RootDiscoverTime[edge.Source])
         {
             RootDiscoverTime[edge.Source] = RootDiscoverTime[edge.Target];
         }
     };
     dfs.FinishNode += delegate(NodeType node)
     {
         int thisRootDiscoverTime = RootDiscoverTime[node];
         if (thisRootDiscoverTime < DiscoverTime[node])
         {
             // not a root
             finished.Push(node);
         }
         else
         {
             // root of a component
             OnBeginComponent();
             OnAddNode(node);
             while (finished.Count > 0 && RootDiscoverTime[finished.Peek()] >= thisRootDiscoverTime)
             {
                 NodeType child = finished.Pop();
                 OnAddNode(child);
                 RootDiscoverTime[child] = Int32.MaxValue; // prevent child from affecting any other components
             }
             RootDiscoverTime[node] = Int32.MaxValue;      // prevent node from affecting any other components
             OnEndComponent();
         }
     };
 }
Example #3
0
 public StrongComponents(Converter <NodeType, IEnumerable <NodeType> > successors,
                         Converter <NodeType, IEnumerable <NodeType> > predecessors, CanCreateNodeData <NodeType> data)
 {
     dfsForward             = new DepthFirstSearch <NodeType>(successors, data);
     finished               = new Stack <NodeType>();
     dfsForward.FinishNode += node => finished.Push(node);
     dfsBackward            =
         new DepthFirstSearch <NodeType>(node => predecessors(node).Where(source => (dfsForward.IsVisited[source] != VisitState.Unvisited)), data);
     dfsBackward.DiscoverNode += OnAddNode;
 }
Example #4
0
        public List <NodeIndex> GetScheduleWithGroups(Converter <NodeIndex, IEnumerable <NodeIndex> > predecessors)
        {
            // toposort the forward edges to get a schedule
            // algorithm: create a schedule for each group and then stitch them together
            List <NodeIndex> schedule = new List <NodeIndex>();

            if (dfsScheduleWithGroups == null)
            {
                // used by SearchFrom
                dfsScheduleWithGroups           = new DepthFirstSearch <NodeIndex>(predecessors, this);
                dfsScheduleWithGroups.BackEdge += delegate(Edge <NodeIndex> edge)
                {
                    List <NodeIndex> cycle = new List <NodeIndex>();
                    cycle.Add(edge.Target);
                    bool found = false;
                    dfsScheduleWithGroups.ForEachStackNode(delegate(NodeIndex node)
                    {
                        if (node == edge.Target)
                        {
                            found = true;
                        }
                        if (!found)
                        {
                            cycle.Add(node);
                        }
                    });
                    //cycle.Reverse();
                    NodeIndex source = cycle[cycle.Count - 1];
                    Debug.Write("cycle: ");
                    Debug.Write(IsGroup(source) ? $"[{source}] " : $"{source}");
                    foreach (var target in cycle)
                    {
                        foreach (EdgeIndex edge2 in GetAllEdges(source, target))
                        {
                            if (IsGroup(source))
                            {
                                Debug.Write($"{g.SourceOf(edge2)}");
                            }
                            Debug.Write($"->{g.TargetOf(edge2)} ");
                        }
                        if (IsGroup(target))
                        {
                            Debug.Write($"[{target}] ");
                        }
                        source = target;
                    }
                    Debug.WriteLine("");
                    throw new InferCompilerException("Cycle of forward edges");
                };
                dfsScheduleWithGroups.FinishNode += node => groupSchedule.Add(node);
            }
            else
            {
                dfsScheduleWithGroups.Clear();
            }
            // the top-level schedule.  will only contain nodes/groups that are not in groups.
            List <NodeIndex> topSchedule = new List <NodeIndex>();
            Dictionary <NodeIndex, List <NodeIndex> > scheduleOfGroup = new Dictionary <EdgeIndex, List <NodeIndex> >();

            scheduleOfGroup[-1] = topSchedule;
            schedule.Clear();
            // build a schedule by visiting each node and placing all predecessors on the schedule.
            // predecessors are added by DFS FinishNode.
            foreach (NodeIndex node in g.Nodes)
            {
                if (!IsGroup(node))
                {
                    SearchFrom(node, scheduleOfGroup);
                }
            }
            // The top-level schedule may contain references to groups, whose schedule is contained in scheduleOfGroup.
            // Insert the group schedules into the top-level schedule to get one combined schedule.
            ForEachLeafNode(topSchedule, scheduleOfGroup, schedule.Add);
            return(schedule);
        }