示例#1
0
    def search(self, task, use_relaxed_plan=False):
        """
        Searches for a plan in the given task using A* search.
        """
        node = task.pop_open()
        task.close(node)

        if node in self.state_cost:
            del self.state_cost[node]

        rplan = None
        if use_relaxed_plan:
            (rh, rplan) = node.heuristic.calc_h_with_plan(searchspace.make_root_node(node.state))

        for operator, successor_state in task.get_successor_states(node.state):
            # ignore this operator if we use the relaxed plan criterion
            if use_relaxed_plan and rplan and not op.name in rplan: continue

            newNode = searchspace.make_child_node(node, operator, successor_state)
            if task.goal_reached(newNode):
                return newNode

            # drop dead ends and explored nodes and nodes on open but with higher costs
            crapNode = self.state_cost[newNode] if newNode in self.state_cost else None
            if newNode.h == float('inf') or task.is_closed(newNode) \
                                         or (crapNode and newNode.g > crapNode.g):
                continue
                             
            #if there's a crapNode we now know it really is crap and we make it kick the bucket
            if crapNode and newNode.g < crapNode.g:
                task.del_open(crapNode)
                del self.state_cost[crapNode]

            task.push_open(newNode)
            self.state_cost[newNode] = newNode
 def setup_root_node(self, task, heuristic):
     rnode = searchspace.make_root_node(task.initial_state, heuristic, self.sorting_rule)
     if (task.goal_reached(rnode)):
         return rnode
     else:
         task.push_open(rnode)
         self.best_heuristic_value = rnode.h
示例#3
0
def gbfs(task, heuristic=BlindHeuristic):
    """
    Searches for a plan in the given task using Greedy Best First Search search.

    @param task The task to be solved
    @param heuristic  A heuristic callable which computes the estimated steps
                      from a search node to reach the goal.
    """

    startSearchNode = searchspace.make_root_node(task.initial_state)
    heap = []
    heapq.heappush(heap, (heuristic(startSearchNode), 0, startSearchNode))
    count = 0
    res = None
    nodeCount = 0
    vis = set()
    while True:
        if not heap:
            return 0
        _, _, tempSearchNode = heapq.heappop(heap)
        nodeCount += 1
        if tempSearchNode.state in vis:
            continue
        vis.add(tempSearchNode.state)
        for action, state in Task.get_successor_states(task,
                                                       tempSearchNode.state):
            nextSearchNode = searchspace.make_child_node(
                tempSearchNode, action, state)
            if Task.goal_reached(task, state):
                logging.info("Node Expansion: " + str(nodeCount))
                return nextSearchNode.extract_solution()
            else:
                count += 1
                heapq.heappush(
                    heap, (heuristic(nextSearchNode), count, nextSearchNode))
示例#4
0
文件: gbfs.py 项目: Gin93/111
def gbfs(task, heuristic=BlindHeuristic):
	"""
	Searches for a plan in the given task using Greedy Best First Search search.

	@param task The task to be solved
	@param heuristic  A heuristic callable which computes the estimated steps
					  from a search node to reach the goal.
	"""
	heap = []
	
	root_node = searchspace.make_root_node(task.initial_state)   # def __init__(self, state, parent, action, g):
	explored = set()
	explored.add(root_node.state)
	counter = 1  # incase the heapq get stuck
	heapq.heappush(heap,( heuristic(root_node)  ,counter , root_node    ))
	node_expansion = 0  # the number of nodes expansion 
	while (True):
		node = heapq.heappop(heap)[2]
		node_expansion = node_expansion + 1  #  POP = node expansion  
		if task.goal_reached(node.state):
			print("------------------")
			print("node expasion:")
			print(node_expansion)   # print the node_expansion for question 3 
			print("------------------")
			return node.extract_solution()

		for successor in task.get_successor_states(node.state):  # pair  successor(1)  or  [1]
			succ_state = successor[1]
			succ_action = successor[0]
			if succ_state not in explored:  # in order loop
				new_node = searchspace.make_child_node(node,succ_action,succ_state)  #make_child_node(parent_node, action, state):
				explored.add(succ_state)
				counter = counter + 1
				heapq.heappush(heap,( heuristic(new_node) , counter ,new_node ))
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
    """
示例#6
0
def a_star(task, heuristic=BlindHeuristic):
    """
    Searches for a plan in the given task using A* search.

    @param task The task to be solved
    @param heuristic  A heuristic callable which computes the estimated steps
                      from a search node to reach the goal.
    """
    import time
    start = time.time()
    explored = {}
    queue = []

    # create initial node and push into the queue
    sn_0 = searchspace.make_root_node(task.initial_state)
    heapq.heappush(queue, (heuristic(sn_0) + sn_0.g, 0, sn_0))

    temp = 0  # counter for the queue to break overlab
    num_nodes = 0  # number of pxpanded nodes
    while len(queue) != 0:

        # timer to timeout the program
        # if time.time() - start > 60:
        #     print("time out")
        #     exit()

        # dequeue a top priority node
        current_node = heapq.heappop(queue)[2]
        # count the number of expanded nodes
        num_nodes += 1

        # check if the state is the goal or not
        if task.goal_reached(current_node.state):
            print(current_node.extract_solution())
            logging.info("Number of nodes: " + str(num_nodes))
            return current_node.extract_solution()

        # put this node's state in the explored dictionary with its cost
        explored[current_node.state] = heuristic(current_node) + current_node.g

        for action, state in task.get_successor_states(current_node.state):
            # create new node for the successor
            new_node = searchspace.make_child_node(current_node, action, state)
            # calculate the heuristic value for this new node
            heuristic_new_node = heuristic(new_node) + current_node.g
            # if this state is not visited yet or the cost to get this state is cheper than current cost, register/update the cost to get this state
            if state not in explored or explored[state] > heuristic_new_node:
                explored[state] = heuristic_new_node
                temp += 1
                heapq.heappush(queue, (heuristic_new_node, temp, new_node))
示例#7
0
    def pyperplan_hill_climbing(task):
        # assert False

        current = searchspace.make_root_node(task.initial_state)
        current_h = heuristic(current.state)

        iterations = 0

        while not task.goal_reached(current.state):
            iterations += 1
            if iterations % 1000 == 0:
                logging.debug(
                    "Number of visited states in hill-climbing: {}".format(
                        iterations))

            improvement_found = False
            successors = task.get_successor_states(current.state)

            if not successors:
                logging.error("State without successors found: {}".format(
                    current.state))
                return None

            # This implements steepest-ascent hill climbing.
            # If we want to test in problems with very large branching factors, we might want to jump to
            # an heuristic-improving child as soon as we find one.
            succesor_h_values = [(heuristic(succ), succ, op)
                                 for op, succ in successors]
            h_succ, succ, op = min(succesor_h_values, key=lambda x: x[0])

            if h_succ < current_h:
                current = searchspace.make_child_node(current, op, succ)
                current_h = h_succ
            else:
                logging.error(
                    "Heuristic local minimum of {} found on state {}".format(
                        current_h, current.state))
                logging.error("Children nodes:")
                print("\t" + "\n\t".join("h: {}, s: {}".format(h, s)
                                         for h, s, _ in succesor_h_values))
                return None

        logging.info("Goal found")
        return current.extract_solution()
示例#8
0
def a_star(task, heuristic=BlindHeuristic):
    """
    Searches for a plan in the given task using A* search.

    @param task The task to be solved
    @param heuristic  A heuristic callable which computes the estimated steps
                      from a search node to reach the goal.
    """
    startSearchNode = searchspace.make_root_node(task.initial_state)
    heap = []
    h0 = heuristic(startSearchNode)
    count = 0
    heapq.heappush(heap, (h0, count, startSearchNode))
    count += 1
    nodeCount = 0
    vis = set()
    res = None

    while heap:
        tempH, _, tempSearchNode = heapq.heappop(heap)
        nodeCount += 1
        if tempSearchNode.state in vis:
            continue
        vis.add(tempSearchNode.state)
        if res and res.g <= tempH:
            break
        for action, state in Task.get_successor_states(task,
                                                       tempSearchNode.state):
            nextSearchNode = searchspace.make_child_node(
                tempSearchNode, action, state)
            if Task.goal_reached(task, state):
                if res and res.g <= nextSearchNode.g:
                    continue
                res = nextSearchNode
            else:
                count += 1
                heapq.heappush(heap,
                               (nextSearchNode.g + heuristic(nextSearchNode),
                                count, nextSearchNode))
    logging.info("Node Expansion: " + str(nodeCount))
    return res.extract_solution()
示例#9
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
def astar_search(task,
                 heuristic,
                 make_open_entry=ordered_node_astar,
                 use_relaxed_plan=False):
    """
    Searches for a plan in the given task using A* search.

    @param task The task to be solved
    @param heuristic  A heuristic callable which computes the estimated steps
                      from a search node to reach the goal.
    @param make_open_entry An optional parameter to change the bahavior of the
                           astar search. The callable should return a search
                           node, possible values are ordered_node_astar,
                           ordered_node_weighted_astar and
                           ordered_node_greedy_best_first with obvious
                           meanings.
    """
    open = []
    state_cost = {task.initial_state: 0}
    node_tiebreaker = 0

    root = searchspace.make_root_node(task.initial_state)
    # There is often a one-step error in estimation here
    init_h = heuristic(root)
    heapq.heappush(open, make_open_entry(root, init_h, node_tiebreaker))
    logging.info("Initial h value: %f" % init_h)

    besth = float('inf')
    counter = 0
    expansions = 0

    while open:
        (f, h, _tie, pop_node) = heapq.heappop(open)
        if h < besth:
            besth = h
            logging.debug("Found new best h: %d after %d expansions" %
                          (besth, counter))

        pop_state = pop_node.state
        # Only expand the node if its associated cost (g value) is the lowest
        # cost known for this state. Otherwise we already found a cheaper
        # path after creating this node and hence can disregard it.
        if (state_cost[pop_state]
                == pop_node.g) and (state_cost[pop_state] != float('inf')):
            expansions += 1

            if task.goal_reached(pop_state):
                logging.info("Goal reached. Start extraction of solution.")
                logging.info("%d Nodes expanded" % expansions)
                return pop_node.extract_solution(), expansions
            rplan = None
            if use_relaxed_plan:
                (rh, rplan) = heuristic.calc_h_with_plan(
                    searchspace.make_root_node(pop_state))
                logging.debug("relaxed plan %s " % rplan)

            for op, succ_state in task.get_successor_states(pop_state):
                if use_relaxed_plan:
                    if rplan and not op.name in rplan:
                        # ignore this operator if we use the relaxed plan
                        # criterion
                        logging.debug('removing operator %s << not a '
                                      'preferred operator' % op.name)
                        continue
                    else:
                        logging.debug('keeping operator %s' % op.name)

                ## Visual scoring algorithm ##
                visual_score = 0.0

                if 'join-' in op.name:
                    # Keep track of constructions that are already attempted
                    action_part, handle_part, tool_type = actionParser(op)
                    if (action_part, handle_part) in object_combinations:
                        visual_score = -float('inf')

                    # Compute visual score if flag enabled
                    elif settings_flag['vs_flag']:
                        # Check if parts can be attached
                        if attCompute(action_part, handle_part):
                            visual_score = scoreCompute(
                                action_part, handle_part, tool_type)
                        else:
                            visual_score = -float('inf')

                        # Check flag for sensor_trust parameter
                        if settings_flag['trust'] and visual_score == -float(
                                'inf'):
                            # Use shape score only if visual_score is infinity
                            visual_score = scoreCompute(
                                action_part, handle_part, tool_type, True)

                succ_node = searchspace.make_child_node(
                    pop_node, op, succ_state)

                # We subtract from 2 because max visual score is 2, and we need to retain admissibility of heuristic
                h = heuristic(succ_node) - visual_score if settings_flag[
                    'ff_flag'] else 2.0 - visual_score

                if h == float('inf'):
                    # don't bother with states that can't reach the goal anyway
                    continue
                old_succ_g = state_cost.get(succ_state, float("inf"))
                if succ_node.g < old_succ_g:
                    # We either never saw succ_state before, or we found a
                    # cheaper path to succ_state than previously.
                    node_tiebreaker += 1
                    heapq.heappush(
                        open, make_open_entry(succ_node, h, node_tiebreaker))
                    state_cost[succ_state] = succ_node.g

        counter += 1
    logging.info("No operators left. Task unsolvable.")
    logging.info("%d Nodes expanded" % expansions)
    return None, expansions
示例#11
0
文件: a_star.py 项目: KDercksen/SPML
def astar_search(task, heuristic, make_open_entry=ordered_node_astar,
                 use_relaxed_plan=False):
    """
    Searches for a plan in the given task using A* search.

    @param task The task to be solved
    @param heuristic  A heuristic callable which computes the estimated steps
                      from a search node to reach the goal.
    @param make_open_entry An optional parameter to change the bahavior of the
                           astar search. The callable should return a search
                           node, possible values are ordered_node_astar,
                           ordered_node_weighted_astar and
                           ordered_node_greedy_best_first with obvious
                           meanings.
    """
    open = []
    state_cost = {task.initial_state: 0}
    node_tiebreaker = 0

    root = searchspace.make_root_node(task.initial_state)
    init_h = heuristic(root)
    heapq.heappush(open, make_open_entry(root, init_h, node_tiebreaker))
    logging.info("Initial h value: %f" % init_h)

    besth = float('inf')
    counter = 0
    expansions = 0

    while open:
        (f, h, _tie, pop_node) = heapq.heappop(open)
        if h < besth:
            besth = h
            logging.debug("Found new best h: %d after %d expansions" %
                          (besth, counter))

        pop_state = pop_node.state
        # Only expand the node if its associated cost (g value) is the lowest
        # cost known for this state. Otherwise we already found a cheaper
        # path after creating this node and hence can disregard it.
        if state_cost[pop_state] == pop_node.g:
            expansions += 1

            if task.goal_reached(pop_state):
                logging.info("Goal reached. Start extraction of solution.")
                logging.info("%d Nodes expanded" % expansions)
                return pop_node.extract_solution()
            rplan = None
            if use_relaxed_plan:
                (rh, rplan) = heuristic.calc_h_with_plan(
                                        searchspace.make_root_node(pop_state))
                logging.debug("relaxed plan %s " % rplan)

            for op, succ_state in task.get_successor_states(pop_state):
                if use_relaxed_plan:
                    if rplan and not op.name in rplan:
                        # ignore this operator if we use the relaxed plan
                        # criterion
                        logging.debug('removing operator %s << not a '
                                      'preferred operator' % op.name)
                        continue
                    else:
                        logging.debug('keeping operator %s' % op.name)

                succ_node = searchspace.make_child_node(pop_node, op,
                                                        succ_state)
                h = heuristic(succ_node)
                if h == float('inf'):
                    # don't bother with states that can't reach the goal anyway
                    continue
                old_succ_g = state_cost.get(succ_state, float("inf"))
                if succ_node.g < old_succ_g:
                    # We either never saw succ_state before, or we found a
                    # cheaper path to succ_state than previously.
                    node_tiebreaker += 1
                    heapq.heappush(open, make_open_entry(succ_node, h,
                                                         node_tiebreaker))
                    state_cost[succ_state] = succ_node.g

        counter += 1
    logging.info("No operators left. Task unsolvable.")
    logging.info("%d Nodes expanded" % expansions)
    return None
示例#12
0
def astar_state_sampling(task, heuristic, max_fn, sample_size):
    """
	Samples states in the heuristic search cone
	
	@param task 		The task defining the state model
	@param heuristic 	The heuristic to be used
	"""
    import random

    open = []
    state_cost = {task.initial_state: 0}
    node_tiebreaker = 0

    root = searchspace.make_root_node(task.initial_state)
    root.g = 0
    root.tie = node_tiebreaker
    init_h = heuristic(root)
    root.h = init_h
    heapq.heappush(open, ordered_node_astar(root, init_h, node_tiebreaker))

    besth = float('inf')
    counter = 0
    expansions = 0

    witnesses = []

    while open:
        (f, h, _tie, pop_node) = heapq.heappop(open)
        if pop_node.g > max_fn: continue
        pop_state = pop_node.state
        # Only expand the node if its associated cost (g value) is the lowest
        # cost known for this state. Otherwise we already found a cheaper
        # path after creating this node and hence can disregard it.
        if state_cost[pop_state] == pop_node.g:
            expansions += 1

            if random.randint(0, max_fn) > pop_node.g:
                witnesses.append((pop_node, h))
                sample_size -= 1
                if sample_size == 0: return witnesses  # we're done

            if task.goal_reached(pop_state):
                continue

            for op, succ_state in task.get_successor_states(pop_state):
                succ_node = searchspace.make_child_node(
                    pop_node, op, succ_state)
                h = heuristic(succ_node)
                if h == float('inf'):
                    # don't bother with states that can't reach the goal anyway
                    continue
                old_succ_g = state_cost.get(succ_state, float("inf"))
                if succ_node.g < old_succ_g:
                    # We either never saw succ_state before, or we found a
                    # cheaper path to succ_state than previously.
                    node_tiebreaker += 1
                    succ_node.tie = node_tiebreaker
                    succ_node.h = h
                    heapq.heappush(
                        open, ordered_node_astar(succ_node, h,
                                                 node_tiebreaker))
                    state_cost[succ_state] = succ_node.g

        counter += 1

    return witnesses
示例#13
0
import py.test

# create 4 dummy tasks
task1 = dummy_task.get_search_space_at_goal()
task2 = dummy_task.get_simple_search_space()
task3 = dummy_task.get_simple_search_space_2()
task4 = dummy_task.get_search_space_no_solution()

# call the heuristic for each task
h1 = dummy_task.DummyHeuristic(task1)
h2 = dummy_task.DummyHeuristic(task2)
h3 = dummy_task.DummyHeuristic(task3)
h4 = dummy_task.DummyHeuristic(task4)

# create root node for each task
root1 = searchspace.make_root_node(task1.initial_state)
root2 = searchspace.make_root_node(task2.initial_state)
root3 = searchspace.make_root_node(task3.initial_state)
root4 = searchspace.make_root_node(task4.initial_state)

# Testing each function if it returns the correct values


def test_ordered_node_astar1():
    h_val = h1(root1)
    assert a_star.ordered_node_astar(root1, h_val, 0) == (0, 0, 0, root1)


def test_ordered_node_astar2():
    h_val = h2(root2)
    assert a_star.ordered_node_astar(root2, h_val, 0) == (5, 5, 0, root2)
示例#14
0
def test_blind_heuristic_start():
    task = _get_simple_task()
    bh = BlindHeuristic(task)
    assert bh(searchspace.make_root_node(task.initial_state)) == 1
示例#15
0
def astar_search(task,
                 heuristic,
                 make_open_entry=ordered_node_astar,
                 use_relaxed_plan=False):
    """
    Searches for a plan in the given task using A* search.

    @param task The task to be solved
    @param heuristic  A heuristic callable which computes the estimated steps
                      from a search node to reach the goal.
    @param make_open_entry An optional parameter to change the bahavior of the
                           astar search. The callable should return a search
                           node, possible values are ordered_node_astar,
                           ordered_node_weighted_astar and
                           ordered_node_greedy_best_first with obvious
                           meanings.
    """
    open = []
    state_cost = {task.initial_state: 0}
    node_tiebreaker = 0

    root = searchspace.make_root_node(task.initial_state)
    init_h = heuristic(root)
    heapq.heappush(open, make_open_entry(root, init_h, node_tiebreaker))
    logging.info("Initial h value: %f" % init_h)

    besth = float('inf')
    counter = 0
    expansions = 0

    while open:
        (f, h, _tie, pop_node) = heapq.heappop(open)
        if h < besth:
            besth = h
            logging.debug("Found new best h: %d after %d expansions" %
                          (besth, counter))

        pop_state = pop_node.state
        # Only expand the node if its associated cost (g value) is the lowest
        # cost known for this state. Otherwise we already found a cheaper
        # path after creating this node and hence can disregard it.
        if state_cost[pop_state] == pop_node.g:
            expansions += 1

            if task.goal_reached(pop_state):
                logging.info("Goal reached. Start extraction of solution.")
                logging.info("Nodes expanded: %d" % expansions)
                return pop_node.extract_solution()
            rplan = None
            if use_relaxed_plan:
                (rh, rplan) = heuristic.calc_h_with_plan(
                    searchspace.make_root_node(pop_state))
                logging.debug("relaxed plan %s " % rplan)

            for op, succ_state in task.get_successor_states(pop_state):
                if use_relaxed_plan:
                    if rplan and not op.name in rplan:
                        # ignore this operator if we use the relaxed plan
                        # criterion
                        logging.debug('removing operator %s << not a '
                                      'preferred operator' % op.name)
                        continue
                    else:
                        logging.debug('keeping operator %s' % op.name)

                succ_node = searchspace.make_child_node(
                    pop_node, op, succ_state)
                h = heuristic(succ_node)

                print(80 * '*')
                print("HEURISTIC:", h)
                print("STATE:", succ_node.state)
                print(80 * '*')

                if h == float('inf'):
                    # don't bother with states that can't reach the goal anyway
                    continue
                old_succ_g = state_cost.get(succ_state, float("inf"))
                if succ_node.g < old_succ_g:
                    # We either never saw succ_state before, or we found a
                    # cheaper path to succ_state than previously.
                    node_tiebreaker += 1
                    heapq.heappush(
                        open, make_open_entry(succ_node, h, node_tiebreaker))
                    state_cost[succ_state] = succ_node.g

        counter += 1
    logging.info("No operators left. Task unsolvable.")
    logging.info("Nodes expanded: %d" % expansions)
    return None
示例#16
0
def pref_partial_astar_search(task,
                              heuristic,
                              succ_fn=None,
                              make_open_entry=ordered_node_astar):
    """
        Searches for a plan in the given task using A* search.
        
        @param task The task to be solved
        @param heuristic  A heuristic callable which computes the estimated steps
                          from a search node to reach the goal.
        @param make_open_entry An optional parameter to change the bahavior of the
                                   astar search. The callable should return a search
                                node, possible values are ordered_node_astar,
                                ordered_node_weighted_astar and
                                ordered_node_greedy_best_first with obvious
                                meanings.
        """
    if succ_fn is None:
        succ_fn = task.compute_successor_state
    open = []
    node_tiebreaker = 0

    root = searchspace.make_root_node(task.initial_state)
    init_h = heuristic(root)
    heapq.heappush(open,
                   make_open_entry(root, init_h, tie_breaking_function(root)))
    logging.info("Initial h value: %f" % init_h)
    # try:
    #     heuristic.print_relaxed_plan()
    # except:
    #     pass
    pending = {task.initial_state: root}
    closed = {}

    if init_h == float('inf'):
        logging.info('Problem has no solution, h(s0) = infty')
        return None

    besth = float('inf')
    maxf = root.g + root.h
    counter = 0
    expansions = 0

    while open:
        entry = heapq.heappop(open)  # this is the best node in Open
        f, h, _tie, pop_node = entry
        check_f = pop_node.g + h
        if check_f < f:
            # this node was re-inserted with a lower f-value, so it has already
            # been expanded.
            continue
        elif check_f > f:
            logging.info(
                'PrefPEA*: ASSERT FAIL! f={0}, h={1}, g={2}, po(n)={3}, s={4}, n={5}'
                .format(
                    f, h, pop_node.g,
                    len(pop_node.preferred_ops) -
                    pop_node.preferred_ops_counter,
                    str(pop_node.state.primary),
                    [act.name for act in pop_node.extract_solution()]))
        assert check_f <= f
        #assert pop_node.state in pending
        pending.pop(pop_node.state)
        if f > maxf:
            maxf = f
            logging.info("f = %d, nodes = %d" % (maxf, expansions))
        if h < besth:
            besth = h
            logging.debug("Found new best h: %d after %d evaluations" %
                          (besth, counter))

        pop_state = pop_node.state
        if h == float('inf'):
            # Remove from open
            closed[pop_state] = pop_node
            continue

        if task.goal_reached(pop_state):
            logging.info("Goal reached. Start extraction of solution.")
            logging.info("{0} Nodes expanded, {1} Nodes evaluated".format(
                expansions, counter))
            return pop_node.extract_solution()

        logging.debug(
            'PrefPEA*: Expanding f={0}, h={1}, g={2}, po(n)={3}, s={4}, n={5}'.
            format(
                f, h, pop_node.g,
                len(pop_node.preferred_ops) - pop_node.preferred_ops_counter,
                str(pop_node.state.primary),
                [act.name for act in pop_node.extract_solution()]))

        if pop_node.preferred_ops_counter < len(pop_node.preferred_ops):
            # get next preferred operator, and increase the counter
            action = pop_node.preferred_ops[pop_node.preferred_ops_counter]
            pop_node.preferred_ops_counter += 1

            # generate successor (expensive!)
            succ_state = succ_fn(pop_state, action)
            if succ_state is None:
                heapq.heappush(open, (f, h, _tie, pop_node))
                pending[pop_state] = pop_node
                continue
            logging.debug('Applying helpful action: {0} with cost: {1}'.format(
                action.name, action.cost))
            succ_node = searchspace.make_child_node(pop_node, action,
                                                    succ_state)
            if new_state(succ_node, heuristic, make_open_entry, open, pending,
                         closed):
                counter += 1
                #assert succ_node.state in pending
            heapq.heappush(open, (f, h, _tie, pop_node))
            pending[pop_state] = pop_node
            continue

        for a in task.actions:
            if a in pop_node.preferred_ops: continue
            #logging.info( 'PrefPEA*: Generating successor through non-preferred op...' )
            succ_state = succ_fn(pop_state, a)
            if succ_state is None:
                continue
            succ_node = searchspace.make_child_node(pop_node, a, succ_state)
            if new_state(succ_node, heuristic, make_open_entry, open, pending,
                         closed):
                counter += 1
                #assert succ_node.state in pending

        # Remove from open
        logging.debug(
            'PrefPEA*: closing f={0}, h={1}, g={2}, po(n)={3}, s={4}, n={5}'.
            format(
                pop_node.f, pop_node.h, pop_node.g,
                len(pop_node.preferred_ops) - pop_node.preferred_ops_counter,
                str(pop_node.state.primary),
                [act.name for act in pop_node.extract_solution()]))
        closed[pop_state] = pop_node
        expansions += 1

    logging.info("No operators left. Task unsolvable.")
    logging.info("{0} Nodes expanded, {1} Nodes evaluated".format(
        expansions, counter))
    return None
示例#17
0
def restarting_pref_partial_astar_search(task,
                                         heuristic,
                                         make_open_entry=ordered_node_astar):
    """
        Searches for a plan in the given task using A* search.
        
        @param task The task to be solved
        @param heuristic  A heuristic callable which computes the estimated steps
                          from a search node to reach the goal.
        @param make_open_entry An optional parameter to change the bahavior of the
                                   astar search. The callable should return a search
                                node, possible values are ordered_node_astar,
                                ordered_node_weighted_astar and
                                ordered_node_greedy_best_first with obvious
                                meanings.
        """
    succ_fn = task.compute_successor_state_ngl_dyn_model
    open = []
    node_tiebreaker = 0

    root = searchspace.make_root_node(task.initial_state)
    init_h = heuristic(root)
    heapq.heappush(open,
                   make_open_entry(root, init_h, tie_breaking_function(root)))
    logging.info("Initial h value: %f" % init_h)
    pending = {task.initial_state: root}
    closed = {}

    besth = float('inf')
    counter = 0
    expansions = 0

    while open:
        entry = open[0]  # this is the best node in Open
        (f, h, _tie, pop_node) = entry
        if h < besth:
            besth = h
            logging.debug("Found new best h: %d after %d evaluations" %
                          (besth, counter))

        pop_state = pop_node.state
        if h == float('inf'):
            # Remove from open
            heapq.heappop(open)
            pending.pop(pop_state)
            closed[pop_state] = pop_node
            continue

        if task.goal_reached(pop_state):
            logging.info("Goal reached. Start extraction of solution.")
            logging.info("{0} Nodes expanded, {1} Nodes evaluated".format(
                expansions, counter))
            return pop_node.extract_solution(), False

        logging.debug(
            'PrefPEA*: Expanding f={0}, h={1}, g={2}, po(n)={3}'.format(
                f, h, pop_node.g,
                len(pop_node.preferred_ops) - pop_node.preferred_ops_counter))

        if pop_node.preferred_ops_counter < len(pop_node.preferred_ops):
            # get next preferred operator, and increase the counter
            action = pop_node.preferred_ops[pop_node.preferred_ops_counter]
            pop_node.preferred_ops_counter += 1

            # generate successor (expensive!)
            succ_state, needs_restart = succ_fn(pop_state, action)
            if succ_state is None:
                if needs_restart: return [], True
                continue

            succ_node = searchspace.make_child_node(pop_node, action,
                                                    succ_state)
            if new_state(succ_node, heuristic, make_open_entry, open, pending,
                         closed):
                counter += 1
            continue

        for a in task.actions:
            if a in pop_node.preferred_ops: continue
            #logging.info( 'PrefPEA*: Generating successor through non-preferred op...' )
            succ_state, needs_restart = succ_fn(pop_state, a)
            if succ_state is None:
                if needs_restart: return [], True
                continue
            succ_node = searchspace.make_child_node(pop_node, a, succ_state)
            if new_state(succ_node, heuristic, make_open_entry, open, pending,
                         closed):
                counter += 1

        # Remove from open
        logging.debug(
            'PrefPEA*: closing f={0}, h={1}, g={2}, po(n)={3}'.format(
                pop_node.h, pop_node.h, pop_node.g,
                len(pop_node.preferred_ops) - pop_node.preferred_ops_counter))
        heapq.heappop(open)
        pending.pop(pop_state)
        closed[pop_state] = pop_node
        expansions += 1

    logging.info("No operators left. Task unsolvable.")
    logging.info("{0} Nodes expanded, {1} Nodes evaluated".format(
        expansions, counter))
    return None, False
"""
Unit Testing for the search space module
"""

from search.searchspace import make_root_node, make_child_node

# Construct a small tree in order to perform some needed test methods

root = make_root_node("state1")
child1 = make_child_node(root, "action1", "state2")
child2 = make_child_node(root, "action2", "state3")
grandchild1 = make_child_node(child1, "action3", "state4")
grandchild2 = make_child_node(child2, "action4", "state5")


def test_extract_solution():
    """
    Tests whether extract_solution method within class searchspace returns the
    list of actions starting from the root
    """
    assert root.extract_solution() == []
    assert grandchild1.extract_solution() == ["action1", "action3"]
    assert grandchild2.extract_solution() == ["action2", "action4"]


def test_g_values():
    """
    Tests whether the distance of the node from the root is computed properly
    """
    assert root.g == 0
    assert child1.g == 1
示例#19
0
def test_blind_heuristic_goal():
    task = _get_simple_task()
    bh = BlindHeuristic(task)
    assert bh(searchspace.make_root_node(task.goals)) == 0
示例#20
0
文件: a_star.py 项目: Gin93/111
def a_star(task, heuristic=BlindHeuristic):
	"""
	Searches for a plan in the given task using A* search.

	@param task The task to be solved
	@param heuristic  A heuristic callable which computes the estimated steps
					  from a search node to reach the goal.
	"""
	
	heap = []
	root_node = searchspace.make_root_node(task.initial_state)   # def __init__(self, state, parent, action, g):
	explored = {}
	
	
	explored [root_node.state] =  root_node.g

	counter = 1 
	heapq.heappush(heap,( root_node.g+ heuristic(root_node)  ,counter , root_node    ))
	node_expansion = 0 
	
	while (True):
		node = heapq.heappop(heap)[2]
		node_expansion = node_expansion + 1
		if task.goal_reached(node.state):
			print("------------------")
			print("node expasion:")
			print(node_expansion)
			print("------------------")
			return node.extract_solution()

		for successor in task.get_successor_states(node.state):  # pair  successor(1)  or  [1]
			succ_state = successor[1]
			succ_action = successor[0]
			

			new_node = searchspace.make_child_node(node,succ_action,succ_state)  #make_child_node(parent, action, state):

			if (succ_state in explored and explored[succ_state] > new_node.g) or (succ_state not in explored) : # reopen! 
				counter = counter + 1
				heapq.heappush(heap,( new_node.g+ heuristic(new_node) , counter ,new_node ))
				explored [succ_state] =  new_node.g
			
			
			'''
			skip = False # if the state is already in the heapq, then update it rather than push it 
			for elem in heap :  
				if elem[2].state == succ_state:
					a_counter = a_counter +1
					skip = True 
					elem[2].parent = new_node.parent
					elem[2].action = succ_action
					elem[2].g = new_node.g
			'''
			
			#if not skip:
			'''
			if succ_state not in explored:
				counter = counter + 1
				heapq.heappush(heap,( new_node.g+ heuristic(new_node) , counter ,new_node ))
				explored [succ_state] =  new_node.g
			'''

			
	'''
	def find(heap, f):
		""" Returns some item n from the queue such that f(n) == True and None 
			if there is no such item. 
			(PriorityQueue, (object) -> object/None) -> object
		"""
		for elem in heap:
			if f(elem[2]):
				return elem[2]
		return None
		
	def change_priority(heap, item, priority,counter):
		""" Change the priority of the given item to the specified value. If
			the item is not in the queue, a ValueError is raised.
			(PriorityQueue, object, int) -> None
		"""
		for eid, elem in enumerate(heap):
			if elem[2] == item:
				heap[eid] = (priority, count, item)
				count += 1
				heapq.heapify(heap)
				return
		raise ValueError("Error: " + str(item) + " is not in the PriorityQueue.")
	'''
			

				
				
				
				
示例#21
0

# create 4 dummy tasks
task1 = dummy_task.get_search_space_at_goal()
task2 = dummy_task.get_simple_search_space()
task3 = dummy_task.get_simple_search_space_2()
task4 = dummy_task.get_search_space_no_solution()

# call the heuristic for each task
h1 = dummy_task.DummyHeuristic(task1)
h2 = dummy_task.DummyHeuristic(task2)
h3 = dummy_task.DummyHeuristic(task3)
h4 = dummy_task.DummyHeuristic(task4)

# create root node for each task
root1 = searchspace.make_root_node(task1.initial_state)
root2 = searchspace.make_root_node(task2.initial_state)
root3 = searchspace.make_root_node(task3.initial_state)
root4 = searchspace.make_root_node(task4.initial_state)


# Testing each function if it returns the correct values


def test_ordered_node_astar1():
    h_val = h1(root1)
    assert a_star.ordered_node_astar(root1, h_val, 0) == (0, 0, 0, root1)


def test_ordered_node_astar2():
    h_val = h2(root2)
示例#22
0
"""
Unit Testing for the search space module
"""

from search.searchspace import make_root_node, make_child_node


# Construct a small tree in order to perform some needed test methods

root = make_root_node("state1")
child1 = make_child_node(root, "action1", "state2")
child2 = make_child_node(root, "action2", "state3")
grandchild1 = make_child_node(child1, "action3", "state4")
grandchild2 = make_child_node(child2, "action4", "state5")


def test_extract_solution():
    """
    Tests whether extract_solution method within class searchspace returns the
    list of actions starting from the root
    """
    assert root.extract_solution() == []
    assert grandchild1.extract_solution() == ["action1", "action3"]
    assert grandchild2.extract_solution() == ["action2", "action4"]


def test_g_values():
    """
    Tests whether the distance of the node from the root is computed properly
    """
    assert root.g == 0
import os

import py

from task import Task, Operator

import pyperplan as planner
from search import breadth_first_search, searchspace

benchmarks = os.path.abspath(
    os.path.join(os.path.abspath(__file__), '../../../benchmarks'))

# Collect problem files
problem_file = os.path.join(benchmarks, 'parcprinter', 'task01.pddl')
domain_file = planner.find_domain(problem_file)

problem = planner._parse(domain_file, problem_file)
task = planner._ground(problem)

# Manually do the "search"
node = searchspace.make_root_node(task.initial_state)
for step, op_name in enumerate(optimal_plan, start=1):
    for op, successor_state in task.get_successor_states(node.state):
        if not op.name.strip('()') == op_name:
            continue
        node = searchspace.make_child_node(node, op, successor_state)

# Check that we reached the goal
assert len(task.goals - node.state) == 0
示例#24
0
import os

import py

from task import Task, Operator

import pyperplan as planner
from search import breadth_first_search, searchspace

benchmarks = os.path.abspath(os.path.join(os.path.abspath(__file__),
                                          '../../../benchmarks'))

# Collect problem files
problem_file = os.path.join(benchmarks, 'parcprinter', 'task01.pddl')
domain_file = planner.find_domain(problem_file)

problem = planner._parse(domain_file, problem_file)
task = planner._ground(problem)

# Manually do the "search"
node = searchspace.make_root_node(task.initial_state)
for step, op_name in enumerate(optimal_plan, start=1):
    for op, successor_state in task.get_successor_states(node.state):
        if not op.name.strip('()') == op_name:
            continue
        node = searchspace.make_child_node(node, op, successor_state)

# Check that we reached the goal
assert len(task.goals - node.state) == 0