Пример #1
0
        public void EnterWhileDefination(WhileBuilder whileBuilder)
        {
            if (whileBuilder.ParentWhile != CurrentWhile)
            {
                throw new ArgumentException("Wrong parent relationships");
            }

            CurrentWhile = whileBuilder;
        }
        private static void SetInitialUnvisited(ActionSet actionSet, Element nodeArray, IndexReference unvisitedVar)
        {
            // Create an array counting up to the number of values in the nodeArray array.
            // For example, if nodeArray has 6 variables unvisitedVar will be set to [0, 1, 2, 3, 4, 5].

            // Empty the unvisited array.
            actionSet.AddAction(unvisitedVar.SetVariable(new V_EmptyArray()));

            IndexReference current = actionSet.VarCollection.Assign("unvisitedBuilder", actionSet.IsGlobal, true);

            actionSet.AddAction(current.SetVariable(0));

            WhileBuilder unvisitedBuilder = new WhileBuilder(actionSet, (Element)current.GetVariable() < Element.Part <V_CountOf>(nodeArray));

            unvisitedBuilder.Setup();

            actionSet.AddAction(unvisitedVar.ModifyVariable(Operation.AppendToArray, (Element)current.GetVariable()));

            actionSet.AddAction(current.ModifyVariable(Operation.Add, 1));
            unvisitedBuilder.Finish();
        }
        protected void Backtrack(Element destination, IndexReference finalPath)
        {
            actionSet.AddAction(current.SetVariable(destination));
            actionSet.AddAction(finalPath.SetVariable(new V_EmptyArray()));

            // Get the path.
            WhileBuilder backtrack = new WhileBuilder(actionSet, new V_Compare(
                                                          current.GetVariable(),
                                                          Operators.NotEqual,
                                                          new V_Number(-1)
                                                          ));

            backtrack.Setup();

            Element next  = Nodes[(Element)current.GetVariable()];
            Element array = (Element)finalPath.GetVariable();
            Element first;
            Element second;

            if (!reversed)
            {
                first  = next;
                second = array;
            }
            else
            {
                first  = array;
                second = next;
            }

            actionSet.AddAction(ArrayBuilder <Element> .Build(
                                    finalPath.SetVariable(Element.Part <V_Append>(first, second)),
                                    current.SetVariable(Element.Part <V_ValueInArray>(parentArray.GetVariable(), current.GetVariable()) - 1)
                                    ));
            backtrack.Finish();
        }
        public void Get()
        {
            var firstNode = ClosestNodeToPosition(Nodes, position);

            Assign();

            current = actionSet.VarCollection.Assign("Dijkstra: Current", actionSet.IsGlobal, true);
            IndexReference distances = actionSet.VarCollection.Assign("Dijkstra: Distances", actionSet.IsGlobal, false);

            unvisited = actionSet.VarCollection.Assign("Dijkstra: Unvisited", actionSet.IsGlobal, false);
            IndexReference connectedSegments = actionSet.VarCollection.Assign("Dijkstra: Connected Segments", actionSet.IsGlobal, true);
            IndexReference neighborIndex     = actionSet.VarCollection.Assign("Dijkstra: Neighbor Index", actionSet.IsGlobal, true);
            IndexReference neighborDistance  = actionSet.VarCollection.Assign("Dijkstra: Distance", actionSet.IsGlobal, true);

            parentArray = actionSet.VarCollection.Assign("Dijkstra: Parent Array", actionSet.IsGlobal, false);

            // Set the current variable as the first node.
            actionSet.AddAction(current.SetVariable(firstNode));
            SetInitialDistances(actionSet, distances, (Element)current.GetVariable());
            SetInitialUnvisited(actionSet, Nodes, unvisited);

            WhileBuilder whileBuilder = new WhileBuilder(actionSet, LoopCondition());

            whileBuilder.Setup();

            // Get neighboring indexes
            actionSet.AddAction(connectedSegments.SetVariable(GetConnectedSegments(
                                                                  Nodes,
                                                                  Segments,
                                                                  (Element)current.GetVariable(),
                                                                  reversed
                                                                  )));

            // Loop through neighboring indexes
            ForeachBuilder forBuilder = new ForeachBuilder(actionSet, connectedSegments.GetVariable());

            forBuilder.Setup();

            actionSet.AddAction(ArrayBuilder <Element> .Build(
                                    // Get the index from the segment data
                                    neighborIndex.SetVariable(
                                        Element.TernaryConditional(
                                            new V_Compare(
                                                current.GetVariable(),
                                                Operators.NotEqual,
                                                Node1(forBuilder.IndexValue)
                                                ),
                                            Node1(forBuilder.IndexValue),
                                            Node2(forBuilder.IndexValue)
                                            )
                                        ),

                                    // Get the distance between the current and the neighbor index.
                                    neighborDistance.SetVariable(
                                        Element.Part <V_DistanceBetween>(
                                            Nodes[(Element)neighborIndex.GetVariable()],
                                            Nodes[(Element)current.GetVariable()]
                                            ) + ((Element)distances.GetVariable())[(Element)current.GetVariable()]
                                        )
                                    ));

            // Set the current neighbor's distance if the new distance is less than what it is now.
            IfBuilder ifBuilder = new IfBuilder(actionSet,
                                                (Element)neighborDistance.GetVariable()
                                                <
                                                WorkingDistance((Element)distances.GetVariable(), (Element)neighborIndex.GetVariable())
                                                );

            ifBuilder.Setup();

            actionSet.AddAction(distances.SetVariable((Element)neighborDistance.GetVariable(), null, (Element)neighborIndex.GetVariable()));
            actionSet.AddAction(parentArray.SetVariable((Element)current.GetVariable() + 1, null, (Element)neighborIndex.GetVariable()));

            ifBuilder.Finish();
            forBuilder.Finish();

            actionSet.AddAction(ArrayBuilder <Element> .Build(
                                    // Add the current to the visited array.
                                    unvisited.SetVariable(Element.Part <V_RemoveFromArray>(unvisited.GetVariable(), current.GetVariable())),

                                    // Set the current node as the smallest unvisited.
                                    current.SetVariable(LowestUnvisited(Nodes, (Element)distances.GetVariable(), (Element)unvisited.GetVariable()))
                                    ));

            whileBuilder.Finish();

            GetResult();

            actionSet.AddAction(ArrayBuilder <Element> .Build(
                                    current.SetVariable(-1),
                                    distances.SetVariable(-1),
                                    connectedSegments.SetVariable(-1),
                                    neighborIndex.SetVariable(-1),
                                    neighborDistance.SetVariable(-1),
                                    parentArray.SetVariable(-1)
                                    ));

            Reset();
        }