def uniform_cost_search(start): cost_to_get_to_node = {} frontier = PriorityQueue() // Higher Priority equals Lower Cost expanded_nodes = Set() cost_to_get_to_node[start] = 0 frontier.push((start, 0)) expanded_nodes.add(start) while front.has_elements(): u = frontier.pop() if is_goal(u): return path(u) for v in u.successors: if v not in expanded_nodes: if v in frontier: # if we already have it in the frontier, but we found a cheaper way to get there, update the cost to get here. cost_to_get_to_node[v] = min(cost_to_get_to_node[v], cost_to_get_to_node[u] + u.action_cost(v)) else: frontier.push(v) cost_to_get_to_node[v] = cost_to_get_to_node[u] + u.action_cost(v)) return Failure
In general UCS is not complete, because given an infinite number of zero-weight edges deviating away from the goal state, then UCS will follow this path forever and never find the goal. On the other hand, if there exists some such that every edge has at least this weight, then UCS will find the minimum cost solution, this is because it explores nodes in the search space in non-decreasing order of cost so it must find a minimum cost path to a goal before finding any higher cost paths leading to a goal.