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] */ }
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>()); }