Exemplo n.º 1
0
        static AStarState <T> NextAStarState <T>(AStarState <T> initialState, IGraphNode <T> node,
                                                 IGraphNode <T> to
                                                 )
        {
            //'let'
            var nodeGScore = initialState.gScore[node];

            //'in'
            return(node.Where(x => !initialState.closedSet.Contains(x.Second)).Aggregate(
                       initialState,
                       (state, transition) =>
            {
                var newGScore = nodeGScore + transition.First;
                var neighbor = transition.Second;

                if (!state.openSet.Contains(neighbor) || newGScore < state.gScore[neighbor])
                {
                    state.gScore[neighbor] = newGScore;
                    state.fScore[neighbor] = newGScore + neighbor.Heuristic(to);
                    state.previous[neighbor] = node;
                    state.openSet.Add(neighbor);
                }

                return state;
            }
                       ));
        }
Exemplo n.º 2
0
        public static IEnumerable <IGraphNode <T> > AStar <T>(this IGraphNode <T> from, IGraphNode <T> to)
        {
            //'let'
            //Initial state of the algorithm
            var closedSet = new HashSet <IGraphNode <T> >();
            var openSet   = new HashSet <IGraphNode <T> >()
            {
                from
            };
            var gScore = new Map <IGraphNode <T>, float>()
            {
                { from, 0 }
            };
            var fScore = new Map <IGraphNode <T>, float>()
            {
                { from, from.Heuristic(to) }
            };
            var previous     = new Map <IGraphNode <T>, IGraphNode <T> >();
            var initialState = AStarState.New(closedSet, openSet, gScore, fScore, previous);

            //Compute final state from a sequence generated from the initial state
            //(the functional replacement of the queue), that is the last state of the following
            //generated sequence
            var finalState = Generate(initialState, state =>
            {
                //If we found the last node, we're finished generating states
                if (state.lastNode != null)
                {
                    return(null);
                }

                //'let'
                //Get the one with lowest fScore, lazyness prevents the full query from executing
                var node = state.openSet.OrderBy(x => state.fScore[x]).First();
                //Reached the target, finish the state generation
                if (node.Satisfies(to) || openSet.Count == 0)
                {
                    return(FinalAStarState(state, node));
                }

                //'in'
                return(NextAStarState(CloseNode(state, node), node, to));
            }).Last();

            //'in'
            //Reconstruct the path
            return(Generate(finalState.lastNode, node => finalState.previous[node]).Reverse());
        }
Exemplo n.º 3
0
 static AStarState <T> FinalAStarState <T>(AStarState <T> state, IGraphNode <T> node)
 {
     state.lastNode = node;
     return(state);
 }
Exemplo n.º 4
0
 static AStarState <T> CloseNode <T>(AStarState <T> state, IGraphNode <T> node)
 {
     state.openSet.Remove(node);
     state.closedSet.Add(node);
     return(state);
 }