/// <summary>Finishes a potentially-limited search. To be called by a <see cref="Search"/> method after /// <see cref="BeginSearch"/>. This method calls <see cref="Iterate"/> repeatedly until the search completes or the /// limit expires (if a limit was given), and then returns the result. /// </summary> SearchResult FinishLimitedSearch(SearchLimiter limiter, Func<ContextType> contextMaker, out SolutionType solution) { TaskCancellationEvent foundEvent = new TaskCancellationEvent(); int parallelism = UseAutomaticParallelism ? GetEffectiveParallelism() : 1; KeyValuePair<ContextType,SearchResult>[] results = Tasks.Parallelize(task => { ContextType context = contextMaker(); SearchResult result = SearchResult.Pending; while(result == SearchResult.Pending && !task.WasCanceled && (limiter == null || limiter.LimitReached)) { result = Iterate(context); } if(result == SearchResult.Success) foundEvent.Cancel(); // stop the other threads if we've found a solution return new KeyValuePair<ContextType,SearchResult>( context, result == SearchResult.Pending ? SearchResult.LimitReached : result); }, parallelism, foundEvent); // find the best result type SearchResult bestResult = SearchResult.Failed; foreach(var result in results) { if(result.Value != SearchResult.Failed) { bestResult = result.Value; if(bestResult == SearchResult.Success) break; } } // find the best solution among those having the best result type solution = SelectBestSolution((from r in results where r.Value == bestResult select r.Key).ToArray()); return bestResult; }
/// <include file="documentation.xml" path="/AI/Search/ISearch/Search_State/*"/> public override SearchResult Search(StateType initialState, SearchLimiter limiter, out SolutionType solution) { return FinishLimitedSearch(limiter, () => BeginSearch(initialState), out solution); }
/// <include file="documentation.xml" path="/AI/Search/ISearch/Search/*"/> public override SearchResult Search(SearchLimiter limiter, out SolutionType solution) { return FinishLimitedSearch(limiter, () => BeginSearch(), out solution); }