def r_ids(problem, stype, opt=False, avd=False): """ Iterative deepening depth-first search :param avd: :param opt: :param problem: problem :param stype: type of search: graph or tree (dls_gs or dls_ts) :return: (path, stats): solution as a path and stats The stats are a tuple of (time, npexp, max_depth): elapsed time, number of expansions, max depth reached """ t, depth, stats, cutoff = timer(), 0, [0, 0, 0, 0], True graph = dot_init(problem) while cutoff: path, temp_stats, node, cutoff = stype(problem, opt=opt, avd=avd, limit=depth) temp_graph = close_dot(temp_stats[1], node, sub=True) depth += 1 graph += temp_graph stats[:-1] = [x + y for x, y in zip(stats[:-1], temp_stats[:-1])] stats[-1] = max(stats[-1], temp_stats[-1]) if path is not None or not cutoff: graph = close_dot(stats[0], node, graph) return path, (timer() - t, stats[1], gen(), stats[2]), graph
def astar(problem, stype, opt=False, avd=False): """ A* best-first search :param avd: :param opt: :param problem: problem :param stype: type of search: graph or tree (graph_search or tree_search) :return: (path, stats): solution as a path and stats The stats are a tuple of (time, expc, max_states): elapsed time, number of expansions, max states in memory """ def f(n, c=None): """ f(n) = g(n) + h(n) :param n: node :param c: child state of 'n' :return: L1 norm distance value """ return 0 if n is None else \ heuristics.l1_norm(problem.state_to_pos(c), problem.state_to_pos(int(problem.goalstate))) + n.pathcost + 1 t = timer() path, stats, node, _ = stype(problem, PriorityFringe(), f, gl_astar, opt=opt, avd=avd, shape='record') return path, (timer() - t, stats[0], gen(), stats[1]), close_dot(stats[0], node)
def ucs(problem, stype, opt=False, avd=False): """ Uniform-cost search :param avd: :param opt: :param problem: problem :param stype: type of search: graph or tree (graph_search or tree_search) :return: (path, stats): solution as a path and stats The stats are a tuple of (time, expc, max_states): elapsed time, number of expansions, max states in memory """ def g(n, c=None): """ Path cost function :param n: node :param c: child state of 'n' :return: path cost from root to 'c' """ return n.pathcost + 1 if n is not None else 0 t = timer() path, stats, node, _ = stype(problem, PriorityFringe(), g, gen_label, opt=opt, avd=avd) return path, (timer() - t, stats[0], gen(), stats[1]), close_dot(stats[0], node)
def r_dfs(problem, stype, opt=False, avd=False): """ Depth-first search :param avd: :param opt: :param problem: problem :param stype: type of search: graph or tree (graph_search or tree_search) :return: (path, stats, graph): solution as a path and stats The stats are a tuple of (time, expc, max_states): elapsed time, number of expansions, max states in memory """ t = timer() path, stats, node, _ = stype(problem, opt=opt, avd=avd, limit=-1) return path, (timer() - t, stats[1], gen(), stats[2]), close_dot(stats[1], node)
def bfs(problem, stype, opt=False, avd=False): """ Breadth-first search :param avd: :param opt: :param problem: problem :param stype: type of search: graph or tree (graph_search or tree_search) :return: (path, stats, graph): solution as a path and stats The stats are a tuple of (time, expc, max_states): elapsed time, number of expansions, max states in memory """ t = timer() path, stats, node, _ = stype(problem, QueueFringe(), lambda n, c: 0, gen_label, opt, avd) return path, (timer() - t, stats[0], gen(), stats[1]), close_dot(stats[0], node)
DOT GRAPH SECTION # FringeNode constructor takes 4 parameters, plus 7 optional parameter to generate the dot GRAPH: # 1 - the state embedded in the node # 2 - path cost (from the root node to the current one) # 3 - the value of the node (used for ordering within PriorityFringe) # 4 - parent node as FringeNode instance (None if we are building the root) # 5 - cause the action that generated this state (None or not specified if we are building the root) # 6 - problem the problem instance # 7 - gen_label function # 8 - shape of node (if not specified the default circle shape is gonna be used) # 9 - limit if is limited search (if not specified not limited) # 10 - closed if exist # 11 - fringe if exist """ node = FringeNode(start, 0, 0, None, cause=None, problem=env, shape='box', gen_label=gen_label, fringe=fringe) fringe.add(node) child = FringeNode(env.sample(start, 0), 1, 0, node, cause=0, problem=env, gen_label=gen_label, fringe=fringe) # Child node if child.state not in fringe: fringe.add(child) child = FringeNode(env.sample(start, 1), 1, 0, node, cause=1, problem=env, gen_label=gen_label) # Other child node if child.state in fringe and child.value < fringe[child.state].value: # Replace node of the same fringe.replace(child) print("\n" + close_dot(2))