示例#1
0
            // ReSharper disable once SuggestBaseTypeForParameter
            private static IList <T> createTopologicalOrdering <T>(IDirectedAcyclicGraph <T> graph)
                where T : IEquatable <T>
            {
                // The topological ordering from low to high.
                var ordering = new List <T>(graph.Count);

                var elements = new HashSet <T>(graph.Elements);
                var orderedElementIndices = new Dictionary <T, int>();

                while (ordering.Count < graph.Count)
                {
                    // All the remaining elements which have all their predecessors added to the topological ordering
                    // already. This includes elements which have no predecessors at all. This is equivalent to the set
                    // of sources in a directed acyclic graph where all already elements and adjacent arrows have been
                    // removed.
                    var sources = elements.Where(allPredecessorsHaveBeenOrdered);

                    // For each considered element, we look at the place of all their predecessors in the partial
                    // topological ordering we have constructed so far.
                    // * We first consider the most recently added predecessor of each element. That is, the predecessor
                    //   of said element that is the highest in the current partial topological ordering.
                    // * Of all these predecessors, we pick the predecessor that is lowest in the ordering. If
                    //   there is only one element with said predecessor, that element is added to the ordering next.
                    // * Ties are broken by looking at the next highest ordered predecessor of all tied elements.
                    // * If all predecessors of 2 or more elements are the same, we pick the element with the least
                    //   predecessors.
                    // This selection process is implemented by representing the predecessors of an element as a
                    // decreasing number sequence of the predecessors' indices, and selecting the lowest of those in a
                    // reflected lexicographic ordering.
                    var next = sources.MinBy(createDecreasingNumberSequenceOfPredecessorIndices);

                    orderedElementIndices.Add(next, ordering.Count);
                    ordering.Add(next);
                    elements.Remove(next);
                }

                return(ordering);

                bool allPredecessorsHaveBeenOrdered(T e) => graph.GetDirectPredecessorsOf(e)
                .All(n => orderedElementIndices.ContainsKey(n));

                DecreasingNumberSequence createDecreasingNumberSequenceOfPredecessorIndices(T e)
                {
                    var predecessorIndices = graph.GetDirectPredecessorsOf(e).Select(n => orderedElementIndices[n]);

                    return(DecreasingNumberSequence.FromUnsortedNumbers(predecessorIndices));
                }
            }