コード例 #1
0
    public IEnumerator getGraphFromNode(string title)
    {
        Debug.Log("reached getGraphFromNode");
        yield return(StartCoroutine(parseContentFromHTML(title)));

        Graph graph = new Graph();

        Graph.Information info      = new Graph.Information(title);
        Graph.Node        firstNode = new Graph.Node(info);
        firstNode.setPosition(0.0f, 0.0f, 0.0f);
        graph.addNode(firstNode);


        //we assume that we don't go deeper here.
        //another approach would be to go the same route as Coroutine "getGraph"
        //we use this approach here because it's easier to implement and unterstand
        //plus the depth is unlikely to go deeper
        if (activeNode.getSubchapters() != null)
        {
            foreach (Graph.Information.Chapter subChapter in activeNode.getSubchapters())
            {
                Graph.Information neighborInfo = new Graph.Information(subChapter.getTitle());
                Graph.Node        nextNode     = new Graph.Node(neighborInfo);
                nextNode.setPosition(Random.Range(-DEFAULT_WIDTH / 2, DEFAULT_WIDTH / 2), Random.Range(-DEFAULT_HEIGHT / 2, DEFAULT_HEIGHT / 2), Random.Range(-DEFAULT_LENGTH / 2, DEFAULT_LENGTH / 2));
                Graph.Edge nextedge = new Graph.Edge(firstNode, nextNode);
                graph.addNode(nextNode);
                graph.addEdge(nextedge);

                if (subChapter.getSubchapters() != null)
                {
                    foreach (Graph.Information.Chapter subSubChapter in subChapter.getSubchapters())
                    {
                        Graph.Information subNeighborInfo = new Graph.Information(subSubChapter.getTitle());
                        Graph.Node        subNextNode     = new Graph.Node(subNeighborInfo);
                        subNextNode.setPosition(Random.Range(-DEFAULT_WIDTH / 2, DEFAULT_WIDTH / 2), Random.Range(-DEFAULT_HEIGHT / 2, DEFAULT_HEIGHT / 2), Random.Range(-DEFAULT_LENGTH / 2, DEFAULT_LENGTH / 2));
                        Graph.Edge subNextedge = new Graph.Edge(nextNode, subNextNode);
                        graph.addNode(subNextNode);
                        graph.addEdge(subNextedge);
                        if (subSubChapter.getSubchapters() != null)
                        {
                            foreach (Graph.Information.Chapter subSubSubChapter in subChapter.getSubchapters())
                            {
                                Graph.Information subSubNeighborInfo = new Graph.Information(subSubChapter.getTitle());
                                Graph.Node        subSubNextNode     = new Graph.Node(subSubNeighborInfo);
                                subSubNextNode.setPosition(Random.Range(-DEFAULT_WIDTH / 2, DEFAULT_WIDTH / 2), Random.Range(-DEFAULT_HEIGHT / 2, DEFAULT_HEIGHT / 2), Random.Range(-DEFAULT_LENGTH / 2, DEFAULT_LENGTH / 2));
                                Graph.Edge subSubNextedge = new Graph.Edge(subNextNode, subSubNextNode);

                                graph.addNode(subSubNextNode);
                                graph.addEdge(subSubNextedge);
                            }
                        }
                    }
                }
            }
        }
        setGraph(graph, 100.0f, 100.0f, 100.0f);
        drawGraph();
    }
コード例 #2
0
    /**
     * This method uses the title of a starting article and the amount of hops (distance from the start) to generate a graph
     * It also uses maxNodes (saved in the GraphVisualizer structure), to limit maximum nodes
     *
     */
    public IEnumerator getGraph(string startingNode, int hops)
    {
        Debug.Log("hops: " + hops);
        Debug.Log("max nodes: " + maxNodes);
        measuringTime = System.Environment.TickCount;

        isAcquiringGraph = true;
        //Note: We identify graph nodes by string because of easier comprehension
        //Note: Don't confuse the lists graph is taking care of with the list of strings of neighbors...
        Graph graph = new Graph();

        Graph.Information info      = new Graph.Information(startingNode);
        Graph.Node        firstNode = new Graph.Node(info);
        firstNode.setPosition(0.0f, 0.0f, 0.0f);
        graph.addNode(firstNode);                                 //this will keep track of ALL accumulated nodes and edges

        List <Graph.Node> nodesToCheck = new List <Graph.Node>(); //these are nodes that are found in the neighborhood

        nodesToCheck.Add(firstNode);                              //this only keeps track of neighborhoods and deletes nodes that have been explored already

        //NOTE: This version of BFS does currently not keep track of a "visited" list. Since we are limited by hops (which shouldn't ever go above 3 for sanity's sake), we finish searching at some point anyway
        for (int i = 0; i < hops; i++)
        {
            Debug.Log("Hop: " + i);
            int currentNodesToCheck = nodesToCheck.Count;
            //this is the number of nodes to check the neighborhoods for.
            //All neighbors that are found will be added to "nodesToCheck" in the next loop
            for (int j = 0; j < currentNodesToCheck; j++)
            {
                Debug.Log("currentNodeToCheck: " + j);
                //this for iterates a list of nodes that will be explored
                //KEEP IN MIND it checks the amount of nodes beforehand and works on the first x found nodes because nodes are being added to the list while working on it
                //i.e. the list nodesToCheck has 1 node in the beginning (starting node), so "currentNodesToCheck" is 1
                //we now explore this node and find all neighbors and add them to the graph and to nodesToCheck
                //after the next for loop, nodesToCheck will have a lot of new nodes
                //when the hop is done, meaning the for loop iterating j has come to an end, delete the first currentNodesToCheck-many elements in nodesToCheck
                yield return(StartCoroutine(communicator.requestNeighbors(nodesToCheck[j].getName())));

                List <string> tempNeighbors = communicator.getNeighbors();
                for (int z = 0; z < tempNeighbors.Count; z++)
                {
                    Debug.Log("currentNeighborToCheck: " + z);

                    //this for adds all neighbors of a node that is currently being explored to the list of nodes to be explored and the graph
                    Graph.Information neighborInfo = new Graph.Information(tempNeighbors[z]);
                    Graph.Node        nextNode     = new Graph.Node(neighborInfo);
                    nextNode.setPosition(Random.Range(-DEFAULT_WIDTH / 2, DEFAULT_WIDTH / 2), Random.Range(-DEFAULT_HEIGHT / 2, DEFAULT_HEIGHT / 2), Random.Range(-DEFAULT_LENGTH / 2, DEFAULT_LENGTH / 2));
                    Graph.Edge nextedge = new Graph.Edge(nodesToCheck[j], nextNode);
                    if (!graph.getNodes().Exists(node => node.getName().Equals(tempNeighbors[z])))
                    {
                        graph.addNode(nextNode);                                                                                                               //add neighbor to graph if not already in graph
                    }
                    if (!graph.getEdges().Exists(edge => edge.getFrom().getName().Equals(nodesToCheck[j]) && edge.getTo().getName().Equals(tempNeighbors[z]))) //I don't want to talk about this
                    {
                        //above if should check if edge is already in list

                        int oppositeEdge = graph.getEdges().FindIndex(edge => edge.getFrom().getName().Equals(tempNeighbors[z]) && edge.getTo().getName().Equals(nodesToCheck[j]));
                        if (oppositeEdge >= 0)
                        {
                            //check if the edge exists in the opposite direction (try to find an edge where FROM is the neighbor that is looked at and TO is the node that is being explored)
                            graph.getEdges()[oppositeEdge].setBothWays(true);
                        }
                        else
                        {
                            /*
                             * IMPORTANT NOTE: THE ABOVE STEP IS NECESSARY WHEN AN EDGE IS SAVED WITH A FLAG THAT INDICATES IT GOES IN BOTH DIRECTIONS
                             * AN EDGE IS CURRENTLY MODELED SO THAT EDGES BETWEEN TWO NODES CAN BE ADDED TWICE IF THEY ARE OPPOSITES
                             * I only realised I could've left this out after I almost finished it.
                             *
                             * EDIT: Edges now have a flag that says whether it runs in both ways or not.
                             */
                            graph.addEdge(nextedge); //add edge to graph if not already in graph
                        }
                    }
                    nodesToCheck.Add(nextNode); //this adds the currently looked at node to the list of nodes to explore
                    if (graph.getNodes().Count >= maxNodes)
                    {
                        break;
                    }
                }
                if (graph.getNodes().Count >= maxNodes)
                {
                    break;
                }
            }
            nodesToCheck.RemoveRange(0, currentNodesToCheck); //see comment at start of for loop iterating j for more information on why this is necessary
            if (graph.getNodes().Count >= maxNodes)
            {
                break;
            }
        }
        setGraph(graph, 100.0f, 100.0f, 100.0f);
        isAcquiringGraph = false;
        Debug.Log("Elapsed Time: " + (System.Environment.TickCount - measuringTime));
        Debug.Log("Nodes in total: " + graph.getNodes().Count);
    }