示例#1
0
        /// <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));
        }
示例#2
0
        private Task <SearchResult> Evaluate(IDeterministicState startState, SearchContext searchContext,
                                             IDictionary <IState, double> storedStates, IState state)
        {
            var taskResult = storedStates != null && storedStates.ContainsKey(state)
                ? Task.FromResult(new SearchResult(storedStates[state], state))
                : threadManager.Invoke(() =>
            {
                var actualStartState = startState is ProbablisticStateWrapper wrapper
                        ? (IState)wrapper.InnerState
                        : startState;
                return(searchWorker.Evaluate(state, searchContext.CloneAndAddState(actualStartState)));
            }, searchContext.CurrentDepth);

            return(taskResult);
        }