예제 #1
0
        public IEnumerable <T> Search(T start, T goal)
        {
            var closedSet = new HashSet <T>();
            var openSet   = new HashSet <T> {
                start
            };

            var cameFrom = new Dictionary <T, T>();

            var gScore = new MapWithDefaultValueOfInfinity {
                [start] = 0
            };
            var fScore = new MapWithDefaultValueOfInfinity();

            while (openSet.Any())
            {
                var current = NodeHavingTheLowestValue(openSet, fScore);
                if (current.Equals(goal))
                {
                    return(ReconstructPath(current, cameFrom));
                }

                openSet.Remove(current);
                closedSet.Add(current);

                foreach (var neighbor in _neighborsProvider.Get(current))
                {
                    if (closedSet.Contains(neighbor))
                    {
                        continue;
                    }

                    if (!openSet.Contains(neighbor))
                    {
                        openSet.Add(neighbor);
                    }

                    var tentativeGScore = gScore[current] + _distanceBetweenProvider.Get(current, neighbor);
                    if (tentativeGScore > gScore[neighbor])
                    {
                        continue;
                    }

                    cameFrom[neighbor] = current;
                    gScore[neighbor]   = tentativeGScore;
                    fScore[neighbor]   = gScore[neighbor] + _heuristicCostEstimateProvider.Get(neighbor, goal);
                }
            }

            return(null);
        }
예제 #2
0
        private static T NodeHavingTheLowestValue(IEnumerable <T> nodes, MapWithDefaultValueOfInfinity values)
        {
            T result = null;

            foreach (var node in nodes)
            {
                if (result == null || values[node] < values[result])
                {
                    result = node;
                }
            }
            if (result == null)
            {
                throw new Exception("Something goes wrong.");
            }
            return(result);
        }