/// <summary>
        /// Runs a search.
        /// </summary>
        /// <param name="startState">The state that the search will start from</param>
        /// <param name="maxDepth">The search will be terminated after maxDepth</param>
        /// <param name="cancellationToken">Used to cancel the search</param>
        public SearchResult Search(IDeterministicState startState, int maxDepth, CancellationToken cancellationToken)
        {
            if (StateDefinesDepth && CacheMode != CacheMode.NoCache && CacheKeyType != CacheKeyType.StateOnly)
            {
                throw new MinMaxSearchException($"If {nameof(StateDefinesDepth)} the cache key should be of type {CacheKeyType.StateOnly}");
            }

            if (!startState.GetNeighbors().Any())
            {
                throw new NoNeighborsException("start state has no neighbors " + startState);
            }

            if (maxDepth < 1)
            {
                throw new ArgumentException($"{nameof(maxDepth)} must be at least 1. Was {maxDepth}");
            }

            if (SkipEvaluationForFirstNodeSingleNeighbor && startState.GetNeighbors().Count() == 1)
            {
                return(new SearchResult(0, startState, true, true, false));
            }

            var searchContext = new SearchContext(maxDepth, 0, cancellationToken);
            var searchWorker  = new SearchWorker(CreateSearchOptions(), GetThreadManager(maxDepth), cacheManagerFactory());
            var stopwatch     = new Stopwatch();

            stopwatch.Start();
            var result = searchWorker.Evaluate(startState, searchContext);

            stopwatch.Stop();
            result.StateSequence.Reverse();
            result.StateSequence.RemoveAt(0); // Removing the top node will make the result "nicer"
            return(new SearchResult(result, stopwatch.Elapsed, maxDepth, !cancellationToken.IsCancellationRequested));
        }
Example #2
0
 public DeterministicSearchUtils(SearchWorker searchWorker, SearchOptions searchOptions, IThreadManager threadManager)
 {
     this.searchWorker  = searchWorker;
     this.searchOptions = searchOptions;
     this.threadManager = threadManager;
 }