예제 #1
0
파일: Program.cs 프로젝트: ajs2440/School
        // show shortest chain of relationships between name1 and name2
        private static void ShowBingo(string name1, string name2)
        {
            GraphNode start = rg.GetNode(name1);
            GraphNode end   = rg.GetNode(name2);

            // invalid case - start not in file
            if (start == null)
            {
                Console.WriteLine("\t{0} not found", name1);
            }

            // invalid case - end not in file
            else if (end == null)
            {
                Console.WriteLine("\t{0} not found", name2);
            }
            // invalid case - start is same as end
            else if (start == end)
            {
                Console.WriteLine("\t{0} and {1} are the same", name1, name2);
            }

            // valid case - start and end are in file, and are different nodes
            else
            {
                // list of nodes that will store the shortest path nodes
                List <GraphNode> shortestPath = new List <GraphNode>();

                // list of list of nodes that will store different paths from start to end
                List <List <GraphNode> > paths = new List <List <GraphNode> >();

                // list of nodes that will store the information of current depth nodes
                List <GraphNode> currentDepth = new List <GraphNode>();

                // dictionary to keep track of which nodes have been added and visited
                Dictionary <string, bool> check = new Dictionary <string, bool>();
                currentDepth.Add(start);
                paths.Add(currentDepth);
                int depthCount = 0;

                while (true)
                {
                    // new unique path
                    currentDepth = new List <GraphNode>();

                    // BFS
                    // for each node in the last path stored
                    foreach (GraphNode n in paths[paths.Count - 1])
                    {
                        // for each edge for the current node
                        foreach (GraphEdge e in n.GetEdges())
                        {
                            // if this edge leads to end, go to label
                            if (e.To() == end.GetName())
                            {
                                goto Found;
                            }
                            // otherwise update current path, and add it to our dictionary if not in there already
                            if (!check.ContainsKey(e.To()))
                            {
                                currentDepth.Add(e.ToNode());
                                check.Add(e.To(), true);
                            }
                        }
                    }
                    // add new unique path to list of paths
                    paths.Add(currentDepth);
                }
Found:
                shortestPath.Add(end);
                depthCount = paths.Count - 1;

                // while the last node in shortest path is not the same as start node, keep adding nodes to shortestPath list
                // from end to start checking to see if they are in our paths list
                while (shortestPath[shortestPath.Count - 1] != start && depthCount >= 0)
                {
                    // for each edge of last node in shortest path
                    foreach (GraphEdge e in shortestPath[shortestPath.Count - 1].GetEdges())
                    {
                        if (paths[depthCount].Contains(e.ToNode()))
                        {
                            shortestPath.Add(e.ToNode());
                            goto NextLoop;
                        }
                    }

                    // for each node in this depth
                    foreach (GraphNode n in paths[depthCount])
                    {
                        foreach (GraphEdge e in n.GetEdges())
                        {
                            if (e.ToNode() == shortestPath[shortestPath.Count - 1])
                            {
                                shortestPath.Add(n);
                                goto NextLoop;
                            }
                        }
                    }
                    // decrement depthCount for next iteration
NextLoop:
                    depthCount--;
                }
                // reverse order shortestPath to get order from start to end, since it is in reverse order (end to start) right now
                shortestPath.Reverse();

                // output in line the relationship sentence for each edge in shortest path
                for (int i = 1; i < shortestPath.Count; i++)
                {
                    foreach (GraphEdge e in shortestPath[i - 1].GetEdges())
                    {
                        if (e.ToNode() == shortestPath[i])
                        {
                            Console.WriteLine("\t" + shortestPath[i - 1].GetName() + " is a " + e.Label.Substring(3).ToLower() + " of " + shortestPath[i].GetName());
                        }
                    }
                }
            }
        }