public bool Search(out GlobalPath solution, bool returnPartialSolution = false) { solution = null; NodeRecord bestNode = null; for (int max = 0; max < this.NodesPerFrame; max++) { if (Open.CountOpen() == 0) { this.InProgress = false; break; } bestNode = Open.GetBestAndRemove(); this.TotalExploredNodes++; if (bestNode.node == this.GoalNode) { solution = CalculateSolution(bestNode, returnPartialSolution); this.InProgress = false; return(true); } Closed.AddToClosed(bestNode); var outConnections = bestNode.node.OutEdgeCount; //Debug.Log(bestNode.hValue); for (int i = 0; i < outConnections; i++) { this.ProcessChildNode(bestNode, bestNode.node.EdgeOut(i), i); } } this.TotalProcessingTime += Time.deltaTime; //solution = CalculateSolution(bestNode, true); return(true); }
protected virtual void ProcessChildNode(NodeRecord parentNode, NavigationGraphEdge connectionEdge, int edgeIndex) { //this is where you process a child node var childNode = GenerateChildNodeRecord(parentNode, connectionEdge); NodeRecord childOpen = Open.SearchInOpen(childNode); NodeRecord childClose = Closed.SearchInClosed(childNode); if (childOpen == null && childClose == null) { Open.AddToOpen(childNode); if (this.MaxOpenNodes < Open.CountOpen()) { this.MaxOpenNodes = Open.CountOpen(); } // childOpen.status = NodeStatus.Open; } else if (childOpen != null && childOpen.fValue > childNode.fValue) { Open.Replace(childOpen, childNode); } else if (childClose != null && childClose.fValue > childNode.fValue) { Closed.RemoveFromClosed(childClose); Open.AddToOpen(childNode); //childOpen.status = NodeStatus.Open; } }
protected override void ProcessChildNode(NodeRecord bestNode, NavigationGraphEdge connectionEdge, int edgeIndex) { float f; float g; float h; var childNode = connectionEdge.ToNode; var childNodeRecord = this.NodeRecordArray.GetNodeRecord(childNode); if (childNodeRecord == null) { //this piece of code is used just because of the special start nodes and goal nodes added to the RAIN Navigation graph when a new search is performed. //Since these special goals were not in the original navigation graph, they will not be stored in the NodeRecordArray and we will have to add them //to a special structure //it's ok if you don't understand this, this is a hack and not part of the NodeArrayA* algorithm, just do NOT CHANGE THIS, or your algorithm will not work childNodeRecord = new NodeRecord { node = childNode, parent = bestNode, status = NodeStatus.Unvisited }; this.NodeRecordArray.AddSpecialCaseNode(childNodeRecord); return; } g = bestNode.gValue + (childNodeRecord.node.LocalPosition - bestNode.node.LocalPosition).magnitude; h = this.Heuristic.H(childNodeRecord.node, this.GoalNode); f = F(g, h); //childNodeRecord = GenerateChildNodeRecord(bestNode, connectionEdge); var childOpen = this.Open.SearchInOpen(childNodeRecord); var childClosed = this.Closed.SearchInClosed(childNodeRecord); if (childNodeRecord.status == NodeStatus.Unvisited) { childNodeRecord = GenerateChildNodeRecord(bestNode, connectionEdge); Open.AddToOpen(childNodeRecord); int count = Open.CountOpen(); if (this.MaxOpenNodes < count) { this.MaxOpenNodes = count; } } else if (childNodeRecord.status == NodeStatus.Open && childOpen != null && childOpen.fValue > childNodeRecord.fValue) { childNodeRecord = GenerateChildNodeRecord(bestNode, connectionEdge); this.Open.Replace(childOpen, childNodeRecord); } else if (childNodeRecord.status == NodeStatus.Closed && childClosed != null && childClosed.fValue > childNodeRecord.fValue) { childNodeRecord = GenerateChildNodeRecord(bestNode, connectionEdge); this.Closed.RemoveFromClosed(childClosed); this.Open.AddToOpen(childNodeRecord); } }
public virtual bool Search(out GlobalPath solution, bool returnPartialSolution = false) { solution = null; if (InitialTime == -1.0f) { InitialTime = Time.realtimeSinceStartup; } float finalTime = 0f; for (int i = 0; Open.CountOpen() > 0; ++i) { NodeRecord record = Open.GetBestAndRemove(); if (i >= NodesPerSearch) { if (returnPartialSolution) { solution = CalculateSolution(record, returnPartialSolution); } return(false); } // update debug information if (Open.CountOpen() > MaxOpenNodes) { MaxOpenNodes = Open.CountOpen(); } ++TotalProcessedNodes; if (record.node == GoalNode) { solution = CalculateSolution(record, returnPartialSolution); CleanUp(); finalTime = Time.realtimeSinceStartup; TotalProcessingTime = finalTime - InitialTime; return(true); } Closed.AddToClosed(record); for (int e = 0; e < record.node.OutEdgeCount; ++e) { ProcessChildNode(record, record.node.EdgeOut(e)); } } CleanUp(); finalTime = Time.realtimeSinceStartup; TotalProcessingTime = finalTime - InitialTime; return(true); }
public bool Search(out GlobalPath solution, bool returnPartialSolution) { //TODO: implement this //to determine the connections of the selected nodeRecord you need to look at the NavigationGraphNode' EdgeOut list //something like this //var outConnections = bestNode.node.OutEdgeCount; //for (int i = 0; i < outConnections; i++) //{ //this.ProcessChildNode(bestNode, bestNode.node.EdgeOut(i)); if (this.Open.CountOpen() == 0) { //Debug.Log("acabou1"); solution = null; return(true); } var currentNode = Open.GetBestAndRemove(); if (this.GoalNode == currentNode.node) { //Debug.Log("acabou2"); solution = CalculateSolution(currentNode, false); return(true); } if (returnPartialSolution) { solution = CalculateSolution(currentNode, true); return(true); } this.Closed.AddToClosed(currentNode); this.TotalExploredNodes += 1; uint outConnections = (uint)currentNode.node.OutEdgeCount; if (outConnections > this.NodesPerFrame) { outConnections = this.NodesPerFrame; //setting nodes visited each frame } if (Open.CountOpen() > this.MaxOpenNodes) { this.MaxOpenNodes = Open.CountOpen(); } for (int i = 0; i < outConnections; i++) { this.ProcessChildNode(currentNode, currentNode.node.EdgeOut(i), i); } this.TotalProcessingTime += Time.deltaTime; //check later solution = null; return(false); }
public bool Search(out GlobalPath solution, bool returnPartialSolution = false) { var startTime = Time.realtimeSinceStartup; int counter = 0; while (true) { if (Open.CountOpen() == 0) { solution = null; TotalProcessingTime += Time.realtimeSinceStartup - startTime; CleanUp(); return(true); } NodeRecord bestNode = Open.GetBestAndRemove(); if (bestNode.node.Equals(GoalNode)) { solution = CalculateSolution(bestNode, false); this.InProgress = false; TotalProcessingTime += Time.realtimeSinceStartup - startTime; CleanUp(); return(true); } Closed.AddToClosed(bestNode); //to determine the connections of the selected nodeRecord you need to look at the NavigationGraphNode' EdgeOut list //something like this var outConnections = bestNode.node.OutEdgeCount; for (int i = 0; i < outConnections; i++) { this.ProcessChildNode(bestNode, bestNode.node.EdgeOut(i)); } if (counter >= NodesPerSearch) { TotalProcessingTime += Time.realtimeSinceStartup - startTime; solution = CalculateSolution(bestNode, true); return(false); } counter += 1; TotalProcessedNodes += 1; if (MaxOpenNodes <= Open.CountOpen()) { MaxOpenNodes = Open.CountOpen(); } } }
public void Search(NavigationGraphNode startNode, NodeGoalBounds nodeGoalBounds) { //TODO: Implement the algorithm that calculates the goal bounds using a dijkstra //Given that the nodes in the graph correspond to the edges of a polygon, we won't be able to use the vertices of the polygon to update the bounding boxes this.Open.Initialize(); this.Closed.Initialize(); //Initialize starting node for Dijkstra NodeRecord StartNode = NodeRecordArray.GetNodeRecord(startNode); StartNode.gValue = 0; StartNode.StartNodeOutConnectionIndex = -1; // -1 corresponds to not having a "color". Valid indices will start at 0 Open.AddToOpen(StartNode); //Dijkstra while (Open.CountOpen() > 0) { NodeRecord currentNode = Open.GetBestAndRemove(); Open.RemoveFromOpen(currentNode); Closed.AddToClosed(currentNode); //We don't fill out the starting position as it is colorless if (currentNode.StartNodeOutConnectionIndex != -1) { var outFillConnections = currentNode.node.OutEdgeCount; Vector3 edgePosition; //Update the bounding box with all positions of EdgeOuts of the current Node for (int i = 0; i < outFillConnections; i++) { edgePosition = currentNode.node.EdgeOut(i).ToNode.Position; nodeGoalBounds.connectionBounds[currentNode.StartNodeOutConnectionIndex].UpdateBounds(edgePosition); //update only the bound corresponding to the ConnectionIndex } } //Process Child Nodes var outConnections = currentNode.node.OutEdgeCount; for (int i = 0; i < outConnections; i++) { this.ProcessChildNode(currentNode, currentNode.node.EdgeOut(i), i); } } }
public bool Search(out GlobalPath solution, bool returnPartialSolution = false) { //TODO: implement this //to determine the connections of the selected nodeRecord you need to look at the NavigationGraphNode' EdgeOut list //something like this int nodesVisited = 0; NodeRecord bestNode; while (this.Open.CountOpen() > 0) { if (Open.CountOpen() > MaxOpenNodes) { MaxOpenNodes = Open.CountOpen(); } bestNode = this.Open.GetBestAndRemove(); this.Closed.AddToClosed(bestNode); if (bestNode.node.Equals(GoalNode)) { solution = CalculateSolution(bestNode, false); TotalProcessingTime += Time.deltaTime; CleanUp(); InProgress = false; return(true); } for (int i = 0; i < bestNode.node.OutEdgeCount; i++) { this.ProcessChildNode(bestNode, bestNode.node.EdgeOut(i), i); } nodesVisited++; TotalExploredNodes++; if (returnPartialSolution && nodesVisited == NodesPerFrame) { solution = CalculateSolution(bestNode, true); TotalProcessingTime += Time.deltaTime; return(false); } } CleanUp(); InProgress = false; solution = null; TotalProcessingTime += Time.deltaTime; return(true); }
public bool Search(out GlobalPath solution, bool returnPartialSolution = false) { var openCount = Open.CountOpen(); solution = null; for (int j = 0; j < this.NodesPerFrame; j++) { if (openCount == 0) { solution = null; this.InProgress = false; this.TotalProcessingTime += Time.time; return(true); } var bestNode = Open.GetBestAndRemove(); this.TotalExploredNodes++; Closed.AddToClosed(bestNode); if (bestNode.node.Equals(GoalNode)) { solution = CalculateSolution(bestNode, false); this.InProgress = false; this.TotalProcessingTime += Time.time; return(true); } var outConnections = bestNode.node.OutEdgeCount; for (int i = 0; i < outConnections; i++) { this.ProcessChildNode(bestNode, bestNode.node.EdgeOut(i), i); } openCount = this.Open.CountOpen(); if (openCount > this.MaxOpenNodes) { this.MaxOpenNodes = openCount; } } if (returnPartialSolution) { solution = CalculateSolution(Open.PeekBest(), true); } return(false); }
public void Search(NavigationGraphNode startNode, NodeGoalBounds nodeGoalBounds) { this.Open.Initialize(); this.Closed.Initialize(); StartNode = startNode; var startNodeRecord = this.NodeRecordArray.GetNodeRecord(startNode); startNodeRecord.gValue = 0; startNodeRecord.hValue = 0; startNodeRecord.fValue = F(startNodeRecord); Closed.AddToClosed(startNodeRecord); var outConnectionsStart = startNodeRecord.node.OutEdgeCount; for (int i = 0; i < outConnectionsStart; i++) { ProcessChildNode(startNodeRecord, startNodeRecord.node.EdgeOut(i), i); NavigationGraphNode childNode = startNodeRecord.node.EdgeOut(i).ToNode; var childNodeRecord = this.NodeRecordArray.GetNodeRecord(childNode); nodeGoalBounds.connectionBounds[i].InitializeBounds(childNodeRecord.node.LocalPosition); } while (Open.CountOpen() > 0) { var bestNode = Open.GetBestAndRemove(); this.Closed.AddToClosed(bestNode); //UnityEngine.Debug.Log("Parent index: " + bestNode.StartNodeOutConnectionIndex); nodeGoalBounds.connectionBounds[bestNode.StartNodeOutConnectionIndex].UpdateBounds(bestNode.node.LocalPosition); var outConnections = bestNode.node.OutEdgeCount; for (int i = 0; i < outConnections; i++) { ProcessChildNode(bestNode, bestNode.node.EdgeOut(i), bestNode.StartNodeOutConnectionIndex); } } }
public int CountOpen() { return Open.CountOpen(); }
//this method should return true if it finished processing, and false if it still needs to continue public bool MapFloodDijkstra() { var processedNodes = 0; while (Open.CountOpen() > 0) { processedNodes++; if (processedNodes > NodesPerFlood) { return(false); } LocationRecord currentRecord = Open.GetBestAndRemove(); Closed.AddToClosed(currentRecord); int outConnections = currentRecord.Location.OutEdgeCount; for (int i = 0; i < outConnections; i++) { var location = GenerateChildNodeRecord(currentRecord, currentRecord.Location.EdgeOut(i)); float influence = InfluenceFunction.DetermineInfluence(currentRecord.StrongestInfluenceUnit, location.Location.Position); if (InfluenceThreshold.CompareTo(influence) > 0) { continue; } LocationRecord neighborRecord = Closed.SearchInClosed(location); if (neighborRecord != null) { if (neighborRecord.Influence >= influence) { continue; } else { Closed.RemoveFromClosed(neighborRecord); } } else { neighborRecord = Open.SearchInOpen(location); if (neighborRecord != null) { if (neighborRecord.Influence < influence) { neighborRecord.StrongestInfluenceUnit = currentRecord.StrongestInfluenceUnit; neighborRecord.Influence = influence; } continue; } else //we found a new record not in open or closed { neighborRecord = new LocationRecord(); neighborRecord.Location = location.Location; } } neighborRecord.StrongestInfluenceUnit = currentRecord.StrongestInfluenceUnit; neighborRecord.Influence = influence; Open.AddToOpen(neighborRecord); } } this.InProgress = false; //this.CleanUp(); return(true); }
public bool Search(out GlobalPath solution, bool returnPartialSolution = false) { var time = UnityEngine.Time.realtimeSinceStartup; var nodesprocessed = 0; var maximumOpen = 0; //to determine the connections of the selected nodeRecord you need to look at the NavigationGraphNode' EdgeOut list //something like this while (true) { if (Open.CountOpen() > maximumOpen) { maximumOpen = Open.CountOpen(); } if (Open.CountOpen() == 0) { solution = null; InProgress = false; TotalProcessedNodes += (uint)nodesprocessed; TotalProcessingTime = UnityEngine.Time.realtimeSinceStartup - time; MaxOpenNodes = maximumOpen; return(true); } NodeRecord bestNode = Open.GetBestAndRemove(); if (nodesprocessed > NodesPerSearch) { if (returnPartialSolution) { solution = CalculateSolution(bestNode, returnPartialSolution); } else { solution = null; } InProgress = true; TotalProcessedNodes += (uint)nodesprocessed; TotalProcessingTime = UnityEngine.Time.realtimeSinceStartup - time; MaxOpenNodes = maximumOpen; return(false); } if (bestNode.node == GoalNode) { solution = CalculateSolution(bestNode, false); InProgress = false; TotalProcessedNodes += (uint)nodesprocessed; TotalProcessingTime = UnityEngine.Time.realtimeSinceStartup - time; MaxOpenNodes = maximumOpen; return(true); } Closed.AddToClosed(bestNode); nodesprocessed++; // //TODO put your code here //or if you would like, you can change just these lines of code this in the original A* Pathfinding Base Class, //create a ProcessChildNode method in the base class with the code from the previous A* algorithm. //if you do this, then you don't need to implement this search method method. Just delete this and don't forget to override the ProcessChildMethod if you do this var outConnections = bestNode.node.OutEdgeCount; for (int i = 0; i < outConnections; i++) { this.ProcessChildNode(bestNode, bestNode.node.EdgeOut(i)); } } }
public bool Search(out GlobalPath solution, bool returnPartialSolution = false) { //TODO put the code from the previous LAB here //you will get compiler errors, because I change the method names in the IOpenSet and IClosedSet interfaces //sorry but I had to do it because if not, Unity profiler would consider the Search method in Open and Closed to be the same //and you would not be able to see the difference in performance searching the Open Set and in searching the closed set //so just replace this.Open.Search(...) by this.Open.SearchInOpen(...) and all other methods where you get the compilation errors var CurrentSearchNodes = 0; var NodesProcessed = 0; var MaxOpenSize = 0; float StartTime = Time.realtimeSinceStartup; while (true) { if (Open.CountOpen() > MaxOpenSize) { MaxOpenSize = Open.CountOpen(); } if (Open.CountOpen() == 0) { solution = null; TotalProcessedNodes = (uint)NodesProcessed; MaxOpenNodes = MaxOpenSize; this.InProgress = false; TotalProcessingTime = Time.realtimeSinceStartup - StartTime; return(true); } if (NodesPerSearch < CurrentSearchNodes) { if (returnPartialSolution) { solution = CalculateSolution(this.Open.PeekBest(), returnPartialSolution); } else { solution = null; } TotalProcessedNodes = (uint)NodesProcessed; MaxOpenNodes = MaxOpenSize; TotalProcessingTime = Time.realtimeSinceStartup - StartTime; return(false); } NodeRecord CurrentNode = Open.GetBestAndRemove(); if (CurrentNode.node == GoalNode) { InProgress = false; TotalProcessedNodes = (uint)NodesProcessed; MaxOpenNodes = MaxOpenSize; TotalProcessingTime = Time.realtimeSinceStartup - StartTime; solution = CalculateSolution(CurrentNode, false); return(true); } Closed.AddToClosed(CurrentNode); CurrentSearchNodes++; NodesProcessed++; var NodeActions = CurrentNode.node.OutEdgeCount; for (int i = 0; i < NodeActions; i++) { ProcessChildNode(CurrentNode, CurrentNode.node.EdgeOut(i)); } } }