예제 #1
0
        public static string[] GetBuildOrder(string[] projects, string[,] dependencies)
        {
            //TODO: check cycles!
            var graph = new Common.Graph <string, int>();

            for (int i = 0; i < dependencies.GetUpperBound(0) + 1; i++)
            {
                graph.AddDirectedEdge(new Common.Edge <string, int>(dependencies[i, 0], dependencies[i, 1], 0));
            }

            var visited       = new HashSet <string>();
            var ordering      = new string[projects.Length];
            var indexOrdering = projects.Length - 1;

            // find all non visited nodes with no connections to them
            // and set them to return List, then mark them as visited
            // in short, implement topological sort

            foreach (var project in projects)
            {
                if (!visited.Contains(project))
                {
                    // create list of visited nodes starting from 'project' node
                    var visitedNodes = new List <string>();
                    execDFS(project, visited, visitedNodes, graph);
                    foreach (var vn in visitedNodes)
                    {
                        ordering[indexOrdering] = vn;
                        indexOrdering           = indexOrdering - 1;
                    }
                }
            }

            return(ordering);
        }
예제 #2
0
        // Perform a depth first search on a graph with n nodes.
        // This impl returns number of connected nodes starting from firstNode
        public static int DFS(T[] nodes, Common.Edge <T, W>[] dependencies, T firstNode)
        {
            // Example
            // nodes = { a, b, c, d, e, f }
            // dependencies = { {a, d}, {f, b}, {b, d}, {f, a}, {d, c}}

            // DFS(params, a).Count == 5 // connected to 5 other nodes
            // DFS(params, e).Count == 1 // not connected to any other nodes

            var graph = new Common.Graph <T, W>();

            for (int i = 0; i < dependencies.Length; i++)
            {
                graph.AddDirectedEdge(dependencies[i]);
            }

            var numberOfNodes = nodes.Length;

            // initialize visited list/map
            var visited = new Dictionary <T, bool>();

            foreach (var p in nodes)
            {
                visited[p] = false;
            }

            var count = 0;

            // non recursive solution, here we use Stack

            var stack = new pv.Common.Stack <T>();            // lets use homemade stack

            stack.Push(firstNode);
            visited[firstNode] = true;

            while (!stack.IsEmpty())
            {
                var node = stack.Pop();
                // famous doSomething :) e.g. count++
                count++;

                if (graph.ContainsKey(node))
                {
                    foreach (var edge in graph[node])
                    {
                        if (!visited[edge.To])
                        {
                            stack.Push(edge.To);
                            visited[edge.To] = true;
                        }
                    }
                }
            }

            return(count);
        }
예제 #3
0
        private static void execDFS(string project, HashSet <string> visited, List <string> visitedNodes, Common.Graph <string, int> graph)
        {
            visited.Add(project);

            var edges = graph.ContainsKey(project) ? graph[project] : null;

            if (edges != null)
            {
                foreach (var edge in edges)
                {
                    if (!visited.Contains(edge.To))
                    {
                        execDFS(edge.To, visited, visitedNodes, graph);
                    }
                }
            }
            visitedNodes.Add(project);
        }