/// <summary>
 ///   Ensure a node with the given name exists, creating if necessary.
 /// </summary>
 public void AddNode(string name)
 {
     if (!nodeDict.ContainsKey(name))
     {
         GraphNode n = new GraphNode(name);
         nodes.Add(n);
         nodeDict.Add(name, n);
     }
 }
Beispiel #2
0
 public GraphEdge(GraphNode from, GraphNode to, string label)
 {
     FromNode = from;
     ToNode = to;
     Label = label;
 }
Beispiel #3
0
        // 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());
                        }
                    }
                }
            }
        }
Beispiel #4
0
        // show all descendents of person, arranged by generation
        private static void ShowDescendents(string name)
        {
            GraphNode root = rg.GetNode(name);

            // name not in file
            if (root == null)
            {
                Console.WriteLine("\t{0} not found", name);
            }

            // this person has no descendents
            else if (root.GetEdges("hasChild").Count == 0)
            {
                Console.WriteLine("\t{0} has no descendents", name);
            }

            // this person has some descendents
            else
            {
                Console.WriteLine("{0}'s descendents:", name);
                List <GraphNode> currentGenNodes = new List <GraphNode>();
                currentGenNodes.Add(root);
                // root has been visited, so set its label to "Visited" to avoid cycles, if any in file
                root.Label = "Visited";

                List <GraphNode> nextGenNodes = new List <GraphNode>();

                // generation counter (to determine the number of 'Great's in output)
                int           generation = 0;
                List <string> children   = new List <string>();

                // while there are some descendents
                while (currentGenNodes.Count > 0)
                {
                    children = new List <string>();
                    // for each descendent
                    foreach (GraphNode n in currentGenNodes)
                    {
                        // set label for each visited node to "Visited" to avoid cycles, if any
                        n.Label = "Visited";
                        // for each child of descendent, add them to the appropriate lists if unvisited
                        foreach (GraphEdge e in n.GetEdges("hasChild"))
                        {
                            if (e.ToNode().Label != "Visited")
                            {
                                nextGenNodes.Add(e.ToNode());
                                children.Add(e.To());
                            }
                        }
                    }

                    // output descendents with labels appropriately
                    if (generation == 0 && children.Count > 0)
                    {
                        Console.Write("\tChildren: ");
                        Console.WriteLine("\t" + String.Join(", ", (String[])children.ToArray()));
                    }
                    else if (generation == 1 && children.Count > 0)
                    {
                        Console.Write("\tGrandchildren: ");
                        Console.WriteLine("\t" + String.Join(", ", (String[])children.ToArray()));
                    }
                    else if (generation > 1 && children.Count > 0)
                    {
                        Console.Write("\tGreat ");
                        for (int i = generation - 1; i > 1; i--)
                        {
                            Console.Write("Great ");
                        }
                        Console.Write("Grandchildren: ");
                        Console.WriteLine("\t" + String.Join(", ", (String[])children.ToArray()));
                    }
                    // make currentGenNodes point to the next generation of descendents,
                    // generate a new list for the next generation to compute in the next iteration of the loop
                    // increment generation counter variable
                    currentGenNodes = nextGenNodes;
                    nextGenNodes    = new List <GraphNode>();
                    generation++;
                }
            }
        }
Beispiel #5
0
        // Show a person's siblings
        // assumes that siblings don't share the same name (because if they do, then the later occurrence of the sibling
        // with the same name won't be recorded)
        private static void ShowSiblings(string name)
        {
            GraphNode n = rg.GetNode(name);

            if (n != null)
            {
                Console.Write("{0}'s siblings: ", name);
                List <GraphEdge> parentEdges = n.GetEdges("hasParent");
                List <GraphNode> parentNodes = new List <GraphNode>();
                List <GraphNode> childNodes  = new List <GraphNode>();

                // get this person's parents
                foreach (GraphEdge e in parentEdges)
                {
                    parentNodes.Add(e.ToNode());
                }

                // for each parent node
                foreach (GraphNode p in parentNodes)
                {
                    // for each child edge of this parent
                    foreach (GraphEdge c in p.GetEdges("hasChild"))
                    {
                        // set copy to false
                        bool copy = false;
                        // for each child in childNodes list so far
                        foreach (GraphNode d in childNodes)
                        {
                            // if 'd' (a node in childNodes) is the same as 'c', then don't add it again by setting copy to true
                            if (d.GetName() == c.ToNode().GetName())
                            {
                                copy = true;
                            }
                        }

                        // if this node is not a copy and is not the same as the person being passed in, then add it to childNodes
                        if (!copy && c.ToNode().GetName() != name)
                        {
                            childNodes.Add(c.ToNode());
                        }
                    }
                }
                if (childNodes.Count != 0)
                {
                    Console.WriteLine();
                    int counter = 1;
                    foreach (GraphNode c in childNodes)
                    {
                        Console.WriteLine("\t" + counter + ". " + c.GetName());
                        counter++;
                    }
                }
                else
                {
                    Console.Write("\n\tno siblings found for {0}", name);
                }
            }
            else
            {
                Console.WriteLine("\t{0} not found", name);
            }
            Console.WriteLine();
        }
Beispiel #6
0
 // constructor
 public GraphEdge(GraphNode from, GraphNode to, string myLabel)
 {
     fromNode = from;
     toNode   = to;
     Label    = myLabel;
 }