Beispiel #1
0
        /// <summary>
        /// We build a spanning tree by following the DFS, the tree induces an order on vertices
        /// measured by the distance from the tree root. The feedback set will consist of edges
        /// directed against this order.
        /// </summary>
        /// <param name="graph"></param>
        /// <returns></returns>
        static internal IEnumerable <IEdge> GetFeedbackSet(BasicGraphOnEdges <TEdge> graph)
        {
            if (graph != null && graph.NodeCount > 0 && graph.Edges.Count > 0)
            {
                Set <IEdge>  feedbackSet = new Set <IEdge>();
                VertStatus[] status      = new VertStatus[graph.NodeCount]; //will be Unvisited at the beginning
#if SHARPKIT                                                                //http://code.google.com/p/sharpkit/issues/detail?id=367 arrays are not default initialised
                for (int i = 0; i < status.Length; i++)
                {
                    status[i] = VertStatus.NotVisited;
                }
#endif
                for (int vertex = 0; vertex < graph.NodeCount; vertex++)
                {
                    if (status[vertex] == VertStatus.Visited)
                    {
                        continue;
                    }

                    System.Diagnostics.Debug.Assert(status[vertex] != VertStatus.InStack);

                    Stack <IEnumerator <TEdge> > enumStack = new Stack <IEnumerator <TEdge> >(); //avoiding the recursion
                    Stack <int>         vertexStack        = new Stack <int>();                  //avoiding the recursion
                    IEnumerator <TEdge> outEnum            = graph.OutEdges(vertex).GetEnumerator();
                    Push(enumStack, vertexStack, status, vertex, outEnum);
                    while (enumStack.Count > 0)
                    {
                        Pop(enumStack, vertexStack, status, out vertex, out outEnum);

                        while (outEnum.MoveNext())
                        {
                            TEdge e = outEnum.Current;

                            if (e.Source == e.Target)
                            {
                                continue;
                            }

                            VertStatus targetStatus = status[e.Target];
                            if (targetStatus == VertStatus.InStack)
                            {
                                feedbackSet.Insert(e);
                            }
                            else if (targetStatus == VertStatus.NotVisited)                             //have to go deeper
                            {
                                Push(enumStack, vertexStack, status, vertex, outEnum);
                                vertex           = e.Target;
                                status[e.Target] = VertStatus.Visited;
                                outEnum          = graph.OutEdges(vertex).GetEnumerator();
                            }
                        }
                    }
                }
                return(feedbackSet as IEnumerable <IEdge>);
            }
            else
            {
                return(new Set <IEdge>());
            }
        }
        /// <summary>
        /// The function returns an array arr such that
        /// arr is a permutation of the graph vertices,
        /// and for any edge e in graph if e.Source=arr[i]
        /// e.Target=arr[j], then i is less than j
        /// </summary>
        /// <param name="graph"></param>
        /// <returns></returns>
        internal static int[] GetOrder <TEdge>(BasicGraphOnEdges <TEdge> graph) where TEdge : IEdge
        {
            var visited = new bool[graph.NodeCount];

            //no recursion! So we have to organize a stack
            var sv = new Stack <int>();
            var se = new Stack <IEnumerator <int> >();

            var order = new List <int>();

            IEnumerator <int> en;

            for (int u = 0; u < graph.NodeCount; u++)
            {
                if (visited[u])
                {
                    continue;
                }

                int cu = u;
                visited[cu] = true;
                en          = graph.OutEdges(u).Select(e => e.Target).GetEnumerator();

                do
                {
                    while (en.MoveNext())
                    {
                        int v = en.Current;
                        if (!visited[v])
                        {
                            visited[v] = true;
                            sv.Push(cu);
                            se.Push(en);
                            cu = v;
                            en = graph.OutEdges(cu).Select(e => e.Target).GetEnumerator();
                        }
                    }
                    order.Add(cu);


                    if (sv.Count > 0)
                    {
                        en = se.Pop();
                        cu = sv.Pop();
                    }
                    else
                    {
                        break;
                    }
                } while (true);
            }
            order.Reverse();
            return(order.ToArray());
        }
 static IEnumerable <int> Neighbors(BasicGraphOnEdges <TEdge> graph, int s)
 {
     foreach (TEdge e in graph.OutEdges(s))
     {
         yield return(e.Target);
     }
     foreach (TEdge e in graph.InEdges(s))
     {
         yield return(e.Source);
     }
 }