/// <summary>
        /// The method that controls the creation of the history graph.
        /// </summary>
        public StoryGraph CreateStoryGraph(StoryNode rootNode)
        {
            // We clone the root into a separate variable.
            StoryNode originRoot = (StoryNode)rootNode.Clone();

            // We continue to work until at least one target state is reached.
            while (!reachedGoalState)
            {
                // We create a new graph by starting to expand the root.
                BFSTraversing(newStoryGraph.GetRoot());

                // We go through the created graph, looking for target states in it.
                BFSGoalAchieveControl(newStoryGraph.GetRoot());

                // If it was not possible to find even one target state in the constructed graph.
                if (!reachedGoalState || newStoryGraph.GetNodes().Count > maxNodes)
                {
                    graphСonstructor.CreateGraph(newStoryGraph, @"D:\Graphviz\bin\newStoryGraph.dt");

                    // Then we clear the graph, and all the links added to the root.
                    newStoryGraph = new StoryGraph();
                    originRoot.GetEdges().Clear();
                    originRoot.GetLinks().Clear();

                    // After that, we reassign to the previously cleared column an indication of the root.
                    newStoryGraph.SetRoot((StoryNode)originRoot.Clone());

                    reachedGoalState = false;
                }
            }

            // We return a graph that is guaranteed to have at least one target state.
            return(newStoryGraph);
        }
示例#2
0
        public bool TarjanAlgStep(StoryNode checkedNode, ref string[] colors, bool duplicated, StoryNode duplicatedNode)
        {
            bool result = true;

            colors[checkedNode.GetNumberInSequence()] = "grey";

            foreach (StoryNode nextNode in checkedNode.GetLinks())
            {
                if (!result)
                {
                    return(result);
                }

                if (colors[nextNode.GetNumberInSequence()] == "grey")
                {
                    if (duplicated)
                    {
                        if (duplicatedNode.Equals(nextNode))
                        {
                            bool test = true;
                        }
                    }

                    if (checkedNode.isChildren(nextNode) && !duplicated)
                    {
                        continue;
                    }
                    else if (duplicated && checkedNode.isChildren(nextNode) && !duplicatedNode.Equals(nextNode))
                    {
                        continue;
                    }

                    result = false;
                    return(result);
                }
                else if (colors[nextNode.GetNumberInSequence()] == "black")
                {
                    continue;
                }
                else
                {
                    result = TarjanAlgStep(nextNode, ref colors, duplicated, duplicatedNode);
                    if (!result)
                    {
                        return(result);
                    }
                }
            }

            colors[checkedNode.GetNumberInSequence()] = "black";

            return(result);
        }
示例#3
0
        public void DeleteTestNode(ref StoryNode testNode)
        {
            foreach (var edge in testNode.GetEdges().ToList())
            {
                edge.GetUpperNode().RemoveEdge(edge);
                edge.GetLowerNode().RemoveEdge(edge);
                edge.ClearEdge();
            }

            foreach (var link in testNode.GetLinks().ToList())
            {
                testNode.DeleteLink(link);
            }
        }
        /// <summary>
        /// A method that traverses the graph according to the concept of breadth-first search
        ///    and determines the presence of at least one target state in it.
        /// </summary>
        public bool BFSGoalAchieveControl(StoryNode rootNode)
        {
            // We create a queue and a list of visited nodes.
            Queue <StoryNode>   queue        = new Queue <StoryNode>();
            HashSet <StoryNode> visitedNodes = new HashSet <StoryNode>();

            // Add the root node to the queue and the list of visited nodes.
            queue.Enqueue(rootNode);
            visitedNodes.Add(rootNode);

            // We are in a loop until the queue is empty.
            while (queue.Count > 0)
            {
                // We take the current node under consideration from the queue.
                StoryNode currentNode = queue.Dequeue();

                // We check if the target state has been reached in the node under consideration.
                reachedGoalState = storyworldConvergence.ControlToAchieveGoalState(ref currentNode);

                // If so, terminate the method and return true.
                if (reachedGoalState)
                {
                    return(true);
                }

                // Otherwise, we go through the nodes associated with the node in question.
                foreach (StoryNode nextNode in currentNode.GetLinks())
                {
                    // If they have already been visited earlier, then we continue, moving on to the next.
                    if (visitedNodes.Contains(nextNode))
                    {
                        continue;
                    }

                    // Otherwise, we add to the queue and the list of visited nodes.
                    queue.Enqueue(nextNode);
                    visitedNodes.Add(nextNode);
                }
            }

            // If no target state was found, then terminate the method and return false.
            return(false);
        }
示例#5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="firstNode">Current node</param>
        /// <param name="secondNode">New node</param>
        public void ConnectionTwoNodes(PlanAction action, StoryNode firstNode, StoryNode secondNode, bool duplicate)
        {
            Edge newEdge = new Edge();

            newEdge.SetAction(action);

            newEdge.SetUpperNode(ref firstNode);
            newEdge.SetLowerNode(ref secondNode);

            firstNode.AddEdge(newEdge);
            secondNode.AddEdge(newEdge);

            firstNode.AddLinkToNode(ref secondNode);
            secondNode.AddLinkToNode(ref firstNode);

            if (firstNode.GetEdges().Count != firstNode.GetLinks().Count)
            {
                bool test = true;
            }
        }
        /// <summary>
        /// A method in which we sequentially create a story graph, node by node, starting at the root, using the concept of Breadth First Search.
        /// </summary>
        public void BFSTraversing(StoryNode rootNode, bool root = true)
        {
            // We create a queue and a list of visited nodes.
            Queue <StoryNode>   queue        = new Queue <StoryNode>();
            HashSet <StoryNode> visitedNodes = new HashSet <StoryNode>();

            // Добавляем узел в очередь и список посещённых узлов.
            queue.Enqueue(rootNode);
            visitedNodes.Add(rootNode);

            // We initialize numeric variables storing the number of the current agent and the number of the last node in the sequence.
            int actualAgentNumber = 0;
            int globalNodeNumber  = -1;

            // We will perform the action in a loop until the queue becomes empty.
            while (queue.Count > 0 && newStoryGraph.GetNodes().Count <= maxNodes)
            {
                // We take the node in question from the queue.
                StoryNode currentNode = queue.Dequeue();

                // If we come across a node with a target state, then we do not expand it.
                if (storyworldConvergence.ControlToAchieveGoalState(ref currentNode))
                {
                    //currentNode.goalState = true;
                    continue;
                }
                else
                {
                    // If the node in question is a root.
                    if (currentNode.Equals(rootNode) && root)
                    {
                        // We call the method for creating a new node.
                        Step(newStoryGraph.GetRoot(), actualAgentNumber, root, ref globalNodeNumber, ref queue);

                        // Add the considered node back to the queue (in the case of the root, we only changed it and will consider it again),
                        //    and also to the list of visited nodes. We remove the flag indicating that we are considering the root node.
                        queue.Enqueue(currentNode);
                        visitedNodes.Add(currentNode);
                        root = false;
                    }
                    // If the node in question IS NOT a root.
                    else
                    {
                        // We determine the index of the agent, which will have to act when creating a new node.
                        actualAgentNumber = GetActualAgentNumber(currentNode.GetWorldState().GetIndexOfAgent(currentNode.GetActiveAgent()), ref currentNode);

                        // We call the method to create a new node.
                        Step(newStoryGraph.GetNode(currentNode), actualAgentNumber, root, ref globalNodeNumber, ref queue);
                    }
                }

                // We go through the nodes associated with the considered one.
                foreach (StoryNode nextNode in currentNode.GetLinks())
                {
                    // If one of them has already been visited earlier, then we continue, moving on to the next.
                    if (visitedNodes.Contains(nextNode))
                    {
                        continue;
                    }

                    // Otherwise, we add them to the queue and the list of visited nodes.
                    queue.Enqueue(nextNode);
                    visitedNodes.Add(nextNode);
                }

                // We clear the link pointing to the node in question.
                currentNode = null;
            }
        }