예제 #1
0
        public static List <T> AEstrela <T>(this Grafo <T, double> grafo, T inicio, T fim, Func <T, double> heuristicCostEstimate = null, Action <List <T>, double> onChangePathCallback = null) where T : class
        {
            HashSet <T> closedSet = new HashSet <T>(), openSet = new HashSet <T> {
                inicio
            };

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

            var gScore = new Dictionary <T, double>();

            foreach (var vertex in grafo.PegarVertices())
            {
                gScore[vertex] = double.PositiveInfinity;
            }

            gScore[inicio] = 0;

            var fScore = new Dictionary <T, double>();

            foreach (var vertex in grafo.PegarVertices())
            {
                fScore[vertex] = double.PositiveInfinity;
            }

            if (heuristicCostEstimate == null)
            {
                heuristicCostEstimate = t => 0.0;
            }

            fScore[inicio] = gScore[inicio] + heuristicCostEstimate(inicio);

            while (openSet.Count > 0)
            {
                var current = openSet.Aggregate((a, b) => fScore[a] < fScore[b] ? a : b);

                if (current == fim)
                {
                    var finalPath = CaminhoDeReconstrução(cameFrom, fim);

                    if (onChangePathCallback != null)
                    {
                        onChangePathCallback(finalPath, gScore[fim]);
                    }

                    return(finalPath);
                }

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

                foreach (var neighbor in grafo.VerticesAdjacentes(current))
                {
                    if (closedSet.Contains(neighbor))
                    {
                        continue;
                    }

                    var tentativeGScore = gScore[current] + grafo.PegarAresta(current, neighbor);

                    if (!openSet.Contains(neighbor) || tentativeGScore < gScore[neighbor])
                    {
                        cameFrom[neighbor] = current;
                        gScore[neighbor]   = tentativeGScore;
                        fScore[neighbor]   = gScore[neighbor] + heuristicCostEstimate(neighbor);
                        if (!openSet.Contains(neighbor))
                        {
                            openSet.Add(neighbor);
                        }

                        if (onChangePathCallback != null)
                        {
                            onChangePathCallback(CaminhoDeReconstrução(cameFrom, neighbor), gScore[neighbor]);
                        }
                    }
                }
            }

            throw new Exception();
        }