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(); }