// function HILL-CLIMBING(problem) returns a state that is a local maximum public IList <IAction> Search(Problem p) { ClearInstrumentation(); outcome = SearchOutcome.Failure; lastState = null; // current <- MAKE-NODE(problem.INITIAL-STATE) Node current = new Node(p.InitialState); Node neighbor = null; // loop do while (!CancelableThread.CurrIsCanceled()) { IList <Node> children = ExpandNode(current, p); // neighbor <- a highest-valued successor of current neighbor = this.GetHighestValuedNodeFrom(children, p); // if neighbor.VALUE <= current.VALUE then return current.STATE if ((neighbor == null) || (this.GetValue(neighbor) <= this.GetValue(current))) { if (SearchUtils.IsGoalState(p, current)) { outcome = SearchOutcome.SolutionFound; } lastState = current.State; return(SearchUtils.ActionsFromNodes(current.GetPathFromRoot())); } // current <- neighbor current = neighbor; } return(new List <IAction>()); }
// function RECURSIVE-DLS(node, problem, limit) returns a solution, or // failure/cutoff private IList <IAction> RecursiveDls(Node node, Problem problem, int limit) { // if problem.GOAL-TEST(node.STATE) then return SOLUTION(node) if (SearchUtils.IsGoalState(problem, node)) { this.SetPathCost(node.PathCost); return(SearchUtils.ActionsFromNodes(node.GetPathFromRoot())); } else if (0 == limit) { // else if limit = 0 then return cutoff return(this.Cutoff()); } else { // else // cutoff_occurred? <- false bool cutoffOccurred = false; // for each action in problem.ACTIONS(node.STATE) do foreach (Node child in this.ExpandNode(node, problem)) { // child <- CHILD-NODE(problem, node, action) // result <- RECURSIVE-DLS(child, problem, limit - 1) IList <IAction> result = this.RecursiveDls(child, problem, limit - 1); // if result = cutoff then cutoff_occurred? <- true if (this.IsCutOff(result)) { cutoffOccurred = true; } else if (!this.IsFailure(result)) { // else if result != failure then return result return(result); } } // if cutoff_occurred? then return cutoff else return failure if (cutoffOccurred) { return(this.Cutoff()); } else { return(this.Failure()); } } }
// function SIMULATED-ANNEALING(problem, schedule) returns a solution state public IList <IAction> Search(Problem p) { ClearInstrumentation(); outcome = SearchOutcome.Failure; lastState = null; // current <- MAKE-NODE(problem.INITIAL-STATE) Node current = new Node(p.InitialState); Node next = null; IList <IAction> ret = new List <IAction>(); // for t = 1 to INFINITY do int timeStep = 0; while (!CancelableThread.CurrIsCanceled()) { // temperature <- schedule(t) double temperature = scheduler.GetTemp(timeStep); timeStep++; // if temperature = 0 then return current if (temperature == 0.0) { if (SearchUtils.IsGoalState(p, current)) { outcome = SearchOutcome.SolutionFound; } ret = SearchUtils.ActionsFromNodes(current.GetPathFromRoot()); lastState = current.State; break; } IList <Node> children = ExpandNode(current, p); if (children.Count > 0) { // next <- a randomly selected successor of current next = Util.SelectRandomlyFromList(children); // /\E <- next.VALUE - current.value double deltaE = this.GetValue(p, next) - this.GetValue(p, current); if (this.ShouldAccept(temperature, deltaE)) { current = next; } } } return(ret); }
// function RECURSIVE-BEST-FIRST-SEARCH(problem) returns a solution, or // failure public IList <IAction> Search(Problem p) { IList <IAction> actions = new List <IAction>(); ClearInstrumentation(); // RBFS(problem, MAKE-NODE(INITIAL-STATE[problem]), infinity) Node n = new Node(p.InitialState); SearchResult sr = this.Rbfs(p, n, evaluationFunction.F(n), Infinity, 0); if (sr.GetOutcome() == SearchResult.SearchOutcome.SolutionFound) { Node s = sr.GetSolution(); actions = SearchUtils.ActionsFromNodes(s.GetPathFromRoot()); this.SetPathCost(s.PathCost); } // Empty IList can indicate already at Goal // or unable to find valid Set of actions return(actions); }
private IList <IAction> RetrieveActions(Problem op, Problem rp, Node originalPath, Node reversePath) { IList <IAction> actions = new List <IAction>(); if (null == reversePath) { // This is the simple case whereby the path has been found // from the original problem first this.SetPathCost(originalPath.PathCost); searchOutcome = SearchOutcome.PathFoundFromOriginalProblem; actions = SearchUtils.ActionsFromNodes(originalPath.GetPathFromRoot()); } else { var nodePath = new List <Node>(); object originalState = null; if (null != originalPath) { nodePath.AddRange(originalPath.GetPathFromRoot()); originalState = originalPath.State; } // Only append the reverse path if it is not the // GOAL state from the original problem (if you don't // you could end up appending a partial reverse path // that looks back on its initial state) if (!SearchUtils.IsGoalState(op, reversePath)) { IList <Node> rpath = reversePath.GetPathFromRoot(); for (int i = rpath.Count - 1; i >= 0; i--) { // Ensure do not include the node from the reverse path // that is the one that potentially overlaps with the // original path (i.e. if started in goal state or where // they meet in the middle). if (!rpath[i].State.Equals(originalState)) { nodePath.Add(rpath[i]); } } } if (!canTraversePathFromOriginalProblem(op, nodePath, actions)) { // This is where it is possible to get to the initial state // from the goal state (i.e. reverse path) but not the other way // round, null returned to indicate an invalid path found from // the reverse problem return(null); } if (null == originalPath) { searchOutcome = SearchOutcome.PathFoundFromReverseProblem; } else { // Need to ensure that where the original and reverse paths // overlap, as they can link based on their fringes, that // the reverse path is actually capable of connecting to // the previous node in the original path (if not root). if (this.CanConnectToOriginalFromReverse(rp, originalPath, reversePath)) { searchOutcome = SearchOutcome.PathFoundBetweenProblems; } else { searchOutcome = SearchOutcome.PathFoundFromOriginalProblem; } } } return(actions); }