Пример #1
0
        public override IEnumerable <T> Search(ISearchProblem <A, S, C> problem, S initialState)
        {
            // Save the old node expander
            var oldExpander = strategy.Expander;

            // Wrap the expander with a depth-limied expanded in order to
            // terminate the search
            var expander = new DepthLimitedNodeExpander <A, S, T, C>(oldExpander, limit);

            strategy.Expander = expander;

            // Run the search
            var solution = base.Search(problem, initialState);

            // Restore the old expander
            strategy.Expander = oldExpander;

            // Check to see we failed and if the reason for failing was not reaching the cutoff depth.
            if (!solution.Any() && expander.CutoffOccured)
            {
                return(null);
            }

            return(solution);
        }
Пример #2
0
        public BreadthFirst(ISearchProblem <TState, TAction> problem) : base(problem)
        {
            var root = new Node <TState, TAction>(Problem.Initial, Problem.InitialNode);

            _frontier = new Queue <Node <TState, TAction> >();
            _frontier.Enqueue(root);
        }
Пример #3
0
        public S FindState(ISearchProblem <S, A> problem)
        {
            _frontier.Clear();
            var node = _impl.FindNode(problem, _frontier);

            return(SearchUtils.ToState(node));
        }
Пример #4
0
        public IEnumerable <T> Expand(ISearchProblem <A, S, C> problem, T node)
        {
            var successors = problem.Successors(node.State);

            // Debug
            #if VERBOSE_DEBUG
            Console.WriteLine(String.Format("There are {0} successors for {1}", successors.Count(), node));
            Console.WriteLine(String.Format("This node has a current path cost of {0}", node.PathCost));
            #endif

            foreach (var successor in successors)
            {
                var action = successor.Item1;
                var state  = successor.Item2;
                var next   = CreateNode(node, state);

                next.Action    = action;
                next.StepCost  = problem.StepCost(node.State, action, state);
                next.Heuristic = problem.Heuristic(state);

                #if VERBOSE_DEBUG
                System.Diagnostics.Trace.WriteLine("   Action = " + next.Action + ", g(n') = " + next.PathCost + ", h(n') = " + next.Heuristic);
                #endif

                yield return(next);
            }
        }
Пример #5
0
        public IEnumerable <A> FindActions(ISearchProblem <S, A> problem)
        {
            _frontier.Clear();
            var node = _impl.FindNode(problem, _frontier);

            return(SearchUtils.ToActions(node));
        }
        public IEnumerable <T> Search(ISearchProblem <A, S, C> problem, S initialState)
        {
            C bound = Cost.Zero();

            while (bound.CompareTo(limit) < 0)
            {
                var limiter = new CostNodeLimiter <T, C>(bound, Cost.Maximum());
                var dls     = new DepthLimitedSearch <A, S, T, C>(search, limiter);
                var result  = dls.Search(problem, initialState);

                // If there was no cutoff, return the solution (or lack thereof)
                if (!dls.IsCutoff(result))
                {
                    return(result);
                }

                // If the cost did not change, throw exception
                if (bound.Equals(limiter.NextCost))
                {
                    throw new ApplicationException("IDA*: Bound did not increase after depth-limited search");
                }

                // Otherwise, increase the cutoff to the next value
                bound = limiter.NextCost;
            }

            // An empty list signals failure
            return(Enumerable.Empty <T>());
        }
Пример #7
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="problem"></param>
 /// <param name="heuristic">An estimate of the cost to reach the goal from the given state</param>
 public GreedyBestFirstSearch(ISearchProblem <TState, TAction> problem, Func <TState, int> heuristic) : base(problem)
 {
     _heuristic = heuristic;
     // todo: this should be in BestFirst Init function.. or something. have to call same frontier push
     //       in all subclasses
     Frontier.Push(new SearchNode <TState, TAction>(problem.InitialState, null, default(TAction), 0));
 }
Пример #8
0
        public SolutionSearchBase <TState, TAction> Search(
            ISearchProblem <TState, TAction> problem)
        {
            var rootNode = Node <TState, TAction> .Root(problem.InitialState);

            if (problem.GoalTest(rootNode.State))
            {
                return(new SolutionFound <TState, TAction>(rootNode));
            }

            var frontier = new BasicPriorityQueue <double, FrontierItem <TState, TAction> >(
                x => x.Evaluation);

            var explored = new HashSet <TState>(sComparer);

            frontier.Enqueue(new FrontierItem <TState, TAction>(rootNode,
                                                                EvaluationFuntion(problem, rootNode)));

            while (frontier.Count > 0)
            {
                var element = frontier.Dequeue();

                if (problem.GoalTest(element.Node.State))
                {
                    return(new SolutionFound <TState, TAction>(element.Node));
                }

                explored.Add(element.Node.State);

                var actions = problem.Actions(element.Node.State);

                foreach (var action in actions)
                {
                    var child = NodeExtensions.ChildNode(problem, element.Node, action);

                    var childElement = new FrontierItem <TState, TAction>(child,
                                                                          EvaluationFuntion(problem, child));

                    var comparedChild = frontier.CherryPeek(
                        x => sComparer.Equals(x.Node.State, childElement.Node.State));

                    bool stateInFrontier = comparedChild != default;

                    bool containsState = explored.Contains(child.State) || stateInFrontier;

                    if (!containsState)
                    {
                        frontier.Enqueue(childElement);
                    }
                    else if (stateInFrontier &&
                             comparedChild.Evaluation > childElement.Evaluation)
                    {
                        frontier.ReplaceWith(comparedChild, childElement);
                    }
                }
            }

            return(new SolutionFailure <TState, TAction>());
        }
Пример #9
0
        public UniformCost(ISearchProblem <TState, TAction> problem) : base(problem)
        {
            var root = new Node <TState, TAction>(Problem.Initial, Problem.InitialNode);

            _frontier = new List <Node <TState, TAction> > {
                root
            };
        }
Пример #10
0
        internal GenericSearch(ISearchProblem <TState, TAction> problem)
        {
            _problem     = problem;
            CurrentState = problem.InitialState;
            _explored    = new Dictionary <TState, SearchNode <TState, TAction> >();

            IsFinished = false;
        }
Пример #11
0
 protected override void AddNodes(IQueue <T> fringe, T node, ISearchProblem <A, S, C> problem)
 {
     if (!closed.Contains(node.State))
     {
         closed.Add(node.State);
         fringe.AddRange(Expander.Expand(problem, node));
     }
 }
Пример #12
0
        public IEnumerable <Node <TState, TAction> > Expand(ISearchProblem <TState, TAction> problem)
        {
            var actions = problem.Actions(State);

            foreach (var action in actions)
            {
                yield return(ChildNode(problem, action));
            }
        }
Пример #13
0
        public override IEnumerable <T> Expand(ISearchProblem <A, S, C> problem, T node)
        {
            if (limit.Cutoff(node))
            {
                cutoffOccured = true;
                return(Enumerable.Empty <T>());
            }

            return(base.Expand(problem, node));
        }
Пример #14
0
 public static Node <TState, TAction> ChildNode <TState, TAction>(
     ISearchProblem <TState, TAction> problem,
     Node <TState, TAction> parent,
     TAction action)
 {
     return(new Node <TState, TAction>(
                problem.Result(parent.State, action),
                parent,
                action,
                parent.PathCost + problem.StepCost(parent.State, action)));
 }
Пример #15
0
        public AStar(
            ISearchProblem <TState, TAction> problem,
            Func <string, string, double> heuristic) : base(problem)
        {
            _heuristic = heuristic;

            var root = new HeuristicNode <TState, TAction>(Problem.Initial, Problem.InitialNode);

            root.HeuristicPathCost = _heuristic(root.State.Name, Problem.Goal.Name);
            _frontier = new List <HeuristicNode <TState, TAction> > {
                root
            };
        }
Пример #16
0
        private Node <TState, TAction> ChildNode(ISearchProblem <TState, TAction> problem, TAction action)
        {
            var nextState = problem.Result(State, action);

            return(new Node <TState, TAction>(
                       nextState,
                       action,
                       this,
                       problem.PathCost(
                           PathCost, State, action, nextState
                           )
                       ));
        }
Пример #17
0
        public SolutionSearchBase <TState, TAction> Search(ISearchProblem <TState, TAction> problem)
        {
            for (int i = 0; i < int.MaxValue; i++)
            {
                var result = new DepthLimitedStrategy <TState, TAction>(i).Search(problem);

                if (result.GetType() != typeof(SolutionCutoff <TState, TAction>))
                {
                    return(result);
                }
            }

            return(new SolutionFailure <TState, TAction>());
        }
Пример #18
0
        public void SetUp()
        {
            // These objects define the abstract search problem
            var goalTest    = new EightPuzzleGoalTest(EightPuzzleBoard.GOAL);
            var stepCost    = new EightPuzzleStepCost();
            var successorFn = new EightPuzzleSuccessorFunction();
            var heuristic1  = new MisplacedHeuristic(EightPuzzleBoard.GOAL);
            var heuristic2  = new ManhattanHeuristic(EightPuzzleBoard.GOAL);

            // Create three search problem objects.  One without a heuristic and two with the different
            // heuristics
            problem_none = new SearchProblem <Direction, EightPuzzleBoard, IntegerCost>(goalTest, stepCost, successorFn);
            problem_h1   = new SearchProblem <Direction, EightPuzzleBoard, IntegerCost>(goalTest, stepCost, successorFn, heuristic1);
            problem_h2   = new SearchProblem <Direction, EightPuzzleBoard, IntegerCost>(goalTest, stepCost, successorFn, heuristic2);
        }
        public IEnumerable <T> Search(ISearchProblem <A, S, C> problem, S initialState)
        {
            for (int depth = 1; depth <= limit; depth++)
            {
                var dls    = new DepthLimitedSearch <A, S, T, C>(search, new DepthNodeLimiter <T, C>(depth));
                var result = dls.Search(problem, initialState);

                if (!dls.IsCutoff(result))
                {
                    return(result);
                }
            }

            return(Enumerable.Empty <T>());
        }
Пример #20
0
        public SolutionSearchBase <TState, TAction> Search(ISearchProblem <TState, TAction> problem)
        {
            var rootNode = Node <TState, TAction> .Root(problem.InitialState);

            if (problem.GoalTest(rootNode.State))
            {
                return(new SolutionFound <TState, TAction>(rootNode));
            }


            var frontier = new Stack <Node <TState, TAction> >();

            var explored = new HashSet <TState>(sComparer);

            frontier.Push(rootNode);

            while (frontier.Count > 0)
            {
                var node = frontier.Pop();

                explored.Add(node.State);

                var actions = problem.Actions(node.State);

                foreach (var action in actions)
                {
                    var child = NodeExtensions.ChildNode(problem, node, action);

                    bool containsState = explored.Contains(child.State) ||
                                         frontier.Contains(child, nComparer);

                    if (!containsState)
                    {
                        if (problem.GoalTest(child.State))
                        {
                            return(new SolutionFound <TState, TAction>(child));
                        }

                        frontier.Push(child);
                    }
                }
            }

            return(new SolutionFailure <TState, TAction>());
        }
Пример #21
0
        public IEnumerable <T> FindPath <T>(ISearchProblem <T> problem)
        {
            var frontier     = new CustomPriorityQueue <SearchNode <T> >();
            var predecessors = new Dictionary <T, T>();
            var costs        = new Dictionary <T, float>();

            var initialNode = new SearchNode <T>(problem.InitialState, 0);

            frontier.Enqueue(initialNode);

            predecessors[problem.InitialState] = default;
            costs[problem.InitialState]        = 0;

            while (frontier.Any())
            {
                var node = frontier.Dequeue();

                if (problem.IsGoalState(node.State))
                {
                    return(Path.Build(problem.InitialState, node.State, predecessors));
                }

                var successors = problem.GetSuccessors(node.State);
                foreach (var successor in successors)
                {
                    var newCost = costs[node.State] + successor.Cost;
                    if (costs.TryGetValue(successor.State, out var cost) && cost < newCost)
                    {
                        continue;
                    }

                    costs[successor.State]        = newCost;
                    predecessors[successor.State] = node.State;

                    var heuristic = problem.CalculateHeuristic(successor.State);
                    var priority  = newCost + heuristic;

                    var successorNode = new SearchNode <T>(successor.State, priority);
                    frontier.Enqueue(successorNode);
                }
            }

            return(null);
        }
Пример #22
0
        public override Node <S, A> FindNode(ISearchProblem <S, A> problem, InOutCollection <Node <S, A> > frontier)
        {
            _bytes = GC.GetTotalMemory(true);

            var startTime = Stopwatch.StartNew();

            startTime.Start();

            Frontier = frontier;

            var root = NodeFactory.CreateNode <S, A>(problem.InitState);

            AddToFrontier(root);

            long maxMemory = _bytes;

            while (!IsFrontierEmpty())
            {
                maxMemory = Math.Max(maxMemory, GC.GetTotalMemory(false));

                _count++;
                var node = RemoveFromFrontier();

                if (problem.GoalTest(node.State))
                {
                    startTime.Stop();
                    _times  = startTime.Elapsed;
                    _bytes -= maxMemory;
                    return(node);
                }

                foreach (var successor in NodeFactory.GetSuccessors(node, problem))
                {
                    AddToFrontier(successor);
                }
            }

            _bytes -= maxMemory;
            startTime.Stop();
            _times = startTime.Elapsed;

            return(null);
        }
Пример #23
0
        private SolutionSearchBase <TState, TAction> RecursiveDLS(
            Node <TState, TAction> node, ISearchProblem <TState, TAction> problem, int limit)
        {
            if (problem.GoalTest(node.State))
            {
                return(new SolutionFound <TState, TAction>(node));
            }
            else if (limit == 0)
            {
                return(new SolutionCutoff <TState, TAction>());
            }
            else
            {
                var cutoffOccurred = false;

                var actions = problem.Actions(node.State);

                foreach (var action in actions)
                {
                    var child = NodeExtensions.ChildNode(problem, node, action);

                    var result = RecursiveDLS(child, problem, limit - 1);

                    if (result.GetType() == typeof(SolutionCutoff <TState, TAction>))
                    {
                        cutoffOccurred = true;
                    }
                    else if (result.GetType() != typeof(SolutionFailure <TState, TAction>))
                    {
                        return(result);
                    }
                }

                if (cutoffOccurred)
                {
                    return(new SolutionCutoff <TState, TAction>());
                }
                else
                {
                    return(new SolutionFailure <TState, TAction>());
                }
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="problem"></param>
        /// <param name="fringe">Must be initialized -- usually that means being empty</param>
        /// <param name="initialState"></param>
        /// <returns></returns>
        public virtual IEnumerable <T> Search(ISearchProblem <A, S, C> problem, IQueue <T> fringe, S initialState)
        {
            // Add the initial state to the fringe
            fringe.Enqueue(Expander.CreateNode(initialState));

            // Search until success, or the search space is exhausted
            while (!fringe.Empty)
            {
                var node = fringe.Remove();

                if (problem.IsGoal(node.State))
                {
                    return(Solution(node));
                }

                AddNodes(fringe, node, problem);
            }

            return(Enumerable.Empty <T>());
        }
Пример #25
0
        public IEnumerable <T> FindPath <T>(ISearchProblem <T> problem)
        {
            var frontier  = new CustomPriorityQueue <SearchNode <T> >();
            var cameFrom  = new Dictionary <T, T>();
            var costSoFar = new Dictionary <T, float>();

            var firstNode = new SearchNode <T>(problem.InitialState, 0);

            frontier.Enqueue(firstNode);
            cameFrom[problem.InitialState]  = default;
            costSoFar[problem.InitialState] = 0;

            while (frontier.Any())
            {
                var node = frontier.Dequeue();

                if (problem.IsGoalState(node.State))
                {
                    return(Path.Build(problem.InitialState, node.State, cameFrom));
                }

                var successors = problem.GetSuccessors(node.State);
                foreach (var successor in successors)
                {
                    var newCost = costSoFar[node.State] + successor.Cost;

                    if (costSoFar.TryGetValue(successor.State, out var cost) && newCost >= cost)
                    {
                        continue;
                    }

                    var action = new SearchNode <T>(successor.State, newCost);
                    frontier.Enqueue(action);

                    costSoFar[successor.State] = newCost;
                    cameFrom[successor.State]  = node.State;
                }
            }

            return(null);
        }
Пример #26
0
        public LabyrinthScene(ISearchProblem <S, A> problem, ISearchForActions <S, A> search, IMetrics metrics)
        {
            Utils.GameUtils.OgmoProject.LoadLevelFromFile("level.oel", this);

            var skovoroda = new Skovoroda(40 * 17, 40 * 14);
            var world     = new World(40, 40);

            Add(skovoroda);
            Add(world);

            var actions = search.FindActions(problem);

            var actionsTask = Task.Run(async() =>
            {
                foreach (A a in actions)
                {
                    var action = a as MoveAction;
                    world.X   += action.Action switch
                    {
                        MoveActionEnum.Up => 0,
                        MoveActionEnum.Down => 0,
                        MoveActionEnum.Left => - 40,
                        MoveActionEnum.Right => 40,
                        _ => 0
                    };

                    world.Y += action.Action switch
                    {
                        MoveActionEnum.Up => - 40,
                        MoveActionEnum.Down => 40,
                        MoveActionEnum.Left => 0,
                        MoveActionEnum.Right => 0,
                        _ => 0
                    };

                    await Task.Delay(20);
                }
            });

            actionsTask.ContinueWith(t => Game.SwitchScene(new MetricsScene(actions.Count(), metrics)));
        }
Пример #27
0
        public IEnumerable <T> FindPath <T>(ISearchProblem <T> problem)
        {
            var frontier = new CustomPriorityQueue <SearchNode <T> >();
            var cameFrom = new Dictionary <T, T>();

            var initialNode = new SearchNode <T>(problem.InitialState, 0);

            frontier.Enqueue(initialNode);
            cameFrom[problem.InitialState] = default;

            while (frontier.Any())
            {
                var node = frontier.Dequeue();

                if (problem.IsGoalState(node.State))
                {
                    return(Path.Build(problem.InitialState, node.State, cameFrom));
                }

                var successors = problem.GetSuccessors(node.State);
                foreach (var successor in successors)
                {
                    if (cameFrom.ContainsKey(successor.State))
                    {
                        continue;
                    }

                    var priority      = problem.CalculateHeuristic(successor.State);
                    var successorNode = new SearchNode <T>(successor.State, priority);

                    frontier.Enqueue(successorNode);
                    cameFrom[successor.State] = node.State;
                }
            }

            return(null);
        }
Пример #28
0
        public IEnumerable <T> FindPath <T>(ISearchProblem <T> problem)
        {
            // Setup data-structures.
            var frontier = new Queue <T>();
            var cameFrom = new Dictionary <T, T>();

            // Add initial state.
            frontier.Enqueue(problem.InitialState);
            cameFrom[problem.InitialState] = default;

            while (frontier.Any())
            {
                var state = frontier.Dequeue();

                // Goal test.
                if (problem.IsGoalState(state))
                {
                    return(Path.Build(problem.InitialState, state, cameFrom).Reverse());
                }

                // Add new successors.
                var successors = problem.GetSuccessors(state);
                foreach (var successor in successors)
                {
                    if (cameFrom.ContainsKey(successor.State))
                    {
                        continue;
                    }

                    cameFrom[successor.State] = successor.State;
                    frontier.Enqueue(successor.State);
                }
            }

            return(null);
        }
 public override System.Collections.Generic.IEnumerable <T> Search(ISearchProblem <A, S, C> problem, IQueue <T> fringe, S initialState)
 {
     RBFS(Expander.CreateNode(initialState), Cost.Zero(), Cost.Maximum());
 }
 /// <summary>
 /// When it's time to actually expand a node and add the new states to the fringe, different
 /// algorithms can make different choices
 /// </summary>
 /// <param name="fringe"></param>
 /// <param name="node"></param>
 /// <param name="problem"></param>
 protected abstract void AddNodes(IQueue <T> fringe, T node, ISearchProblem <A, S, C> problem);