CSCE 420 Lecture 4

From Notes
Jump to navigation Jump to search

« previous | Thursday, January 24, 2013 | next »


Review of BFS and DFS

For a tree with branching factor , max height , and a solution at worst-case position at depth

Table 3.21
  BFS DFS UC ID
Time
Space
Completeness [1] yes no yes [2] yes
Optimality [3] yes [4] no yes yes [4]

Uniform Cost Algorithm

Same basic algorithm as BFS, but use a Priority Queue data structure instead.

Explores nodes in search space in order of increasing cost.

def graph_search algorithm, problem
  node = make_node initial_state
  frontier = case algorithm
    when :bfs then Queue[node]
    when :dfs then Stack[node]
    then :uniform_cost then PriorityQueue[node] {|node| node.path_cost}
  end

  loop do
    return false if frontier.empty?
    node = frontier.remove
    return child if problem == :uniform_cost
    action.each do |a|
      child = a.target
      return child if problem in [:bfs, :dfs] and goal_test child
      frontier.add child
    end
  end
end

This algorithm implies positive edge costs , the smallest of which is

Complexity

Suppose optimal goal has cost . How many other nodes do we have to search before we arrive at a goal node?

Both time and space complexity:

Correctness

proof by contradiction. Suppose UC finds a suboptimal goal such that there exists a better node : .

has a parent such that .

By the graph separation property, there must have been some node on the path from the root to such that . In that case, would have been pulled before . Contradiction.

Q.E.D.


Graph Separation Property

in graph search, frontier separates the visited/explored part of search space from the unvisited/unexplored space. Therefore, for any node , there is always some node in the frontier that is on the path from the root node to . Each of these nodes have the property .


Iterative Deepening

To obtain space complexity of DFS without the threat of infinite depth searchi, we could implement a depth-limited search (DLS) that caps the maximum search depth:

def depth_limited_search init, oper, goal_test, limit
  frontier = Stack[init]
  until frontier.empty?
    node = frontier.pop
    return child if goal_test node
    oper(node).each {|child| frontier.push child} if depth(node) < limit
  end
  false
end

Iterative deepening algorithm is a wrapper for depth_limited_search:

 def iterative_deepening init, oper, goal_test
  limit = 0
  loop do
    result = depth_limited_search init, oper, goal_test, limit
    return result if result
    limit += 1
  end
end

Footnotes

  1. Optimality: Will search find a goal if it exists?
  2. Provided that all operator costs are positive
  3. Optimality: Does search find best goal?
  4. 4.0 4.1 Provided that all operators have uniform/equal cost