Problem Solving: Uninformed Search References ● ● Russell and Norvig, Artificial Intelligence: A modern approach, 2nd ed. Prentice Hall, 2003 (chapter 3) Nilsson, Artificial intelligence: A New synthesis. McGraw Hill, 2001 Outline Basic uninformed-search algorithms Breadth-first search Uniform-cost search Depth-first search Depth limited search Iterative deepening Bidirectional search More on uninformed search Avoiding repeated states Uninformed (Blind) Search or “blind” uninformed non-adversary search informed adversary or “heuristic” Uninformed (Blind) Search Uninformed --or blind-- search strategies use only the information available in the problem definition Recall that blind search assumes that f(x) ≡ g(x) Uninformed search Breadth-first search Uniform-cost search Depth-first search Depth-limited search Iterative deepening Bidirectional search Breadth-first search Idea: explore the search space “horizontally”, i.e. expanding all nodes at level k before taking into account nodes at level k+1 Breadth-first search Implementation: The intended behavior can be ensured by using a LIFO policy for storing expanded nodes defun BREADTH-FIRST-SEARCH(problem) returns solution return TREE-SEARCH ( problem, queue ) Breadth-first search Node expansion: Expand the shallowest unexpanded node Implementation: fringe is a FIFO queue, i.e. new successors go at end Breadth-first search: properties Completeness: Yes, it is complete (if b is finite) Time complexity: O(bd) exponential in d (depth of least cost solution) Space complexity: O(bd) (keeps every node in memory) Optimality: NOT optimal in general It is optimal only if the actual cost of any step is 1 Breadth-first search: properties Space is the major problem: at a rate of 10.000 nodes/sec (easy), with 10KB/node, generates 860GB in 24 hrs If b=10, d=10 it needs 1011 nodes = 129 days Uninformed search Breadth-first search Uniform-cost search Depth-first search Depth-limited search Iterative deepening Bidirectional search Uniform-cost search Idea: explore the search space according to the cost g(x) spent to get the node x Note that breath-first search is a special case of uniform-cost search in which g(x) = DEPTH(x) Uniform-cost search Implementation: The intended behavior can be ensured by using an ordered queue in which nodes are inserted according to the function f(x) = g(x) defun UNIFORM-COST-SEARCH(problem) returns solution return TREE-SEARCH ( problem, ordered-queue ) Uniform-cost search Node expansion: Expands least-cost unexpanded node Implementation: Fringe is a queue ordered by path cost Completeness: Yes, it is complete, provided that –at each step– the corresponding cost is ≥ ε Optimality: Yes, it is optimal Nodes are expanded in increasing order of g(n) Uninformed search Breadth-first search Uniform-cost search Depth-first search Depth-limited search Iterative deepening Bidirectional search Depth-first search Idea: explore the search space “vertically” according to a “left-to-right” ordering Depth-first search Implementation: The intended behavior can be ensured by using a FIFO policy while storing expanded nodes defun DEPTH-FIRST-SEARCH(problem) returns solution return TREE-SEARCH ( problem, stack ) Depth-first search Node expansion: Expands the deepest unexpanded node Implementation: Fringe is a LIFO queue (i.e. a stack), put successors at front Depth-first search - continued Depth-first search: properties Completeness: No, in general it is NOT complete (it fails in infinite-depth spaces --e.g., spaces with state loops) It is complete in finite spaces, provided that it is able to avoid repeated states along paths Time complexity: O(bm): terrible if m is much greater than d On the other hand, if solutions are dense, it may be much faster than breadth-first Space complexity: O(bm) --- i.e. linear (great!) Optimality: NOT optimal Uninformed search Breadth-first search Uniform-cost search Depth-first search Depth-limited search Iterative deepening Bidirectional search Depth-limited search Idea: avoid the pitfalls of depth-first search by imposing a cutoff on the maximum depth of a path Depth-limited search Implementation: perform a depth-first search on the part of the search tree that fulfills the constraint imposed by the given limit There are three possible outcomes: The GOAL-TEST? function succeeded somewhere within the part of the search tree that has been explored (i.e. a solution has been found) The imposed limit has been reached somewhere, meaning that a solution might still be found although NOT within the given limit (see the pseudo-code: *CUTOFF*) A failure occurred, meaning that no solution can be found, even if the limit constraint is relaxed (see the pseudocode: *FAILURE*) DLS: an implementation Depth-limited search defun DEPTH-LIMITED-SEARCH (problem, limit) returns solution node ← MAKE-NODE(INITIAL-STATE(problem)) return RECURSIVE-DLS(problem, node, limit) defun RECURSIVE-DLS (problem, node, limit) returns solution cutoff? : boolean --- flag used to remember whether cutoff occurred if problem.GOAL-TEST?(STATE(node)) then return SOLUTION(node) if DEPTH(node) = limit then return *CUTOFF* cutoff? ← false for each succ in problem.EXPAND(node) do result ← RECURSIVE-DLS(problem, succ, limit) if result = *CUTOFF* then cutoff? ← true else if result <> *FAILURE* then return result if cutoff? then return *CUTOFF* else return *FAILURE* Uninformed search Breadth-first search Uniform-cost search Depth-first search Depth-limited search Iterative deepening Bidirectional search Iterative deepening search Idea: iteratively perform depth-limited searches with incremental cutoffs, until a goal state is found Iterative deepening search Implementation: repeatedly calls a DLS algorithm, with different (i.e., increasing) depth limits IDS: an implementation Iterative deepening search defun ITERATIVE-DEEPENING-SEARCH (problem) returns solution limit ← 0 loop do --- the loop may not terminate ... result ← DEPTH-LIMITED-SEARCH(problem,limit) if result <> *CUTOFF* then return result limit ← limit + 1 Iterative deepening search Iterative deepening search Iterative deepening search Iterative deepening search Iterative deepening search Completeness: Yes, it is complete Time complexity: (d+1)⋅ b0 + d⋅ b1 + (d-1)⋅ b2 + … + bd = O(bd) Space complexity: O(b⋅ d) Optimality: NOT optimal in general It is optimal only if the actual step cost is 1 It can be adapted to use uniform cost; in this case the algorithm is optimal! Iterative deepening search Numerical comparison for b=10 and d=5, with solution at the far right end of the search tree: N(IDS) = 50 + 400 + 3,000 + 20,000 + 100,000 = 123,450 N(BFS) = 10 + 100 + 1,000 + 10,000 + 100,000 + 999,990 = 1,111,100 DLS: an implementation Summary (uninformed search) Problem formulation usually demands abstracting away real-world details in order to define a state space that can feasibly be explored. There is a variety of uninformed (blind) search strategies Iterative deepening search grants an optimal solution (in the version adapted to use uniform cost) with a reasonable amount of time and space Bidirectional search Breadth-first search Uniform-cost search Depth-first search Depth-limited search Iterative deepening Bidirectional search Bidirectional search Idea: save time by searching from both the initial state (forward) and the final state (backward) Bidirectional search Stop when both searches meet bd/2+ bd/2 << bd To avoid repetitions, one search (or both) must check –for each node to be expanded– whether the corresponding state is in the fringe of the other tree Bidirectional search Space complexity: O(bd/2), because at least one of the trees must be kept in memory Difficulties: Can we compute “predecessor(n)” efficiently? What is the initial state for backward search if the overall goal is defined by a goal condition (e.g.. “checkmate”)? More on Uninformed Search Repeated states Failure to detect repeated states can turn a linear problem into an exponential one! Dealing with repeated states Introduce a CLOSED list that stores every expanded node If the current node is in the CLOSED list, discard it instead of expanding it Keeping each node in memory increases space complexity The fringe of unexpanded nodes is frequently called the OPEN list Tree Search with OPEN-CLOSED lists defun GRAPH-SEARCH (problem, fringe) returns solution closed ← {} --- a set of CLOSED nodes (actually states), initially empty fringe.insert(MAKE-NODE(problem.initial-state)) while not ISEMPTY?(fringe) do node ← fringe.remove() if problem.GOAL-TEST?(STATE(node)) then return SOLUTION(node) if not closed.member(STATE(node)) then closed.add(STATE(node)) children ← problem.EXPAND(node) for each child in children do fringe.insert(child) return *FAILURE*
© Copyright 2024 Paperzz