/// <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
        /// <summary>
        /// Initialization of the search procedure. Should be done before every search!
        /// </summary>
        /// <param name="type">Search type.</param>
        protected override void InitSearch(SearchType type)
        {
            base.InitSearch(type);

            OpenNodes.Clear();
            NodesInfo.Clear();
        }
示例#3
0
        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;
            }
        }
示例#4
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);
            }
        }
        /// <summary>
        /// Gets the new open node from the list of open nodes (with minimal value).
        /// </summary>
        /// <returns>New open node.</returns>
        protected override ISearchNode GetMinOpenNode()
        {
            do // periodically iterate over the non-empty open lists
            {
                CurrentOpenListIndex = (CurrentOpenListIndex + 1) % NumberOfOpenLists;
                OpenNodes            = OpenLists[CurrentOpenListIndex];
            }while (OpenNodes.GetSize() <= 0);

            --AllOpenNodesCount;
            return(base.GetMinOpenNode());
        }
示例#6
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);
        }
示例#7
0
        public Node SelectNextNode(Node currentNode)
        {
            if (!IsInitialized)
            {
                throw new Exception("Grid is not initialized");
            }
            if (FindNeighbours(currentNode).Count <= 0)
            {
                return(OpenNodes.LastOrDefault());
            }
            var neighboursList = currentNode.Neighbours.Where(x => !ClosedNodes.Contains(x, nodeComparer)).ToList();

            OpenNodes.AddRange(neighboursList.Where(x => !OpenNodes.Contains(x, nodeComparer)));
            return(OpenNodes.OrderBy(x => x.Fn).ThenBy(x => x.Id).FirstOrDefault());
        }
        /// <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;
                }
            }
        }
示例#9
0
        /// <summary>
        /// Logs the search statistics.
        /// </summary>
        protected override void LogSearchStatistics()
        {
            if (LoggingEnabled)
            {
                string message = $"Expanded nodes: {NodesInfo.Count - OpenNodes.GetSize()}" +
                                 $"\tOpen nodes: {GetOpenNodesCount()}" +
                                 $"\tVisited nodes: {GetProcessedNodesCount()}";

                IHeuristic heuristic = Heuristic as IHeuristic;
                if (heuristic != null)
                {
                    message += $"\tHeuristic calls: {heuristic.GetCallsCount()}";
                }

                LogMessage(message);
            }
        }
示例#10
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);
            }
        }
示例#11
0
 public void OnEnterNode(Guid node)
 {
     NodeCount++;
     OpenNodes.Add(node);
 }
示例#12
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);
                    }
                }
            });
        }
示例#13
0
 public void OnCloseNode(Guid node)
 {
     OpenNodes.Remove(node);
 }
示例#14
0
 /// <summary>
 /// Gets the number of open nodes.
 /// </summary>
 /// <returns>Number of open nodes.</returns>
 protected override long GetOpenNodesCount()
 {
     return(OpenNodes.GetSize());
 }
示例#15
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));
 }
示例#16
0
 /// <summary>
 /// Gets the new open node from the list of open nodes (with minimal value).
 /// </summary>
 /// <returns>New open node.</returns>
 protected virtual ISearchNode GetMinOpenNode()
 {
     return(OpenNodes.RemoveMin());
 }
示例#17
0
 /// <summary>
 /// Checks whether there is any open node for the search available.
 /// </summary>
 /// <returns>True if there is some open node available. False otherwise.</returns>
 protected virtual bool HasAnyOpenNode()
 {
     return(OpenNodes.GetSize() > 0);
 }