Example #1
0
def Breadth_first_search(graph: Maze, start, goal):
    expanded = []
    expanded_with_parent = []
    frontier = []
    # dict format: { "Node": 2, "Parent": 1 },
    init = {"Node": start, "Parent": None}
    frontier.append(init)
    # return nothing if goal is start
    if start == goal:
        return [goal], [goal]

    while frontier:
        current_node = frontier.pop(0)
        node = current_node["Node"]
        if node not in expanded:
            neighbours = (graph.getNode(node)).adjacent_list()
            for neighbour in neighbours:
                if neighbour == goal:
                    expanded.append(node)
                    expanded.append(goal)
                    expanded_with_parent.append(current_node)
                    expanded_with_parent.append({"Node": goal, "Parent": node})

                    path_to_node = tracePath(expanded_with_parent, start, neighbour)
                    return expanded, path_to_node
                else:
                    new_node = {"Node": int(neighbour), "Parent": node}
                    frontier.append(new_node)
            expanded.append(node)
            expanded_with_parent.append(current_node)

    return expanded, None
def A_star_graph_search(graph: Maze, start, goal):
    if goal == start:
        return [], []

    path = []
    path.append(start)
    path_heuristic = graph.manhattan_heuristic_calculator(start)

    expanded = []
    frontier = []
    frontier.append(Evaluation(path_heuristic, path))

    while True:
        item = ExploreFrontier(frontier)  # find the best next node to explore
        if item is None:
            break

        current_node = item.getFurthestNode()
        current_path = list(item.getPath())
        current_cost = item.getCost() - graph.manhattan_heuristic_calculator(
            current_node)
        expanded.append(current_node)

        # if goal was in frontier
        if current_node == goal:
            return expanded, current_path

        nearby_nodes = (graph.getNode(current_node)).adjacent_list()

        for node in nearby_nodes:
            new_path = list(current_path)
            new_path.append(node)
            new_cost = current_cost + step_cost + graph.manhattan_heuristic_calculator(
                node)
            new_item = Evaluation(new_cost, new_path)

            location_in_frontier = is_in_frontier(node, frontier)
            if location_in_frontier is None:
                if node not in expanded:
                    frontier.append(new_item)
            else:
                # replace an existing frontier node which have higher cost
                if frontier[location_in_frontier].getCost() > new_cost:
                    frontier.pop(location_in_frontier)
                    frontier.append(new_item)
                    # no need to sort frontier 'cause ExploreFrontier can handle it

    return None, None
def A_star_graph_search(graph: Maze, start, goal):
    if goal == start:
        return [goal], [goal]

    start_heuristic = graph.manhattan_heuristic_calculator(start)
    init = {"Node": start, "Parent": None, "Cost": start_heuristic}
    expanded = []
    expanded_with_parent = []
    frontier = []
    frontier.append(init)

    while True:
        item = ExploreFrontier(frontier)# find the best next node to explore
        if item is None:
            #print(expanded)
            break

        expanded.append(item["Node"])
        expanded_with_parent.append(item)

        # if goal was in frontier
        if item["Node"] == goal:
            current_path = tracePath(expanded_with_parent, start, item["Node"])
            return expanded, current_path
        
        current_cost = item["Cost"] - graph.manhattan_heuristic_calculator(item["Node"])
        nearby_nodes = (graph.getNode(item["Node"])).adjacent_list()

        for node in nearby_nodes:
            new_cost = current_cost + step_cost + graph.manhattan_heuristic_calculator(node)
            new_item = {"Node": node, "Parent": item["Node"], "Cost": new_cost}

            location_in_frontier = is_in_frontier(node, frontier)
            if location_in_frontier is None:
                if node not in expanded:
                    frontier.append(new_item)
            else:
                temp = frontier[location_in_frontier]
                if temp["Cost"] > new_item["Cost"]:
                    frontier.pop(location_in_frontier)
                    frontier.append(new_item)
                    # no need to sort frontier 'cause ExploreFrontier can handle it

    return expanded, None

    
def Uniform_cost_search(graph: Maze, start, goal):
    if goal == start:
        return [], []
    
    path_cost = 0
    path = []
    path.append(start)
    expanded = []    
    frontier = []
    frontier.append(Evaluation(path_cost, path))
    
    while True:
        item = ExploreFrontier(frontier)
        if item is None:
            break
        
        current_node = item.getFurthestNode()
        current_path = list(item.getPath())
        current_cost = item.getCost()
        # print(current_path)
        expanded.append(current_node)
        
        # if goal was in frontier
        if current_node == goal:
            return expanded, current_path     
        
        nearby_nodes = (graph.getNode(current_node)).adjacent_list()
    
        for node in nearby_nodes:
            new_path = list(current_path)
            new_path.append(node)
            new_cost = current_cost + step_cost
            new_item = Evaluation(new_cost, new_path)
        
            in_frontier = is_in_frontier(node, frontier)
            if in_frontier is None:
                if node not in expanded:
                    frontier.append(new_item)
            else:
                if frontier[in_frontier].getCost() > new_cost:
                    frontier.pop(in_frontier)
                    frontier.append(new_item)
                    # no need to sort frontier 'cause ExploreFrontier can handle it
    
    return None, None
    
def recursive_depth_limited_search(graph: Maze, current_node: dict, goal, limit, expanded):
    expanded.append(current_node["Node"])
    if(current_node["Node"] == goal):
        return True, [current_node["Node"]]

    # If reached the depth limit, stop recursing. 
    if limit <= 0 : 
        return False, []
    
    node: Node = graph.getNode(current_node["Node"])
    nearby_nodes = node.adjacent_list()
    path = [current_node["Node"]]
    # Recur for all the vertices adjacent to this vertex 
    for item in nearby_nodes:       
        if item != current_node["Parent"]:
            next_node = {"Node" : item, "Parent" : current_node["Node"]}
            res, child_path = recursive_depth_limited_search(graph, next_node, goal, limit - 1, expanded)
            if(res): 
                return True, path + child_path
        
    return False, []
def Breadth_first_search(graph: Maze, start, goal):
    # keep track of explored nodes
    expanded_list = []
    # keep track of all the paths to be checked
    path_list = [[start]]

    # return nothing if goal is start
    if start == goal:
        return [], []

    # test run all given paths until path_list is empty
    while path_list:
        # pop the oldest path from the path_list -> FIFO
        path = path_list.pop(0)
        # get the furthest node in path
        node = path[-1]
        if node not in expanded_list:
            # get node's adjacent_list
            neighbours = (graph.getNode(node)).adjacent_list()
            # if input data is wrong (no node exist at given location)
            if neighbours is None:
                # mark node as explored
                expanded_list.append(node)
                continue
            # check go through all neighbour nodes, create a new path and add it into the testing_paths
            for neighbour in neighbours:
                new_path = list(path)
                new_path.append(neighbour)
                path_list.append(new_path)
                # return path if neighbour is goal
                if neighbour == goal:
                    expanded_list.append(node)
                    expanded_list.append(goal)  # task requirement
                    return expanded_list, new_path

            # mark node as explored
            expanded_list.append(node)
    # if no result can be found
    return None, None
def recursive_depth_limited_search(graph: Maze, current_node: int, goal, limit):
    if(goal == None):
        return True, Node
    
    return None

    # If reached the depth limit, stop recursing. 
    if limit <= 0 : 
        return False, None
    
    
    node = graph.getNode(current_node)
    nearby_nodes = node.adjacent_list()
    path = []
    path.append(current_node)
    # Recur for all the vertices adjacent to this vertex 
    for item in nearby_nodes:
        res, _path = recursive_depth_limited_search(graph, item, goal, limit - 1)
        if(res): 
            return True, path.append(path)
        
    return False, None