/// <summary>
        /// Adds the specified node to the open nodes collection.
        /// </summary>
        /// <param name="node">Node to be added.</param>
        /// <param name="gValue">Calculated distance from the start.</param>
        /// <param name="predecessor">Predecessor node.</param>
        /// <param name="appliedOperator">Predecessor operator.</param>
        protected override void AddToOpenNodes(ISearchNode node, int gValue, ISearchNode predecessor, IOperator appliedOperator)
        {
            if (gValue > LimitValue)
            {
                return;
            }

            NodeInfo nodeInfo;

            if (NodesInfo.TryGetValue(node, out nodeInfo))
            {
                if (nodeInfo.GValue > gValue)
                {
                    nodeInfo.GValue      = gValue;
                    nodeInfo.Predecessor = Tuple.Create(predecessor, appliedOperator);
                    NodesInfo[node]      = nodeInfo;

                    double hValue = Heuristic.GetValue(node);
                    OpenNodes.Add(gValue + hValue, node);
                }
            }
            else
            {
                double hValue = Heuristic.GetValue(node);
                double fValue = gValue + hValue;
                if (fValue > LimitValue)
                {
                    LowestValueOverLimit = Math.Min(LowestValueOverLimit, fValue);
                    return;
                }
                NodesInfo.Add(node, new NodeInfo(gValue, Tuple.Create(predecessor, appliedOperator)));
                OpenNodes.Add(fValue, node);
            }
        }
예제 #2
0
파일: Traversal.cs 프로젝트: XIntric/AStar
        public async Task <INode <TState, TCost> > StepAsync()
        {
            if (Result.IsCompleted)
            {
                return(Result.Result);
            }
            try
            {
                //System.Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}: Step started.");


                return(await OpenNodes.PerformWorkerOperationAsync(
                           async node =>
                {
                    Diag_NodeTraversing?.Invoke(node);
                    if (Problem.Comparer.Compare(node.EstimatedDistance, Scenario.AcceptedDistance) <= 0) //Found a goal node
                    {
                        lock (ResultSetter)
                        {
                            ResultSetter.SetResult(node);
                            WorkTokenSource.Cancel();
                            return node;
                        }
                    }


                    var newnodes = (await Problem.ExpandNode(new NodeExpansionImplementation(this, node))).ToList();

                    foreach (var newnode in newnodes)
                    {
                        OpenNodes.Add(newnode);
                    }

                    Diag_NodeTraversed?.Invoke(node);
                    return node;
                }));
            }
            catch (NodeRepository <TState, TCost> .QueueExhaustedException)
            {
                if (Result.IsCompleted)
                {
                    return(Result.Result);
                }
                if (Result.IsFaulted)
                {
                    throw Result.Exception;
                }
                var ex = new MissingSolutionException();
                ResultSetter.TrySetException(ex);
                throw ex;
            }
            catch (Exception e)
            {
                ResultSetter.TrySetException(e);
                throw;
            }
        }
예제 #3
0
        /// <summary>
        /// Computes the heuristic value for the specified node and inserts both into open nodes. Should not be called separately, but only
        /// within AddToOpenNodes() method containing necessary checks and additional operations.
        /// </summary>
        /// <param name="node">Node to be added.</param>
        /// <param name="gValue">Calculated distance from the start.</param>
        /// <param name="predecessor">Predecessor node.</param>
        /// <param name="appliedOperator">Predecessor operator.</param>
        protected virtual void ComputeHeuristicAndInsertNewOpenNode(ISearchNode node, int gValue, ISearchNode predecessor, IOperator appliedOperator)
        {
            double hValue = (IsComplexHeuristic) ? ((ComplexHeuristic)Heuristic).GetValue(node, predecessor, appliedOperator) : Heuristic.GetValue(node);

            if (!double.IsInfinity(hValue)) // Infinity heuristic indicates dead-end
            {
                OpenNodes.Add(ComputeNewOpenNodeValueWithTieBreakingRule(gValue, hValue), node);
            }
        }
예제 #4
0
        public List <Node> FindPath(Node start, Node end)
        {
            if (!IsInitialized)
            {
                throw new Exception("First you need to Initialize the grid.");
            }
            if (start?.IsUnavailable == true || end?.IsUnavailable == true)
            {
                throw new Exception("Start currentNode or End currentNode is unavailable. Pick others.");
            }
            StartNode = start;
            EndNode   = end;
            CalculateHeruisticFromNode(StartNode);
            OpenNodes.Add(StartNode);

            var currentNode = StartNode;

            while (currentNode != null && !currentNode.Equals(EndNode))
            {
                ClosedNodes.Add(currentNode);
                OpenNodes.Remove(currentNode);
                currentNode = SelectNextNode(currentNode);
            }

            if (currentNode == null)
            {
                throw new Exception("Cannot reach the end.");
            }
            var pathList = new List <Node>();
            var nod      = currentNode;

            nod.FindNeighbours(this);
            while (nod != null && !nod.Equals(StartNode))
            {
                pathList.Add(nod);
                if (!nod.Neighbours.Any())
                {
                    nod.FindNeighbours(this);
                }
                // nod = nod.Neighbours.OrderBy(x => x.Fn).FirstOrDefault(x => !(x.IsUnavailable ?? false));
                nod = nod.Parent;
            }
            if (nod == null)
            {
                throw new Exception("Something went wrong. !!!!");
            }
            pathList.Add(StartNode);
            pathList.Reverse();
            return(pathList);
        }
        /// <summary>
        /// Computes the heuristic value for the specified node and inserts both into open nodes. Should not be called separately, but only
        /// within AddToOpenNodes() method containing necessary checks and additional operations.
        /// </summary>
        /// <param name="node">Node to be added.</param>
        /// <param name="gValue">Calculated distance from the start.</param>
        /// <param name="predecessor">Predecessor node.</param>
        /// <param name="appliedOperator">Predecessor operator.</param>
        protected override void ComputeHeuristicAndInsertNewOpenNode(ISearchNode node, int gValue, ISearchNode predecessor, IOperator appliedOperator)
        {
            for (int i = 0; i < NumberOfOpenLists; ++i)
            {
                Heuristic = Heuristics[i];
                OpenNodes = OpenLists[i];

                double hValue = Heuristic.GetValue(node);
                if (!double.IsInfinity(hValue)) // Infinity heuristic indicates dead-end
                {
                    OpenNodes.Add(ComputeNewOpenNodeValueWithTieBreakingRule(gValue, hValue), node);
                    ++AllOpenNodesCount;
                }
            }
        }
예제 #6
0
        /// <summary>
        /// Adds the specified node to the open nodes collection.
        /// </summary>
        /// <param name="node">Node to be added.</param>
        /// <param name="gValue">Calculated distance from the start.</param>
        /// <param name="hValue">Heuristic distance to the goal.</param>
        /// <param name="predecessor">Predecessor node.</param>
        /// <param name="appliedOperator">Predecessor operator.</param>
        protected void AddToOpenNodes(ISearchNode node, int gValue, double hValue, ISearchNode predecessor, IOperator appliedOperator)
        {
            NodeInfo nodeInfo;

            if (NodesInfo.TryGetValue(node, out nodeInfo))
            {
                if (nodeInfo.GValue > gValue)
                {
                    nodeInfo.GValue      = gValue;
                    nodeInfo.Predecessor = Tuple.Create(predecessor, appliedOperator);
                    NodesInfo[node]      = nodeInfo;

                    OpenNodes.Add(gValue + hValue, node);
                }
            }
            else
            {
                NodesInfo.Add(node, new NodeInfo(gValue, Tuple.Create(predecessor, appliedOperator)));
                OpenNodes.Add(gValue + hValue, node);
            }
        }
예제 #7
0
 /// <summary>
 /// Sets the initial search node of the search procedure.
 /// </summary>
 /// <param name="initialNode">Initial node of the search.</param>
 protected virtual void SetInitialNode(ISearchNode initialNode)
 {
     OpenNodes.Add(0, initialNode);
     NodesInfo.Add(initialNode, new NodeInfo(0, null));
 }
예제 #8
0
 public void OnEnterNode(Guid node)
 {
     NodeCount++;
     OpenNodes.Add(node);
 }
예제 #9
0
        public async Task FindPathAsync(CancellationToken cancellationToken)
        {
            await Task.Factory.StartNew(() =>
            {
                if (grid.Algorithm == null)
                {
                    throw new NullReferenceException("Scenario grid does not have an assigned pathfinding algorithim!");
                }

                while (true)
                {
                    if (OpenNodes.Count == 1 && OpenNodes[0] == grid.StartingNode)
                    {
                        CurrentNode = OpenNodes[0];
                    }
                    else
                    {
                        CurrentNode = GetNodeWithLowestFCost(OpenNodes);
                    }
                    Thread.Sleep(VisualizationTime);
                    OpenNodes.Remove(CurrentNode);
                    ClosedNodes.Add(CurrentNode);
                    Thread.Sleep(VisualizationTime);

                    if (CurrentNode == grid.TargetNode)
                    {
                        SetSolution(cancellationToken);
                        PathfindingFinished?.Invoke(this, null);
                        return;
                    }

                    neighbouringNodes = GetNeighbouringNodes(CurrentNode, allowDiagonals: AllowDiagonalMovement);
                    foreach (Node n in neighbouringNodes)
                    {
                        if (cancellationToken.IsCancellationRequested)
                        {
                            ClearPath();
                            PathfindingFinished?.Invoke(this, null);
                            return;
                        }

                        if (!n.IsTraversable || ClosedNodes.Contains(n))
                        {
                            continue;
                        }

                        if (IsNewPathShorter(CurrentNode, n) || !OpenNodes.Contains(n))
                        {
                            n.GCost  = CurrentNode.GCost + GetDistance(CurrentNode, n);
                            n.HCost  = GetDistance(n, grid.TargetNode);
                            n.Parent = CurrentNode;

                            if (!OpenNodes.Contains(n))
                            {
                                OpenNodes.Add(n);
                            }
                        }

                        Thread.Sleep(VisualizationTime / 3);
                    }
                }
            });
        }