예제 #1
0
def a_star_search(initial_state, goal_config, heuristic):
    PERIOD_OF_TIME = 150 # limite de tiempo: 300 segundos
    start_time = time.time()
    
    frontier = Frontier().heap  # lista de entradas ordenadas en un heap
    entry_finder = {}  # mapo de estados a entradas
    explored = Explored().set  # un set de estados explorados
    
    # calcular la heuristica inicial
    # en este punto, el costo g es 0
    if (heuristic=="heuristica_1" or heuristic=="ambas"):
        initial_state.f = h1(initial_state.config, goal_config)
    elif heuristic=="heuristica_2":
        initial_state.f = h2(initial_state.config, goal_config)
    
    # añadir estado inicial
    add_state(initial_state, entry_finder, frontier)
    
    # inicializar variable de métricas
    nodes = 0
    while frontier and time.time() - start_time < PERIOD_OF_TIME:
        # sacar el estado con menor costo desde frontier
        state = pop_state(frontier, entry_finder)
        
        # el estado actual ha sido explorado?
        if state.config not in explored:
            explored.add(state.config)
            
            # hemos llegado al estado final?
            if state.config == goal_config:
                return state, nodes, time.time() - start_time
            
            # expandir el estado
            state.expand()
            
            nodes = nodes + 1
            
            for child in state.children:
                # calcular el costo f para nodo hijo
                if heuristic=="heuristica_1":
                    child.f = child.cost + h1(child.config, goal_config)
                elif (heuristic=="heuristica_2" or heuristic=="ambas"):
                    child.f = child.cost + h2(child.config, goal_config)
                
                # revisar por duplicados en entry_finder
                if child.config not in entry_finder:
                    add_state(child, entry_finder, frontier)
                    
                # si un estado hijo ya está en frontier, actualiza 
                # su costo si el costo es menor
                elif child.f < entry_finder[child.config][0]:
                    
                    # actualizar la prioridad de un estado existente
                    remove_state(child.config, entry_finder)
                    add_state(child, entry_finder, frontier)
                    
    # retornamos los valores que consiguió el método de busqueda
    # aun si no consiguió resolver el problema
    return state, nodes, PERIOD_OF_TIME
예제 #2
0
def best_first_search(initial_state, goal_config):
    """Best First search"""

    start_time = time.time()  # initialize timer

    frontier = Frontier().heap  # list of entries arranged in a heap
    entry_finder = {}  # mapping of states to entries

    # calculate initial's states h cost
    initial_state.f = h1(initial_state.config, goal_config)
    # add initial state
    add_state(initial_state, entry_finder, frontier)

    explored = Explored().set

    max_depth = 0
    nodes = 0

    while frontier and time.time() - start_time < PERIOD_OF_TIME:
        # pop the state with the smaller cost from frontier
        state = pop_state(frontier, entry_finder)

        # check if the state has been explored
        if state.config not in explored:
            explored.add(state.config)

            # update max depth
            if max_depth < state.cost:
                max_depth = state.cost

            # check if the state is goal state
            if state.config == goal_config:
                print("SUCCESS")
                return state, nodes, max_depth, time.time() - start_time

            # expand the node
            state.expand()

            nodes = nodes + 1

            for child in state.children:
                # calculate the cost f for child
                child.f = h2(child.config, goal_config)

                # check for duplicates in frontier and frontier
                if child.config not in entry_finder:

                    add_state(child, entry_finder, frontier)
                # if child state is already in frontier update its cost if cost is less
                elif child.f < entry_finder[child.config][0]:

                    # update the priority of an existing state
                    remove_state(child.config, entry_finder)
                    add_state(child, entry_finder, frontier)

    print('FAILURE')
    exit()
예제 #3
0
def dfs_search(initial_state: BlockState, goal_config):
    """DFS search"""
    # initialize timer
    start_time = time.time()

    # initialize frontier and explored
    frontier = Frontier().stack
    frontier.append(initial_state)
    explored = Explored().set

    # frontier_configs is used just for searching and doesn't obstructs functionality
    frontier_configs = set()
    frontier_configs.add(initial_state.config)

    # initialize metrics variables
    max_depth = 0
    nodes = 0
    while frontier and time.time() - start_time < PERIOD_OF_TIME:

        # pop the first state the last state entered in frontier
        state = frontier.pop()
        frontier_configs.remove(state.config)

        # check if state is explored
        if state.config not in explored:
            explored.add(state.config)

            # update max depth
            if max_depth < state.cost:
                max_depth = state.cost

            # check if this state is goal state
            if state.config == goal_config:
                print("SUCCESS")
                return state, nodes, max_depth, time.time() - start_time

            # expand the state
            state.expand()

            # reverse children to put it in frontier with the same priority as bfs
            state.children = state.children[::-1]
            nodes = nodes + 1

            for child in state.children:
                # check for duplicates in frontier and explored
                if child.config not in frontier_configs:
                    # add child to frontier
                    frontier.append(child)
                    frontier_configs.add(child.config)
    print('FAILURE')
    exit()
예제 #4
0
def dfs_search(initial_state: BlockState, goal_config):
    PERIOD_OF_TIME = 30 # limite de tiempo: 30 segundos
    
    start_time = time.time()
    
    frontier = Frontier().stack
    frontier.append(initial_state)
    explored = Explored().set
    
    # frontier_configs es solo usado para busqueda
    frontier_configs = set()
    frontier_configs.add(initial_state.config)
    
    # inicializar variable de métricas
    nodes = 0
    while frontier and time.time() - start_time < PERIOD_OF_TIME:
        
        # sacar el primer y último estado que entraron en frontier
        state = frontier.pop()
        frontier_configs.remove(state.config)
        
        # revisar si el estado ya ha sido explorado
        if state.config not in explored:
            explored.add(state.config)
            
            # llegamos al estado final?
            if state.config == goal_config:
                return state, nodes, time.time() - start_time
            
            # expandir el estado
            state.expand()
            
            # revertir hijos para agregarlos en frontier con la misma prioridad que bfs
            state.children = state.children[::-1]
            nodes = nodes + 1
            
            for child in state.children:
                # revisar por duplicados en frontier y explored
                if child.config not in frontier_configs:
                    # añadir child a frontier
                    frontier.append(child)
                    frontier_configs.add(child.config)
                    
    # retornamos los valores que consiguió el método de busqueda
    # aun si no consiguió resolver el problema
    return state, nodes, PERIOD_OF_TIME
예제 #5
0
def bfs_search(initial_state: BlockState, goal_config):
    """BFS search"""
    # initialize timer
    start_time = time.time()

    # initialize frontier and explored
    frontier = Frontier().queue
    frontier.append(initial_state)
    explored = Explored().set

    # frontier_configs is used just for searching and doesn't obstructs functionality
    frontier_configs = set()
    frontier_configs.add(initial_state.config)

    # initialize metrics variable
    nodes = 0

    while frontier and time.time() - start_time < PERIOD_OF_TIME:

        # pop the first state entered in frontier
        state = frontier.popleft()
        frontier_configs.remove(state.config)
        explored.add(state.config)

        # check if this state is goal state
        if state.config == goal_config:
            print("SUCCESS")
            return state, nodes, state.cost, time.time() - start_time

        # expand the state
        state.expand()
        nodes = nodes + 1

        for child in state.children:
            # check for duplicates in frontier and explored
            if child.config not in explored and child.config not in frontier_configs:
                # add child to frontier
                frontier.append(child)
                frontier_configs.add(child.config)
    print('FAILURE')
    exit()
예제 #6
0
def bfs_search(initial_state: BlockState, goal_config):
    PERIOD_OF_TIME = 60 # limite de tiempo: 60 segundos
    
    start_time = time.time()
    
    frontier = Frontier().queue
    frontier.append(initial_state)
    explored = Explored().set
    
    # frontier_configs se usa solo para busqueda
    frontier_configs = set()
    frontier_configs.add(initial_state.config)
    
    nodes = 0
    
    while frontier and time.time() - start_time < PERIOD_OF_TIME:
        
        # sacar el primer estado que entró en frontier
        state = frontier.popleft()
        frontier_configs.remove(state.config)
        explored.add(state.config)
        
        # llegamos al estado final?
        if state.config == goal_config:
            return state, nodes, time.time() - start_time
        
        # expandir el estado
        state.expand()
        nodes = nodes + 1
        
        for child in state.children:
            # revisar por duplicados en frontier y explored
            if child.config not in explored and child.config not in frontier_configs:
                # añadir child a frontier
                frontier.append(child)
                frontier_configs.add(child.config)
    
    # retornamos los valores que consiguió el método de busqueda
    # aun si no consiguió resolver el problema
    return state, nodes, PERIOD_OF_TIME