public override bool Search(out Path solution, bool returnPartialSolution = false) { NodeRecord node; var nodeCount = 0; while (this.Open.CountOpen() != 0) { node = this.Open.GetBestAndRemove(); nodeCount++; this.TotalProcessedNodes++; var count = this.Open.CountOpen(); if (count > this.MaxOpenNodes) this.MaxOpenNodes = count; if (nodeCount < this.NodesPerSearch) { if (GoalNode.Equals(node.node)) { solution = this.CalculateSolution(node, false); InProgress = false; this.TotalProcessingTime = UnityEngine.Time.deltaTime; return true; } this.NodeRecordArray.AddToClosed(node); var outConnections = node.node.OutEdgeCount; for (int i = 0; i < outConnections; i++) { this.ProcessChildNode(node, node.node.EdgeOut(i)); } } else if (returnPartialSolution) { solution = this.CalculateSolution(node, true); InProgress = true; this.TotalProcessingTime = UnityEngine.Time.deltaTime; return false; } } InProgress = false; solution = null; return true; }
private Path CalculateSolution(NodeRecord node, bool partial) { var path = new Path { IsPartial = partial }; var currentNode = node; path.PathPositions.Add(this.GoalPosition); //I need to remove the first Node and the last Node because they correspond to the dummy first and last Polygons that were created by the initialization. //And for instance I don't want to be forced to go to the center of the initial polygon before starting to move towards my destination. //skip the last node, but only if the solution is not partial (if the solution is partial, the last node does not correspond to the dummy goal polygon) if (!partial && currentNode.parent != null) { currentNode = currentNode.parent; } while (currentNode.parent != null) { path.PathNodes.Add(currentNode.node); //we need to reverse the list because this operator add elements to the end of the list path.PathPositions.Add(currentNode.node.LocalPosition); if (currentNode.parent.parent == null) break; //this skips the first node currentNode = currentNode.parent; } path.PathNodes.Reverse(); path.PathPositions.Reverse(); return path; }
public override bool Search(out Path solution, bool returnPartialSolution = false) { float startTime = Time.realtimeSinceStartup; float endTime; TotalProcessedNodes = 0; while (this.NodeRecordArray.CountOpen() > 0) { var currentNode = NodeRecordArray.GetBestAndRemove(); if (currentNode.node.Equals(GoalNode)) { endTime = Time.realtimeSinceStartup; TotalProcessingTime = endTime - startTime; solution = CalculateSolution(currentNode, false); this.InProgress = false; return true; } if (returnPartialSolution && TotalProcessedNodes >= this.NodesPerSearch) { endTime = Time.realtimeSinceStartup; TotalProcessingTime = endTime - startTime; solution = CalculateSolution(currentNode, true); return false; } TotalProcessedNodes++; this.NodeRecordArray.AddToClosed(currentNode.node, currentNode); var outConnections = currentNode.node.OutEdgeCount; for (int i = 0; i < outConnections; i++) { var childNode = currentNode.node.EdgeOut(i); if (UsingGoalBounding && currentNode.node != this.StartNode && childNode.ToNode != StartNode && childNode.ToNode != GoalNode && !withinGoalBounds(currentNode, i) ) continue; this.ProcessChildNode(currentNode, childNode); } } endTime = Time.realtimeSinceStartup; TotalProcessingTime = endTime - startTime; solution = null; return true; }
//this method should return true if the Search process finished (i.e either because it found a solution or because there was no solution //it should return false if the search process didn't finish yet //when returning true, the solution parameter should be set to null if there is no solution. Otherwise it must contain the found solution //if the parameter returnPartialSolution is true, then the user wants to have a partial path to the best node so far even when the search has not finished searching public bool Search(out Path solution, bool returnPartialSolution = false) { //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++) //{ //var childNode = GenerateChildNodeRecord(bestNode, bestNode.node.EdgeOut(i)); //loop do // if EMPTY ? (open)then return failure // node POP(open) // if problem.Goal - Test(node.State) then return Solution(node) // closed Insert(node, closed) // for each action in problem.Actions(node.State) do // child CHILD - NODE(problem, node, action) // if child.state is not in open nor in closed then // open Insert(child, open) // else if child.state is in open with higher F-value then // replace the node in open with child // else if child.state is in closed with higher F-value then // closed Remove(child, closed) // open Insert(child, open) NodeRecord node; var nodeCount = 0; while (this.Open.Count() != 0) { node = this.Open.GetBestAndRemove(); nodeCount++; this.TotalProcessedNodes++; var count = this.Open.Count(); if (count > this.MaxOpenNodes) this.MaxOpenNodes = count; Debug.Log(nodeCount); if (nodeCount < this.NodesPerSearch) { if (GoalNode.Equals(node.node)) { solution = this.CalculateSolution(node, false); InProgress = false; this.TotalProcessingTime = UnityEngine.Time.deltaTime; return true; } this.Closed.Add(node); var outConnections = node.node.OutEdgeCount; for (int i = 0; i < outConnections; i++) { var childNode = GenerateChildNodeRecord(node, node.node.EdgeOut(i)); var childInOpen = this.Open.Search(childNode); var childInClosed = this.Closed.Search(childNode); if ((childInOpen == null) && (childInClosed == null)) { this.Open.Add(childNode); } else if ((childInOpen != null) && ( (childInOpen.fValue > childNode.fValue) || ((childInOpen.fValue == childNode.fValue) && (childInOpen.hValue > childNode.hValue)) )) { this.Open.Replace(childInOpen, childNode); } else if ((childInClosed != null) && ((childInClosed.fValue > childNode.fValue) || ((childInClosed.fValue == childNode.fValue) && (childInClosed.hValue > childNode.hValue)))) { this.Closed.Remove(childInClosed); this.Open.Add(childNode); } } } else if (returnPartialSolution) { solution = this.CalculateSolution(node, true); InProgress = true; this.TotalProcessingTime = UnityEngine.Time.deltaTime; return false; } } InProgress = false; solution = null; return true; }
public virtual bool Search(out Path 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 NodeRecord node; var nodeCount = 0; while (this.Open.CountOpen() != 0) { node = this.Open.GetBestAndRemove(); nodeCount++; this.TotalProcessedNodes++; var count = this.Open.CountOpen(); if (count > this.MaxOpenNodes) this.MaxOpenNodes = count; if (nodeCount < this.NodesPerSearch) { //Debug.Log(this.NodesPerSearch); if (GoalNode.Equals(node.node)) { solution = this.CalculateSolution(node, false); InProgress = false; this.TotalProcessingTime = UnityEngine.Time.deltaTime; return true; } this.Closed.AddToClosed(node); var outConnections = node.node.OutEdgeCount; for (int i = 0; i < outConnections; i++) { var childNode = GenerateChildNodeRecord(node, node.node.EdgeOut(i)); var childInOpen = this.Open.SearchInOpen(childNode); var childInClosed = this.Closed.SearchInClosed(childNode); if ((childInOpen == null) && (childInClosed == null)) { this.Open.AddToOpen(childNode); } else if ((childInOpen != null) && ((childInOpen.fValue > childNode.fValue) || ((childInOpen.fValue == childNode.fValue) && (childInOpen.hValue > childNode.hValue)))) { this.Open.Replace(childInOpen, childNode); } else if ((childInClosed != null) && ((childInClosed.fValue > childNode.fValue) || ((childInClosed.fValue == childNode.fValue) && (childInClosed.hValue > childNode.hValue)))) { this.Closed.RemoveFromClosed(childInClosed); this.Open.AddToOpen(childNode); } } } else if (returnPartialSolution) { solution = this.CalculateSolution(node, true); InProgress = true; this.TotalProcessingTime = UnityEngine.Time.deltaTime; return false; } } InProgress = false; solution = null; return true; }
public bool Search(out Path solution, bool returnPartialSolution = false) { float runningTime = Time.realtimeSinceStartup; //to determine the connections of the selected nodeRecord you need to look at the NavigationGraphNode' EdgeOut list //something like this int processedNode = 0; while (Open.CountOpen() != 0) { if (Open.CountOpen() > MaxOpenNodes) { MaxOpenNodes = Open.CountOpen(); } ++processedNode; ++TotalProcessedNodes; NodeRecord bestNode = Open.GetBestAndRemove(); if (GoalNode.Equals(bestNode.node)) { this.CleanUp(); this.InProgress = false; TotalProcessingTime += Time.realtimeSinceStartup - runningTime; solution = CalculateSolution(bestNode, false); return true; } else { this.Closed.AddToClosed(bestNode); } int outConnections = bestNode.node.OutEdgeCount; for (int i = 0; i < outConnections; i++) { ProcessChildNode(bestNode, bestNode.node.EdgeOut(i)); } if (processedNode >= NodesPerSearch) { TotalProcessingTime += Time.realtimeSinceStartup - runningTime; if (returnPartialSolution) { solution = CalculateSolution(Open.PeekBest(), true); } else { solution = null; } return false; } } this.CleanUp(); this.InProgress = false; TotalProcessingTime += Time.realtimeSinceStartup - runningTime; solution = null; return true; }
//this method should return true if the Search process finished (i.e either because it found a solution or because there was no solution //it should return false if the search process didn't finish yet //when returning true, the solution parameter should be set to null if there is no solution. Otherwise it must contain the found solution //if the parameter returnPartialSolution is true, then the user wants to have a partial path to the best node so far even when the search has not finished searching public bool Search(out Path solution, bool returnPartialSolution = false) { float runningTime = Time.realtimeSinceStartup; //to determine the connections of the selected nodeRecord you need to look at the NavigationGraphNode' EdgeOut list //something like this int processedNode = 0; while (Open.Count() != 0) { if (Open.Count() > MaxOpenNodes) { MaxOpenNodes = Open.Count(); } ++processedNode; ++TotalProcessedNodes; NodeRecord bestNode = Open.GetBestAndRemove(); if (GoalNode.Equals(bestNode.node)) { this.CleanUp(); this.InProgress = false; TotalProcessingTime += Time.realtimeSinceStartup - runningTime; solution = CalculateSolution(bestNode, false); return true; } else { this.Closed.Add(bestNode); } int outConnections = bestNode.node.OutEdgeCount; for (int i = 0; i < outConnections; i++) { var childNode = GenerateChildNodeRecord(bestNode, bestNode.node.EdgeOut(i)); NodeRecord nodeInOpen = Open.Search(childNode); NodeRecord nodeInClosed = Closed.Search(childNode); // if child state is not in open or in closed then insert in open if (nodeInOpen == null && nodeInClosed == null) { Open.Add(childNode); } else { // if child state is in open with higher F-value replace old one if (nodeInOpen != null && nodeInOpen.fValue > childNode.fValue) { Open.Replace(nodeInOpen, childNode); } else { // if child state is in close with higher F-value then delete old and add new to open if (nodeInClosed != null && nodeInClosed.fValue > childNode.fValue) { Closed.Remove(nodeInClosed); Open.Add(childNode); } } } } if (processedNode >= NodesPerSearch) { TotalProcessingTime += Time.realtimeSinceStartup - runningTime; if (returnPartialSolution) { solution = CalculateSolution(Open.PeekBest(), true); } else { solution = null; } return false; } } this.CleanUp(); this.InProgress = false; TotalProcessingTime += Time.realtimeSinceStartup - runningTime; solution = null; return true; }
public virtual bool Search(out Path solution, bool returnPartialSolution = false) { float startTime = Time.realtimeSinceStartup; float endTime; TotalProcessedNodes = 0; var partialMaxOpenNodes = 0; while (this.Open.CountOpen() > 0) { var currentNode = Open.GetBestAndRemove(); if (currentNode.node.Equals(GoalNode)) { endTime = Time.realtimeSinceStartup; TotalProcessingTime = endTime - startTime; solution = CalculateSolution(currentNode, false); this.InProgress = false; return true; } if (returnPartialSolution && TotalProcessedNodes >= this.NodesPerSearch) { endTime = Time.realtimeSinceStartup; TotalProcessingTime = endTime - startTime; solution = CalculateSolution(currentNode, true); return false; } TotalProcessedNodes++; this.Closed.AddToClosed(currentNode.node, currentNode); var outConnections = currentNode.node.OutEdgeCount; for (int i = 0; i < outConnections; i++) { var childNode = GenerateChildNodeRecord(currentNode, currentNode.node.EdgeOut(i)); NodeRecord nodeInOpen = Open.SearchInOpen(childNode.node, childNode); NodeRecord nodeInClosed = Closed.SearchInClosed(childNode.node, childNode); if (nodeInOpen == null && nodeInClosed == null) { this.Open.AddToOpen(currentNode.node, childNode); partialMaxOpenNodes++; } else if (nodeInOpen != null && nodeInOpen.fValue > childNode.fValue) this.Open.Replace(nodeInOpen, childNode); else if (nodeInClosed != null && nodeInClosed.fValue > childNode.fValue) { this.Closed.RemoveFromClosed(currentNode.node, childNode); this.Open.AddToOpen(childNode.node, childNode); } if (MaxOpenNodes < partialMaxOpenNodes) { MaxOpenNodes = partialMaxOpenNodes; } } } endTime = Time.realtimeSinceStartup; TotalProcessingTime = endTime - startTime; solution = null; return true; //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 }