def test_bfs(): from numpy import array from search import best_first_graph_search, manhattan_dist from environment import Lightworld, expand_state maze_string2 = """\ 111111111 1 1 1 1 1 1 1 1 1 1 1 1 1 11 1 1 1 1 1111111 1 1 1 111111111""" def arr_from_str(string): return array([[1 if z=='1' else 0 for z in l] for l in string.split('\n')]) structure = arr_from_str(maze_string2) h = len(structure[0]) w = len(structure) print structure goal = (w-2, h-2) expand_state_partial = lambda s: expand_state(structure, s) manhattan_dist_partial = lambda s: manhattan_dist(s, goal) print best_first_graph_search((1,1), goal, manhattan_dist_partial, expand_state_partial)
def solve_problem(problem): solved = 0 try: t_delta = time.time() p = ex1.create_bomberman_problem(problem) t_delta = time.time() - t_delta print "Initialization took %s seconds." %t_delta except Exception as e: print "Error creating problem: ", e return None timeout = 100 - t_delta result = check_problem(p, (lambda p: search.best_first_graph_search(p, p.h)), timeout) if type(result) == 'list' and result[1] > 0: result[1] += t_delta print "GBFS", result if result[2] != None: solved = solved + 1 #result = check_problem(p, search.astar_search, timeout) #print "A* ", result #result = check_problem(p, search.breadth_first_graph_search, timeout) #print "BFSg ", result #result = check_problem(p, search.breadth_first_tree_search, timeout) #print "BFSt ", result #result = check_problem(p, search.depth_first_graph_search, timeout) #print "DFSg ", result #result = check_problem(p, search.depth_first_tree_search, timeout) #print "DFSt ", result #result = check_problem(p, search.iterative_deepening_search, timeout) print "GBFS Solved ", solved
def solve_problem(problem): solved = 0 try: t_delta = time.time() p = ex1.create_bomberman_problem(problem) t_delta = time.time() - t_delta print "Initialization took %s seconds." % t_delta except Exception as e: print "Error creating problem: ", e return None timeout = 60 - t_delta result = check_problem(p, (lambda p: search.best_first_graph_search(p, p.h)), timeout) if type(result) == 'list' and result[1] > 0: result[1] += t_delta print "GBFS", result if result[2] != None: solved = solved + 1 #result = check_problem(p, search.astar_search, timeout) #print "A* ", result #result = check_problem(p, search.breadth_first_graph_search, timeout) #print "BFSg ", result #result = check_problem(p, search.breadth_first_tree_search, timeout) #print "BFSt ", result #result = check_problem(p, search.depth_first_graph_search, timeout) #print "DFSg ", result #result = check_problem(p, search.depth_first_tree_search, timeout) #print "DFSt ", result #result = check_problem(p, search.iterative_deepening_search, timeout) print "GBFS Solved ", solved
def astar_search(problem, h=None): """A* search is best-first graph search with f(n) = g(n)+h(n). You need to specify the h function when you call astar_search, or else in your Problem subclass.""" h = memoize(h or problem.h, 'h') return search.best_first_graph_search(problem, lambda n: n.path_cost + h(n))
def solve_sokoban_elem(warehouse): ''' This function should solve using elementary actions the puzzle defined in a file. @param warehouse: a valid Warehouse object @return If puzzle cannot be solved return the string 'Impossible' If a solution was found, return a list of elementary actions that solves the given puzzle coded with 'Left', 'Right', 'Up', 'Down' For example, ['Left', 'Down', Down','Right', 'Up', 'Down'] If the puzzle is already in a goal state, simply return [] ''' def heuristic(node): # Using Manhattan Distance for heuristics nodeState = node.state warehouseFromNode = sokoban.Warehouse() warehouseFromNode.extract_locations(nodeState) warehouseTargets = warehouseFromNode.targets warehouseTargetsCount = len(warehouseTargets) warehouseBoxes = warehouseFromNode.boxes warehouseWorker = warehouseFromNode.worker heuristicValue = 0 for warehouseBox in warehouseBoxes: totalBoxDistance = 0 aSquared = abs(warehouseBox[0] - warehouseWorker[0]) bSquared = abs(warehouseBox[1] - warehouseWorker[1]) workerDistanceToBox = (aSquared + bSquared)**0.5 for warehouseTarget in warehouseTargets: aSquared = abs(warehouseBox[0] - warehouseTarget[0]) bSquared = abs(warehouseBox[1] - warehouseTarget[1]) manhattanDistanceSingleBox = (aSquared + bSquared)**0.5 totalBoxDistance += manhattanDistanceSingleBox heuristicValue += (totalBoxDistance / warehouseTargetsCount) + ( workerDistanceToBox * warehouseTargetsCount) return heuristicValue puzzle = SokobanPuzzle(warehouse) puzzle.macro = False searchResult = search.best_first_graph_search(puzzle, heuristic) if searchResult is None: return ['Impossible'] result = [] for node in searchResult.path(): if node.action is not None: result.append(node.action) return result
def measure_formation_closeness(formation, board): problem = FormationProblem(formation, board) def f(current_node): return sum(abs(s - formation[i]) for i, s in enumerate(current_node.state)) node = best_first_graph_search(problem, f) return node.path_cost if node.solution() else 0.0
def decode(self, ciphertext): """Search for a decoding of the ciphertext.""" self.ciphertext = canonicalize(ciphertext) # reduce domain to speed up search self.chardomain = {c for c in self.ciphertext if c != ' '} problem = PermutationDecoderProblem(decoder=self) solution = search.best_first_graph_search( problem, lambda node: self.score(node.state)) solution.state[' '] = ' ' return translate(self.ciphertext, lambda c: solution.state[c])
def decode(self, ciphertext): """Search for a decoding of the ciphertext.""" self.ciphertext = canonicalize(ciphertext) # reduce domain to speed up search self.chardomain = {c for c in self.ciphertext if c is not ' '} problem = PermutationDecoderProblem(decoder=self) solution = search.best_first_graph_search( problem, lambda node: self.score(node.state)) solution.state[' '] = ' ' return translate(self.ciphertext, lambda c: solution.state[c])
def solve_problems(problems): solved = 0 for problem in problems: try: p = ex1.create_wumpus_problem(problem) except Exception as e: print("Error creating problem: ", e) return None timeout = 60 result = check_problem( p, (lambda p: search.best_first_graph_search(p, p.h)), timeout) print("GBFS ", result) if result[2] != None: if result[0] != -3: solved = solved + 1
def choose_action(self, env, state): if self.room != state.r: self.room = state.r self.plan = None pos = (state.x, state.y) if self.plan is None or pos not in self.plan: priority_func = lambda s: manhattan_dist(s, env.goal) expand_partial = lambda s: expand_state(env.states, s) self.plan = search.best_first_graph_search(pos, env.goal, priority_func, expand_partial) for i, pathpos in enumerate(self.plan): if i == len(self.plan)-1: #print 'choose random option in door plan' return np.array([choice(env.actions)]) elif pos == pathpos: fx,fy = self.plan[i+1] dx,dy = (fx-state.x, fy-state.y) #print 'move in direction',dx,dy,'for door plan' return np.array([env.movemap[dx,dy]])
def main(): """ to run: python main.py <method> <input file> <output file> """ if (len(sys.argv) != 4): print("Wrong number of arguments. Use correct syntax:") syntax_msg() return -1 methods = {'breadth': 1, 'depth': 2, 'best': 3, 'astar': 4} if sys.argv[1] in methods: method = methods[sys.argv[1]] else: print("Wrong method. Use correct syntax:") syntax_msg() return -1 # method = 3 # stacks = readInput("inputfiles/inputN6-2.txt") stacks = readInput(sys.argv[2]) board = Board(stacks) problem = Problem(board) t0 = time.perf_counter() if method == 1: result = breadth_first_graph_search(problem) elif method == 2: result = depth_first_graph_search(problem) # result = profile.runctx( # "depth_first_graph_search(problem)", globals(), locals()) elif method == 3: result = best_first_graph_search(problem, lambda n: n.h_cost) # result = profile.runctx( # "best_first_graph_search(problem, lambda n: n.h_cost)", globals(), locals()) elif method == 4: result = astar_search(problem) t1 = time.perf_counter() print("Time: ", t1 - t0) if result: writeToFile(sys.argv[3], result.solution()) # writeToFile("output.txt", result.solution()) else: print("Could not solve problem")
def choose_action_parameterized(self, env, state, field, action): if self.room != state.r: self.room = state.r self.plan = None pos = (state.x, state.y) if self.plan is None or pos not in self.plan: key_pos = filter_states(env.states, field) # Not positive if this is right move here. if not key_pos: #print 'RANDOM action for plan', action return np.array([choice(env.actions)]) priority_func = lambda s: manhattan_dist(s, key_pos[0]) expand_partial = lambda s: expand_state(env.states, s) self.plan = search.best_first_graph_search(pos, key_pos[0], priority_func, expand_partial) for i, pathpos in enumerate(self.plan): if i == len(self.plan)-1: #print 'action', action, 'for plan', field return np.array([action]) elif pos == pathpos: fx,fy = self.plan[i+1] dx,dy = (fx-state.x, fy-state.y) #print 'move', dx,dy, 'for plan', field return np.array([env.movemap[dx,dy]])
def solve_problems(problem): solved = 0 print "PROBLEM: " definitions = ("Drivers:", "Trucks:", "Packages:", "Locations:", "Links:", "Paths:", "Starting positions:", "Goal:") to_print = zip(definitions, problem) for row in to_print: for c in row: print c, print try: p = ex1.create_driverlog_problem(problem) except Exception as e: print "Error creating problem: ", e return None timeout = 60 result = check_problem(p, (lambda p: search.best_first_graph_search(p, p.h)), timeout) print "GBFS ", result if result[2] != None: solved = solved + 1 result = check_problem(p, search.astar_search, timeout) print "A* ", result # result = check_problem(p, search.breadth_first_graph_search, timeout) # print "BFSg ", result # result = check_problem(p, search.breadth_first_tree_search, timeout) # print "BFSt ", result # result = check_problem(p, search.depth_first_graph_search, timeout) # print "DFSg ", result # result = check_problem(p, search.depth_first_tree_search, timeout) # print "DFSt ", result # result = check_problem(p, search.iterative_deepening_search, timeout) print "GBFS Solved ", solved
def bestFS(problem, h=None): h = memoize(h or problem.h, 'h') return search.best_first_graph_search(problem, lambda n: h(n))
def solve_sokoban_macro(warehouse): """ Solve using macro actions the puzzle defined in the warehouse passed as a parameter. A sequence of macro actions should be represented by a list M of the form [ ((r1,c1), a1), ((r2,c2), a2), ..., ((rn,cn), an) ] For example M = [ ((3,4),'Left') , ((5,2),'Up'), ((12,4),'Down') ] means that the worker first goes the box at row 3 and column 4 and pushes it left, then goes the box at row 5 and column 2 and pushes it up, and finally goes the box at row 12 and column 4 and pushes it down. @param warehouse: a valid Warehouse object @return If puzzle cannot be solved return ['Impossible'] Otherwise return M a sequence of macro actions that solves the puzzle. If the puzzle is already in a goal state, simply return [] """ # specify the goal warehouse_string = str(warehouse) goal = warehouse_string.replace("$", " ").replace(".", "*") # specify heuristic def h(n): # Perform a manhattan distance heuristic state = n.state[1] wh = sokoban.Warehouse() wh.extract_locations(state.split('\n')) num_targets = len(wh.targets) heuristic = 0 test = 1 for box in wh.boxes: # dist = 0 # for target in wh.targets: # dist+= manhattan_distance(box, target) # heuristic += (dist/num_targets) if test == 1: dist = 0 for target in wh.targets: dist += manhattan_distance(box, target) heuristic += 0.8 * (dist / num_targets) + 0.5 * manhattan_distance( warehouse.worker, box) else: dist1 = [] for target in wh.targets: dist1.append(manhattan_distance(box, target)) heuristic += 0.8 * min(dist1) + 0.5 * manhattan_distance( warehouse.worker, box) return heuristic # execute best_first_graph_search to solve the puzzle M = search.best_first_graph_search(SokobanPuzzle(warehouse_string, goal), h) # when the puzzle cannot be solved SokobanPuzzle returns 'None' if M is None: # return ['Impossible'] return ['Impossible'] # take the returned action and it's paths to get there macro_actions = M.path() # extract the action data from the node data macro_actions = [e.action for e in macro_actions] # extract the state data from the node data state_check = M.path() state_check = [b.state for b in state_check] # if no box is in the original state of the puzzle, it is in a goal state if '$' not in str(state_check[0]): # puzzle is in goal state, return [] return [] else: # return sequence of macro actions, M return macro_actions
def best_first_greedy_search(problem): return search.best_first_graph_search(problem, problem.h)
def get_next_action(self, observation): # get observation for the current state and return next action to apply (and None if no action is applicable) #observation is a dictionary with spaceship_name:number_of_laser_around it. global my_world print("my_world_is:") print(my_world) print("this is the observation:") print(observation) spaceships = my_world[0] devices = my_world[1] all_targets = my_world[2] #update spaceships and devices if there is spaceship that exploded for device in devices: if device[0] in observation: ship_name = device[0] if observation[ship_name] == -1: #ship exploded temp_list = list(devices) temp_list.remove(device) devices = tuple(temp_list) for ship in spaceships: if ship[0] in observation: ship_name = ship[0] if observation[ship_name] == -1: # ship exploded temp_list = list(spaceships) temp_list.remove(ship) spaceships = tuple(temp_list) #updated world after removing ships that exploded. important for the GBFS running in the next lines my_world = (spaceships, devices, all_targets) #all ships exploded if not devices or not spaceships: return None ########################## #running GBFS from current world p = SpaceshipProblem(my_world) timeout = 60 result = check_problem( p, (lambda p: search.best_first_graph_search(p, p.h)), timeout) print("GBFS ", result) ########################## #updating the world representation next_action = result[2][0] if next_action[0] in ("turn_on", "use", "calibrate"): self.update_my_world(next_action) return next_action #for all locations without lasers, make a tuple of their neighbors and mark them as safe - without lasers. all_neighbors = () all_neighbors = (next_action[2], ) + all_neighbors for sname, nb_lasers in observation.items(): if nb_lasers == 0: for shipname, location in spaceships: if shipname == sname: ship_all_neighbors = self.get_neighbors(location) for i in ship_all_neighbors: if i not in all_neighbors: all_neighbors = (i, ) + all_neighbors for i in all_neighbors: self.lasers_logic.tell(~(self.grid_dict[i])) #if the action is move for some ship and there isn't lasers around it, go ahead and do it. for sname, nb_lasers in observation.items(): if next_action[1] == sname and nb_lasers == 0 and next_action[ 0] == "move": self.update_my_world(next_action) return next_action #if the code is here, then the gbfs wants to move a ship with lasers around it #next_action[0] = "move", next_action[1] = ship name, next_action[2] = from, next_action[3] = to n_combinations = [] for ship_name, ship_location in spaceships: if ship_name == next_action[1]: near_by_n = self.get_neighbors(ship_location) near_by_n = (ship_location, ) + near_by_n nb_lasers = observation[ship_name] n_combinations = (itertools.combinations( list(near_by_n), len(near_by_n) - nb_lasers)) combination_list = list(n_combinations) small_combinations = (combination_list[0], combination_list[1], combination_list[2]) logic_list = [] for combination in small_combinations: temp = [] for coord in combination: temp.append(~self.grid_dict[coord]) logic_list.append(logic.associate('&', temp)) self.lasers_logic.tell(logic.associate('|', logic_list)) logic_answer = logic.dpll_satisfiable( logic.to_cnf(logic.associate('&', self.lasers_logic.clauses))) #logic answer contains a dict of Lxyz = Flase/True. when False means that the (x,y,z) location is safe, and unsafe #(contains lasers) otherwise #if "to_location" of GBFS is in logic_answer and is false - use it, #else we would like to choose a random one that is not our current location print("logic answer:", logic_answer) # gbfs_to_location = self.grid_dict[next_action[3]] # logic_answer.delete(self.grid_dict[next_action[2]]) for k, v in logic_answer.items(): if v == True: logic_answer = self.minus_key(k, logic_answer) #remove from logic answer not neighbors nears = () neighbors = self.get_neighbors(next_action[2]) for n in neighbors: temp = self.grid_dict[n] nears = (temp, ) + nears for l in logic_answer: if l not in nears: logic_answer = self.minus_key(l, logic_answer) #remove targets locations for t in all_targets: temp = self.grid_dict[t] if temp in logic_answer: logic_answer = self.minus_key(temp, logic_answer) #remove spaceships locations for ship_name, location in spaceships: temp = self.grid_dict[location] if temp in logic_answer: logic_answer = self.minus_key(temp, logic_answer) print("whats left for random: ", list(logic_answer.keys())) random_to_location = random.choice(list(logic_answer.keys())) print("random choise:", random_to_location) if not random_to_location: #empty return None #return Lxyz form to (x,y,z) new_to_location = () for k, v in self.grid_dict.items(): if v == random_to_location: new_to_location = k print("new_to_location:", new_to_location) new_next_action = ("move", next_action[1], next_action[2], new_to_location) print("new next location", new_next_action) self.update_my_world(new_next_action) return new_next_action
_,TS,_,_,_,KS,_,_ ;_,KH,_,_,_,_,_,_ ;_,QS,_,_,_,_,_,_ ;_,_,_,_,_,_,_,_ ;_,_,_,_,_,_,_,_ ;_,_,_,_,_,_,_,_ ;_,_,_,_,_,_,_,_ ;_,_,_,_,_,_,_,_ ;_,_,_,_,_,_,_,_;_,_,_,_,_,_,_,_;_,_,_,_,_,_,_,_;_,_,_,_,_,_,_,_ ;_,_,_,_,_,_,_,_;_,_,_,_,_,_,_,_;_,_,_,_,_,_,_,_;_,_,_,_,_,_,_,_ ;_,_,_,_,_,_,_,_;_,_,_,_,_,_,_,_;_,_,_,_,_,_,_,_;_,_,_,_,_,_,_,_''' ) problem = Freecell(initial=testState, debug=True) print("----------------") solution = search.best_first_graph_search(problem, heuristic, debug=True) if True: testState = FreecellState(shorthand='''JS,_,_,_:9H,9C,KD,5S: QH,6S,QC,KC,TH,TS,JC,_ ;_,KH,_,_,JH,KS,TC,_ ;_,QS,_,_,_,_,9S,_ ;_,8S,_,_,_,_,_,_ ;_,7S,_,_,_,_,_,_ ;_,_,_,_,_,_,_,_ ;_,_,_,_,_,_,_,_ ;_,_,_,_,_,_,_,_ ;_,_,_,_,_,_,_,_;_,_,_,_,_,_,_,_;_,_,_,_,_,_,_,_;_,_,_,_,_,_,_,_ ;_,_,_,_,_,_,_,_;_,_,_,_,_,_,_,_;_,_,_,_,_,_,_,_;_,_,_,_,_,_,_,_ ;_,_,_,_,_,_,_,_;_,_,_,_,_,_,_,_;_,_,_,_,_,_,_,_;_,_,_,_,_,_,_,_''' )
if node.action: (i, j, val) = node.action possibilities = list(node.state.possible_values(i, j)) return len(possibilities) - 1 return 0 choices = { 'depth_first': depth_first_tree_search, # 'best_first_uniform': uniform_cost_tree_search, 'best_first_h1': lambda x: best_first_tree_search(x, h1), 'best_first_h2': lambda x: best_first_tree_search(x, h2), 'best_first_greedy_h1': lambda x: best_first_greedy_tree_search(x, h1), 'best_first_greedy_h2': lambda x: best_first_greedy_tree_search(x, h2), 'best_first_h3': lambda x: best_first_tree_search(x, h3), 'best_first_greedy_h3': lambda x: best_first_greedy_tree_search(x, h3), 'best_first_graph_h1': lambda x: best_first_graph_search(x, h1), 'best_first_graph_h2': lambda x: best_first_graph_search(x, h2), 'hill_climbing': lambda x: hill_climbing(x), 'annealing': lambda x: simulated_annealing(x, schedule=sim) } # print(sys.argv) searchers = sys.argv[1:] lewisProblems = map(LewisSudokuProblem, sudokus) naiveProblems = map(SudokuProblem, sudokus) #csv header print("problem,searcher,explored,states,tests,solution,value") for (i, (p1, p2)) in enumerate(zip(lewisProblems, naiveProblems)): #print("Initial state:") for s in searchers:
def solve(): """Solves the puzzle using astar_search""" return best_first_graph_search(puzzle).solution()
def solve_sokoban_macro(warehouse): ''' Solve using macro actions the puzzle defined in the warehouse passed as a parameter. A sequence of macro actions should be represented by a list M of the form [ ((r1,c1), a1), ((r2,c2), a2), ..., ((rn,cn), an) ] For example M = [ ((3,4),'Left') , ((5,2),'Up'), ((12,4),'Down') ] means that the worker first goes the box at row 3 and column 4 and pushes it left, then goes to the box at row 5 and column 2 and pushes it up, and finally goes the box at row 12 and column 4 and pushes it down. @param warehouse: a valid Warehouse object @return If puzzle cannot be solved return the string 'Impossible' Otherwise return M a sequence of macro actions that solves the puzzle. If the puzzle is already in a goal state, simply return [] ''' def heuristic(node): # Using Manhattan Distance for heuristics nodeState = node.state warehouseFromNode = sokoban.Warehouse() warehouseFromNode.extract_locations(nodeState) warehouseTargets = warehouseFromNode.targets warehouseTargetsCount = len(warehouseTargets) warehouseBoxes = warehouseFromNode.boxes warehouseWorker = warehouseFromNode.worker heuristicValue = 0 for warehouseBox in warehouseBoxes: totalBoxDistance = 0 aSquared = abs(warehouseBox[0] - warehouseWorker[0]) bSquared = abs(warehouseBox[1] - warehouseWorker[1]) workerDistanceToBox = (aSquared + bSquared)**0.5 for warehouseTarget in warehouseTargets: aSquared = abs(warehouseBox[0] - warehouseTarget[0]) bSquared = abs(warehouseBox[1] - warehouseTarget[1]) manhattanDistanceSingleBox = (aSquared + bSquared)**0.5 totalBoxDistance += manhattanDistanceSingleBox heuristicValue += (totalBoxDistance / warehouseTargetsCount) * workerDistanceToBox return heuristicValue puzzle = SokobanPuzzle(warehouse) puzzle.macro = True searchResult = search.best_first_graph_search(puzzle, heuristic) if searchResult is None: return ['Impossible'] result = [] for node in searchResult.path(): if node.action is not None: result.append(node.action) return result
# Search methods import search ab = search.GPSProblem('A', 'B', search.romania) print search.breadth_first_graph_search(ab).path() print search.depth_first_graph_search(ab).path() print search.iterative_deepening_search(ab).path() print search.depth_limited_search(ab).path() #branch and bound no informed search print search.best_first_graph_search(ab, f=lambda n: n.path_cost).path() print search.branch_bound_search(ab).path() #branch and bound informed search print search.branch_bound_subestimation_search(ab).path() # Result: # [<Node B>, <Node P>, <Node R>, <Node S>, <Node A>] : 101 + 97 + 80 + 140 = 418 # [<Node B>, <Node F>, <Node S>, <Node A>] : 211 + 99 + 140 = 450