private C RBFS(T node, C F_N, C bound)
        {
            var f_N = problem.Heuristic(node.State);

            if (f_N.CompareTo(bound) > 0)
            {
                return(f_N);
            }

            if (problem.IsGoal(node.State))
            {
                throw new Exception();
            }

            var children = Expander.Expand(problem, node);

            if (!children.Any())
            {
                return(Cost.Maximum());
            }

            foreach (var N_i in children)
            {
                if (f_N.CompareTo(F_N) < 0)
                {
                    N_i.F = F_N.Max(N_i.EstCost);
                }
                else
                {
                    N_i.F = N_i.EstCost;
                }
            }

            children = children.OrderBy(x => x.F);


            /*
             * RBFS (node: N, value: F(N), bound: B)
             * IF f(N)>B, RETURN f(N)
             * IF N is a goal, EXIT algorithm
             * IF N has no children, RETURN infinity
             * FOR each child Ni of N,
             *  IF f(N)<F(N), F[i] := MAX(F(N),f(Ni))
             *  ELSE F[i] := f(Ni)
             * sort Ni and F[i] in increasing order of F[i]
             * IF only one child, F[2] := infinity
             * WHILE (F[1] <= B and F[1] < infinity)
             *  F[1] := RBFS(N1, F[1], MIN(B, F[2]))
             *  insert Ni and F[1] in sorted order
             * RETURN F[1]
             */
        }
Beispiel #2
0
        public void Step()
        {
            if (IsFinished)
            {
                return;
            }

            SearchNode <TState, TAction> node;

            do
            {
                if (Frontier.IsEmpty())
                {
                    IsFinished = true;
                    return;
                }
                node = Frontier.Pop();
            } while (_explored.ContainsKey(node.State));

            _explored[node.State] = node;
            CurrentState          = node.State;
            var actions = _problem.GetActions(node.State);

            foreach (var action in actions)
            {
                var childState = _problem.DoAction(node.State, action);
                var childCost  = node.PathCost + _problem.PathCost(node.State, action);
                var child      = new SearchNode <TState, TAction>(childState, node, action, childCost);

                if (_explored.ContainsKey(childState) || Frontier.ContainsState(childState))
                {
                    continue;
                }

                if (_problem.IsGoal(childState))
                {
                    CurrentState = childState;
                    IsFinished   = true;
                    IsSolved     = true;
                    // add goal to explored to allow this.getSolutionTo(goal)
                    _explored[childState] = child;
                }
                else
                {
                    Frontier.Push(child);
                }
            }
        }
        /// <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>());
        }