#return states[0] n = 4 m = 4 x = 0 y = 0 x = 1 matrix = [[" " for j in range(m)] for i in range(n)] for i in range(n): for j in range(m): matrix[i][j] = x x = x + 1 matrix[n - 1][m - 1] = " " start_state = Node(matrix, 0, None) num = randint(0, 100) print("The maximum number of moves required = " + str(num)) for i in range(num): states = start_state.generate_successors() shuffle(states) start_state = Node(states[0].matrix, 0, None) #matrix = [[1,2,3,4],[5,6,12,7],[9,10," ",11],[13,14,15,8]] #start_state = Node(matrix, 0,None) start_state.print_matrix() curr_state = start_state frontier = []
def MLA(maze, agent, reserved, start_wait=0, resting=[]): """Returns a list of tuples as a path from the given start to the given end in the given maze""" # Initialize both open and closed list open_list = [] closed_list = set() print(start_wait) # Last label belongs to end node and is equal to number of waypoints + 1. Eg. 2 for an agent with 1 waypoint. final_label = len(agent.waypoints) + 1 waypoint_label = 1 start_node = Node(None, agent.start) start_node.g = start_node.h = start_node.f = 0 if start_wait > 0: open_list.append(construct_wait(start_node, 0, start_wait - 1)) else: # Add the start node open_list.append(start_node) # If we have waypoints, create waypoint node and set it to be the first waypoint. if final_label > 1: waypoint = Node(None, agent.waypoints[0]) waypoint.g = waypoint.h = waypoint.f = 0 # Else we have no waypoints and set the label to -1. else: waypoint_label = -1 # mid_node = Node(None, agent.waypoints[0]) # mid_node.g = mid_node.h = mid_node.f = 0 end_node = Node(None, agent.end) end_node.g = end_node.h = end_node.f = 0 # Loop until you find the end while len(open_list) > 0: # Get the current node current_node = heappop(open_list) closed_list.add(current_node) if current_node.position != agent.end and current_node.position in resting: if len(open_list) > 0: continue # TODO Do more efficiently. Checks if this space is reserved to avoid swap conflicts. if current_node.position in reserved and current_node.g + 1 in reserved[ current_node.position]: continue # Found the waypoint if current_node.l == waypoint_label and current_node == waypoint: # Waypoint is now the next waypoint. if current_node.l < len(agent.waypoints): waypoint = Node(None, agent.waypoints[current_node.l]) else: waypoint = Node(None, (-1, -1)) # N_prime is the new search node, which has the same position as the current node, but with new label and new h. n_prime = Node(current_node.parent, current_node.position) n_prime.g = current_node.g n_prime.h = compute_h(current_node.l - 1, agent.waypoints, end_node) n_prime.f = n_prime.g + n_prime.h n_prime.l = waypoint_label + 1 waypoint_label += 1 closed_list = set() open_list = [] heappush(open_list, n_prime) continue if current_node.l == final_label and current_node == end_node: path = [] current = current_node while current is not None: path.append(current) current = current.parent return path[::-1] # Return reversed path # Loop through children collision = False for child in map( lambda x: Node(current_node, x), maze.get_neighbours(current_node.position[0], current_node.position[1])): if child.position in reserved and current_node.g + 1 in reserved[ child.position]: collision = True # Check if we can wait here. If not we dont consider this step. if current_node.position in reserved and current_node.g + 1 in reserved[ child.position]: break # We can wait, so add a node to wait and then move into that position. elif child.position in reserved and current_node.g + 2 in reserved[ child.position]: break else: wait = Node(current_node, current_node.position) wait.g = current_node.g + 1 wait_move = Node(wait, child.position) wait_move.g = current_node.g + 2 if child.l != final_label: wait_move.h = abs( child.position[0] - waypoint.position[0]) + abs( child.position[1] - waypoint.position[1]) + compute_h( child.l - 1, agent.waypoints, end_node) else: wait_move.h = abs(child.position[0] - end_node.position[0]) + abs( child.position[1] - end_node.position[1]) wait_move.f = wait_move.g + wait_move.f heappush(open_list, wait_move) for child in map( lambda x: Node(current_node, x), maze.get_neighbours(current_node.position[0], current_node.position[1])): # TODO USE HASHSET if child.position in reserved and current_node.g + 1 in reserved[ child.position]: continue # In case of collision # Child is on the closed list if child in closed_list: continue if child in open_list: continue # Create the f, g, and h values child.g = current_node.g + 1 child.l = current_node.l if child.l != final_label: child.h = abs(child.position[0] - waypoint.position[0]) + abs( child.position[1] - waypoint.position[1]) + compute_h( child.l - 1, agent.waypoints, end_node) else: child.h = abs(child.position[0] - end_node.position[0]) + abs(child.position[1] - end_node.position[1]) child.f = child.g + child.h # Add the child to the open list heappush(open_list, child) if start_wait == 0: return MLA(maze, agent, reserved, 1, resting) else: return MLA(maze, agent, reserved, start_wait * 2, resting)
def test_full_binary_tree(self): # 1 1 # / \ / \ # 2 3 ----> 0 3 # / / \ / \ # 0 9 4 9 4 root = Node(1, Node(2, Node(0)), Node(3, Node(9), Node(4))) expected_str_output = "1\n03\n94" self.assertEqual(str(full_binary_tree(root)), expected_str_output) # 1 1 # / \ / \ # 3 2 ----> 3 4 # / \ \ / \ # 0 9 4 0 9 root = Node(1, Node(3, Node(0), Node(9)), Node(2, right=Node(4))) expected_str_output = "1\n34\n09" self.assertEqual(str(full_binary_tree(root)), expected_str_output) # 1 3 # / ----> # 3 root = Node(1, Node(3)) expected_str_output = "3" self.assertEqual(str(full_binary_tree(root)), expected_str_output) # 1 3 # \ ----> # 3 root = Node(1, right=Node(3)) expected_str_output = "3" self.assertEqual(str(full_binary_tree(root)), expected_str_output)
def test_values_at_height(self): root = Node(1) self.assertEqual(values_at_height(root, 1), [1]) root = Node(1, Node(2), Node(3)) self.assertEqual(values_at_height(root, 2), [2, 3]) root = Node(1, Node(3)) self.assertEqual(values_at_height(root, 2), [3]) root = Node(1, Node(2), Node(3)) self.assertEqual(values_at_height(root, 5), []) root = Node(1, Node(2, Node(4), Node(5)), Node(3, right=Node(7))) self.assertEqual(values_at_height(root, 3), [4, 5, 7])
def test_remove_middle(self): head = Node(1, Node(2, Node(3, Node(4, Node(5))))) self.assertEqual(str(head), "[1, 2, 3, 4, 5]") head = remove_kth_last(head, 3) self.assertEqual(str(head), "[1, 2, 4, 5]")
def test_level_order(self): root = Node(1, Node(2), Node(3, Node(4), Node(5))) self.assertEqual(level_order(root), [1, 2, 3, 4, 5]) root = Node(1, right=Node(3, right=Node(5))) self.assertEqual(level_order(root), [1, 3, 5]) root = Node(1, left=Node(2, left=Node(4))) self.assertEqual(level_order(root), [1, 2, 4]) root = Node(1) self.assertEqual(level_order(root), [1]) root = None self.assertEqual(level_order(root), [])
def test_is_bst(self): root = Node(5, Node(1), Node(4, Node(3), Node(6))) self.assertFalse(is_bst(root)) root = Node(5, Node(3, Node(2), Node(4)), Node(7, Node(6), Node(8))) self.assertTrue(is_bst(root)) root = Node(0) self.assertTrue(is_bst(root)) root = Node(2, Node(1)) self.assertTrue(is_bst(root)) root = Node(2, right=Node(3)) self.assertTrue(is_bst(root))