コード例 #1
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);
        }
コード例 #2
0
        public static bool IsRouteBetweenNodes(T[] nodes, Graph <T, W> graph, T node1, T node2)
        {
            // we can use both DFS or BFS
            // try DFS first

            //first case
            if (node1.CompareTo(node2) == 0)
            {
                return(true);
            }

            // we need list of visited nodes
            var visited = new Dictionary <T, bool>();

            // init visited map
            foreach (var node in nodes)
            {
                visited[node] = false;
            }

            // we need a stack here
            var stack = new pv.Common.Stack <T>();

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

            while (!stack.IsEmpty())
            {
                var node = stack.Pop();

                if (graph.ContainsKey(node))
                {
                    foreach (var ne in graph[node])
                    {
                        if (!visited[ne.To])
                        {
                            if (ne.To.CompareTo(node2) == 0)
                            {
                                return(true);
                            }

                            stack.Push(ne.To);
                            visited[ne.To] = true;
                        }
                    }
                }
            }

            return(false);
        }
コード例 #3
0
        // wil try to make solution without recursion
        public static int[] GetBuildOrder(int[] projects, int[,] dependencies)
        {
            var graph                = new Dictionary <int, List <int> >();
            var numberOfPairs        = dependencies.GetUpperBound(0) + 1;
            var orderedProjects      = new int[projects.Length];
            var orderedProjectsIndex = projects.Length - 1;

            for (int i = 0; i < numberOfPairs; i++)
            {
                if (!graph.ContainsKey(dependencies[i, 0]))
                {
                    graph[dependencies[i, 0]] = new List <int>();
                }
                graph[dependencies[i, 0]].Add(dependencies[i, 1]);                 // storing indexes of projects
            }

            // lets try with DFS

            // we need list of visited nodes
            var visited = new bool[projects.Length];             // by default all are false
            var stack   = new pv.Common.Stack <int>();

            // start from node 0, try to find nodes which are not dependent on any other nodes
            for (int at = 0; at < projects.Length; at++)
            {
                if (!visited[at])
                {
                    stack.Push(at);                     // push index of a project to stack
                    visited[at] = true;

                    var visitedNodes = new List <int>();                    // for particular project on index at

                    while (!stack.IsEmpty())
                    {
                        var projectIndex = stack.Pop();

                        // then traverse to its connections and mark visited
                        if (graph.ContainsKey(projectIndex))
                        {
                            for (int j = 0; j < graph[projectIndex].Count; j++)
                            {
                                if (!visited[graph[projectIndex][j]])
                                {
                                    stack.Push(graph[projectIndex][j]);
                                    visited[graph[projectIndex][j]] = true;
                                }
                            }
                        }

                        visitedNodes.Add(projectIndex);
                    }

                    // insert visitedNodes to orderedProjects
                    for (int k = visitedNodes.Count - 1; k >= 0; k--)
                    {
                        orderedProjects[orderedProjectsIndex] = visitedNodes[k];
                        orderedProjectsIndex--;
                    }
                }
            }

            return(orderedProjects);
        }