Exemple #1
0
        /// <summary>Performs the iterative deepening search.</summary>
        SearchResult Search(StateType initialState, SearchLimiter limiter,
                            out Node <StateType, ActionType> solution, bool bidirectional)
        {
            if (limiter != null)
            {
                limiter.Start();
            }

            solution = new Node <StateType, ActionType>();

            for (DepthLimit = 1; limiter == null || !limiter.LimitReached; DepthLimit++)
            {
                SearchResult result = bidirectional ?
                                      base.FinishBidirectionalSearch(initialState, limiter, out solution) :
                                      base.FinishSearch(initialState, limiter, out solution);

                // if the search completed without reaching any limit, then we're done
                if (result != SearchResult.LimitReached)
                {
                    return(result);
                }

                // if the depth limit is about to wrap around, there's no point in continuing
                if (DepthLimit == int.MaxValue)
                {
                    return(SearchResult.LimitReached);
                }
            }

            return(SearchResult.LimitReached);
        }
Exemple #2
0
 /// <include file="documentation.xml" path="/AI/Search/ISearch/Search_State/*"/>
 public override SearchResult Search(StateType initialState, SearchLimiter limiter,
                                     out Node <StateType, ActionType> solution)
 {
     if (limiter != null)
     {
         limiter.Start();
     }
     return(FinishSearch(initialState, limiter, out solution));
 }
Exemple #3
0
 /// <include file="documentation.xml" path="/AI/Search/IBidirectionalGraphSearch/BidirectionalSearch_State/*"/>
 public override SearchResult BidirectionalSearch(StateType initialState, SearchLimiter limiter,
                                                  out Node <StateType, ActionType> solution)
 {
     AssertBidirectionallySearchable();
     if (limiter != null)
     {
         limiter.Start();
     }
     return(FinishBidirectionalSearch(initialState, limiter, out solution));
 }
Exemple #4
0
        /// <include file="documentation.xml" path="/AI/Search/GameSearchBase/IterativeDeepeningSearch/*"/>
        /// <include file="documentation.xml" path="/AI/Search/ISearch/SearchCommon/param[@name='limiter']"/>
        /// <include file="documentation.xml" path="/AI/Search/ISearch/Search_State/param[@name='initialState']"/>
        public SearchResult IterativeDeepeningSearch(StateType initialState, SearchLimiter limiter,
                                                     out StateActionPair <StateType, ActionType> solution)
        {
            SearchResult result;
            int          userDepthLimit = DepthLimit; // save the original depth limit so we can restore it later

            if (limiter == null)                      // if we have an no limit, we might as well do a regular search
            {
                DepthLimit = Infinite;                // with unlimited depth because we have unlimited time
                result     = Search(initialState, limiter, out solution);
            }
            else
            {
                PrepareToStartSearch(initialState); // otherwise, verify that the search is valid

                if (limiter != null)
                {
                    limiter.Start();
                }
                BeginIterativeDeepeningSearch(initialState);

                result   = SearchResult.Failed; // assume that we couldn't complete a single iteration
                solution = new StateActionPair <StateType, ActionType>();

                // gradually increase the depth limit, starting from 1
                for (DepthLimit = 1; ; DepthLimit = DepthLimit == int.MaxValue ? Infinite : DepthLimit + 1)
                {
                    // start a new search with the given depth limit, and run it until it completes or the time expires
                    StateActionPair <StateType, ActionType> currentSolution;
                    SearchResult currentResult = PerformSearch(initialState, limiter, out currentSolution);

                    // Failed, in this case, means that the search couldn't complete because of the limiter, while LimitReached
                    // means that the search completed but was limited by the depth limit
                    if (currentResult == SearchResult.Failed)
                    {
                        break;
                    }

                    // the search completed, so store the result and solution
                    result   = currentResult;
                    solution = currentSolution;

                    // if the search was not limited by depth, increasing the depth won't help, so we're done
                    if (currentResult != SearchResult.LimitReached)
                    {
                        break;
                    }
                }
                EndIterativeDeepeningSearch();
            }

            DepthLimit = userDepthLimit; // restore the previous depth limit
            return(result);
        }
Exemple #5
0
        /// <include file="documentation.xml" path="/AI/Search/ISearch/Search_State/*"/>
        public override SearchResult Search(StateType initialState, SearchLimiter limiter, out Node <StateType, ActionType> solution)
        {
            if (limiter != null)
            {
                limiter.Start();
            }
            solution = new Node <StateType, ActionType>();

            float costLimit = Problem.GetHeuristic(initialState);

            while (true)
            {
                IQueue <Node <StateType, ActionType> > fringe = CreateQueue();
                Dictionary <StateType, Node <StateType, ActionType> > statesSeen =
                    EliminateDuplicateStates ? new Dictionary <StateType, Node <StateType, ActionType> >() : null;
                float newLimit      = float.PositiveInfinity;
                bool  depthLimitHit = false;

                fringe.Enqueue(MakeNode(initialState));

                while (fringe.Count != 0)
                {
                    if (limiter != null && limiter.LimitReached)
                    {
                        return(SearchResult.LimitReached);
                    }

                    Node <StateType, ActionType> node = fringe.Dequeue();
                    if (Problem.IsGoal(node.State))
                    {
                        solution = node;
                        return(SearchResult.Success);
                    }

                    float cost = node.PathCost + node.HeuristicCost;
                    if (cost <= costLimit)
                    {
                        depthLimitHit |= TryEnqueueNodes(fringe, node, statesSeen, false);
                    }
                    else if (cost < newLimit)
                    {
                        newLimit = cost;          // the new limit is the lowest of those that exceeded the old limit
                    }
                }

                if (float.IsInfinity(newLimit))
                {
                    return(depthLimitHit ? SearchResult.LimitReached : SearchResult.Failed);
                }
                costLimit = newLimit;
            }
        }
Exemple #6
0
        /// <include file="documentation.xml" path="/AI/Search/ISearch/Search_State/*"/>
        public sealed override SearchResult Search(StateType initialState, SearchLimiter limiter,
                                                   out StateActionPair <StateType, ActionType> solution)
        {
            PrepareToStartSearch(initialState);
            if (limiter != null)
            {
                limiter.Start();
            }
            // from PerformSearch(), Failed means that the limiter caused the search to abort, while LimitReached means that the
            // search completed, but was truncated by the depth limit. we'll convert Failed to LimitReached here.
            SearchResult result = PerformSearch(initialState, limiter, out solution);

            return(result == SearchResult.Failed ? SearchResult.LimitReached : result);
        }