def a_star(task, heuristic=BlindHeuristic):
    expandedNodes = 0  ## couting the number of nodes
    flag = 0
    Que = frontiers.PriorityQueue()  ## stack que for saving nodes
    root_node = searchspace.make_root_node(
        task.initial_state)  ## creating nodes out of vertices.
    h_root_node = heuristic(
        root_node)  ## creating a node containing its heuristic values.
    Que.push(root_node, root_node.g + h_root_node)
    node_dict1 = dict()  ## dictionary to save nodes based on their cost.
    node_dict1[root_node.state] = (root_node.g + h_root_node)
    '''
    A loop to traverse the priority que in order to find the best solution.
    '''
    while not (Que.is_empty()):
        node = Que.pop()
        expandedNodes = expandedNodes + 1
        succ_act_state_list = task.get_successor_states(node.state)
        for succ_tuple in succ_act_state_list:
            succ_node = searchspace.make_child_node(node, succ_tuple[0],
                                                    succ_tuple[1])
            if task.goal_reached(succ_node.state):
                last_node = succ_node
                flag = 1
                break
            else:
                h_succ_state = heuristic(succ_node)
                if (succ_node.state in node_dict1.keys()):
                    if (node_dict1[succ_node.state] >
                        (succ_node.g + h_succ_state)):
                        node_dict1[
                            succ_node.state] = succ_node.g + h_succ_state
                        Que.change_priority(succ_node,
                                            succ_node.g + h_succ_state)
                else:
                    node_dict1[succ_node.state] = succ_node.g + h_succ_state
                    Que.push(succ_node, succ_node.g + h_succ_state)
        if flag == 1:
            break

    current_node = last_node
    action_list = []
    '''
    Finding the most optimal path to the solution. 
    '''
    while current_node != root_node:
        action_list.append(current_node.action)
        current_node = current_node.parent

    action_list.reverse()
    print("Expanded Nodes= ", expandedNodes)
    return action_list
    """
def solve(problem, heuristic):
    closed = dict()
    frontier = frontiers.PriorityQueue()

    startNode = search_strategies.SearchNode(problem.get_initial_state())
    frontier.push(startNode, 0)

    while not frontier.is_empty():
        node = frontier.pop()
        if problem.goal_test(node.state):
            return actionsList(node)

        if node.state not in closed or node.path_cost + heuristic(node.state,problem) < closed[node.state]:
            closed[node.state] = node.path_cost + heuristic(node.state,problem)
            for state, action, cost in problem.get_successors(node.state):

                    successorNode = search_strategies.SearchNode(state, action, node.path_cost + cost,
                                                                 node, node.depth + 1)
                    frontier.push(successorNode, successorNode.path_cost + heuristic(state, problem))
Exemplo n.º 3
0
def gbfs(task, heuristic=BlindHeuristic):
    expandedNodes = 0
    flag = 0
    Que = frontiers.PriorityQueue()
    root_node = searchspace.make_root_node(task.initial_state)
    heur = heuristic(root_node)
    Que.push(root_node, heur)
    node_dict1 = dict()
    node_dict1[root_node.state] = heur
    while not (Que.is_empty()):
        node = Que.pop()
        expandedNodes = expandedNodes + 1
        succ_act_state_list = task.get_successor_states(node.state)
        for succ_tuple in succ_act_state_list:
            succ_node = searchspace.make_child_node(node, succ_tuple[0],
                                                    succ_tuple[1])
            if task.goal_reached(succ_node.state):
                last_node = succ_node
                flag = 1
                break
            else:
                if (succ_node.state in node_dict1):
                    pass
                else:
                    heur = heuristic(succ_node)
                    node_dict1[succ_node.state] = heur
                    Que.push(succ_node, heur)
        if flag == 1:
            break

    current_node = last_node
    action_list = []
    while current_node != root_node:
        action_list.append(current_node.action)
        current_node = current_node.parent

    action_list.reverse()
    print("Expanded Nodes", expandedNodes)
    return action_list
Exemplo n.º 4
0
def compute_mst(vertices, problem):
    key = {}
    pred = {}
    for v in vertices:
        key[v] = sys.maxint
        pred[v] = None
    key[vertices[0]] = 0
    pq = frontiers.PriorityQueue()
    for v in vertices:
        pq.push(v, key[v])
    while not pq.is_empty():
        u = pq.pop()
        for v in vertices:
            if v != u:
                item = pq.find(lambda x: x == v)
                if item != None:
                    w = problem.maze_distance(u, v)
                    if w < key[v]:
                        pred[v] = u
                        key[v] = w
                        pq.change_priority(item, w)
    # return the sum of weight of all edges in the tree
    return sum(key.values())
def solve(problem,heuristic) :
    """ *** YOUR CODE HERE *** """


    cost=0
    Que= frontiers.PriorityQueue()
    Que.__init__()
    Que1= frontiers.PriorityQueue()
    Que1.__init__()
    pos=problem.get_initial_state()
    node1=CreateNode(pos,(-1,-1),'stop',cost,heuristic,problem)
    Que.push(node1,node1.totalCost)
    Que1.push(node1,node1.totalCost)
    flag=0;
    list_node=[]
    
    while not (Que.is_empty()):
        node=Que.pop();
#        print(node.my_position)
        successors_list=problem.get_successors(node.my_position)
        for successor_tuple in successors_list:
            my_Cost=node.Cost+ successor_tuple[2]
            node_temp=CreateNode(successor_tuple[0],node.my_position,successor_tuple[1],my_Cost,heuristic,problem)
            Redflag=0
            for QueNode in Que1.heap:
                if QueNode[2].my_position==node_temp.my_position and QueNode[2].totalCost<=node_temp.totalCost:
                    Redflag=1
                    break
                else:
                    Redflag=0
                
            if Redflag==0:
                list_node.append(node_temp)  
                if problem.goal_test(node_temp.my_position):
                    node_final=node_temp
                    flag=1
                    break
                else:
                    Que.push(node_temp,node_temp.totalCost)
                    Que1.push(node_temp,node_temp.totalCost)
        if flag==1:
            break
    
    
    direction_list=[node_temp.Action]
    final_list=[node_temp.my_position]
    list_node=[]
    for Q in Que1.heap:
        list_node.append(Q[2])


    while (final_list[len(final_list)-1]!=problem.get_initial_state()):
        for i in range(0,len(list_node)):
            if list_node[i].my_position== node_final.parent_position: 
                final_list.append(list_node[i].my_position)
                node_final=list_node[i]
                if list_node[i].my_position==problem.get_initial_state():
                    break
                direction_list.append(list_node[i].Action)
        
    direction_list.reverse()

    return direction_list
Exemplo n.º 6
0
def a_star_search(problem, heuristic=heuristics.null_heuristic):
    """ Q3: A* Search (3 marks)
        
        Search the node that has the lowest combined cost and heuristic first.

        Your A* search will use the heuristic contained in the heuristic argument.
        The heuristics take a state and return an estimate of the cost to reach
        the goal from that state. The heuristics are defined in heuristics.py
        and for this problem include a null_heuristic, a Manhattan heuristic,
        and a Euclidean heuristic.
        
        It can be assumed that the supplied heuristic function will work with
        the state representation of whatever SearchProblem you have been given
        here.
        
        A* is best implemented with a priority queue found in frontiers.py.
        You can use it by having:
        
            queue = frontiers.PriorityQueue()   OR
            queue = frontiers.PriorityQueueWithFunction(evaluation_function)
            
        In the latter case, you will need to define and pass an evaluation function
        which takes a search node and returns an appropriate f value for the node
        using the given heuristic.
        
        You might want to do this to aid in making a generic search function to
        be used for Q1-3. Making such a generic function is not required.
    """
    """ *** YOUR CODE HERE *** """

    ##prepare the open list(queue) and close list to perform graph search
    queue = frontiers.PriorityQueue()
    close = []

    ##prepare the path to save node from start to goal
    path = []

    ##make start node as a object and assign its values
    start = SearchNode(problem.get_initial_state(), '', 0, '')
    problem.heuristic_info[problem.get_initial_state()] = start

    ##at the same time, push the start node into the queue
    queue.push(start, heuristic(start.state, problem) + start.path_cost)

    ##test the queue.peek() is goal or not

    while not problem.goal_test(queue.peek().state):

        ##pick node with lowest value in queue to test the node has been visit before
        ##or go to the else: part
        if queue.peek().state not in close:

            ##add the explored node to close list
            close.append(queue.peek().state)

            ##save the next node based on the current state to nextnode list
            nextnode = []

            for node in problem.get_successors(queue.peek().state):
                nextnode.append(node)

            ##get parent_state and delete explored node
            parent = queue.pop()

            ##item[0] is state, item[1] is action, item[2] is action_cost
            for item in nextnode:

                ##if the node has never been explored before
                if item[0] not in close or queue.find(
                        lambda x: x.state == item[0]) is None:
                    next_node = SearchNode(item[0], item[1],
                                           parent.path_cost + item[2], parent)

                    ##push the next_node into queue with value
                    queue.push(
                        next_node,
                        heuristic(next_node.state, problem) +
                        next_node.path_cost)

                    ##save the item and node information to problem.heuristic_info dictionary
                    problem.heuristic_info[item[0]] = next_node

                ##when we found a node has already explored with lower cost, explored it again
                elif item[0] in close and parent.path_cost + item[
                        2] < problem.heuristic_info[item[0]].path_cost:
                    next_node = SearchNode(item[0], item[1],
                                           parent.path_cost + item[2], parent)

                    ##push the node back to queue list again
                    queue.push(
                        next_node,
                        heuristic(next_node.state, problem) +
                        next_node.path_cost)

                    ##delete it from close list
                    close.remove(item[0])

        ##if the node has explored before, delete it
        else:
            queue.pop()

        ##stop the search when queue is empty
        if queue.is_empty():

            return 'Cannot find a path'

    ##get the goal node is queue.peek(), by find its parent node to collect
    ##the actions in the path from goal node to start node
    temp = queue.peek()

    while temp.state is not start.state:
        path.append(temp.action)
        temp = temp.parent

    ##change the order of the actions to get a path from start to goal
    path = path[::-1]

    return path