/// <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); }
/// <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)); }
/// <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)); }
/// <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); }
/// <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; } }
/// <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); }