def do_next_step(self, grid_state: PuzzleState): max_ship_length = max(grid_state.missing_ships.keys()) max_length_free_line = max(grid_state.free_lines.keys()) if max_length_free_line == max_ship_length: ship_count = grid_state.missing_ships[max_ship_length] free_lines_count = sum([ len(free_lines[max_length_free_line] if max_length_free_line in free_lines else ()) for free_lines in self.relevant_free_lines_in_columns.values() ]) free_lines_count += sum([ len(free_lines[max_length_free_line] if max_length_free_line in free_lines else ()) for free_lines in self.relevant_free_lines_in_rows.values() ]) if free_lines_count > ship_count: pass elif free_lines_count == ship_count: for free_lines in self.relevant_free_lines_in_columns.values(): if max_length_free_line in free_lines: grid_state.place_ships({ max_ship_length: free_lines[max_length_free_line] }) for free_lines in self.relevant_free_lines_in_rows.values(): if max_length_free_line in free_lines: grid_state.place_ships({ max_ship_length: free_lines[max_length_free_line] }) else: raise ImpossiblePuzzleException( 'Not enough free lines for left ships!')
def do_next_step(self, puzzle_state: PuzzleState): for row, count in enumerate(puzzle_state.puzzle.counts_rows): if count == puzzle_state.current_counts_rows[row]: for column in range(puzzle_state.puzzle.columns): if puzzle_state.state[column][ row] == SlotState.EMPTY.value: puzzle_state.state[column][row] = SlotState.WATER.value
def test_compute_manhattan_distance_all(): config = [8, 7, 6, 5, 4, 3, 2, 1, 0] size = int(math.sqrt(len(config))) puzzle_state = PuzzleState(config, size) result = Utilities.compute_manhattan_distances(puzzle_state) assert result == 20
def test_compute_manhattan_distance_one(): config = [3, 1, 2, 0, 4, 5, 6, 7, 8] size = int(math.sqrt(len(config))) puzzle_state = PuzzleState(config, size) result = Utilities.compute_manhattan_distances(puzzle_state) assert result == 1
def main(): sm = sys.argv[1].lower() begin_state = sys.argv[2].split(",") begin_state = tuple(map(int, begin_state)) size = int(math.sqrt(len(begin_state))) hard_state = PuzzleState(begin_state, size) start_time = time.time() if not is_solvable(hard_state.config): exit() if sm == "bfs": goal_state, nodes, max_depth = bfs_search(hard_state, sm) write_in_file(goal_state, nodes, time.time() - start_time, max_depth) elif sm == "dfs": goal_state, nodes, max_depth = dfs_search(hard_state, sm) write_in_file(goal_state, nodes, time.time() - start_time, max_depth) elif sm == "ast": goal_state, nodes, max_depth = a_star_search(hard_state, sm) write_in_file(goal_state, nodes, time.time() - start_time, max_depth) else: print("Enter valid command arguments !")
def test_bfs_1(): config = [1, 2, 5, 3, 4, 0, 6, 7, 8] size = int(math.sqrt(len(config))) puzzle_state = PuzzleState(config, size) start_state_hash = Utilities.hashed_state(puzzle_state) start_state = puzzle_state def generate_node(node_options): return Node(**node_options) def compute_state_cost(state, state_hash): return 1 def update_stats(max_search_depth = None, increment_expanded = False): pass result = Algorithms.search( expand = Utilities.expand, goal_state_check = Utilities.goal_state_check, hashed_state = Utilities.hashed_state, compute_state_cost = compute_state_cost, update_stats = update_stats, generate_node = generate_node, start_state_hash = start_state_hash, start_state = start_state, search_type = "bfs" ) assert result.state.config == (0, 1, 2, 3, 4, 5, 6, 7, 8)
def run(self, grid_state: PuzzleState): for step in self.steps: if grid_state.puzzle.is_solved(): return step.prepare(grid_state) if self.debug: time_start = time.time() check_for_next_step = step.check_for_next_step(grid_state) print("Running step " + str(step.__class__.__name__) + ": Changes? " + str(check_for_next_step)) if check_for_next_step: step.do_next_step(grid_state) grid_state.update() grid_state.display() print("Took " + str(time.time() - time_start) + " seconds") elif step.check_for_next_step(grid_state): step.do_next_step(grid_state)
def do_next_step(self, puzzle_state: PuzzleState): changes = False for column in range(puzzle_state.puzzle.columns): if 0 < puzzle_state.currently_missing_ships_in_columns[column] \ == FillUpShips.count_slots_in_lines(puzzle_state.currently_free_lines_in_columns[column]): if not self.are_correct_ships_missing( puzzle_state, puzzle_state.currently_free_lines_in_columns[column]): continue puzzle_state.place_ships( puzzle_state.currently_free_lines_in_columns[column]) changes = True # if ships in columns were set, update the empty lines and counts # ToDo: when specific ship parts start to count, it will be important to go from longest ship to smallest if changes: puzzle_state.update() for row in range(puzzle_state.puzzle.rows): if 0 < puzzle_state.currently_missing_ships_in_rows[row] == \ FillUpShips.count_slots_in_lines(puzzle_state.currently_free_lines_in_rows[row]): if not self.are_correct_ships_missing( puzzle_state, puzzle_state.currently_free_lines_in_rows[row]): continue puzzle_state.place_ships( puzzle_state.currently_free_lines_in_rows[row])
def test_expand(): config = [1, 2, 5, 3, 4, 0, 6, 7, 8] size = int(math.sqrt(len(config))) puzzle_state = PuzzleState(config, size) result = Utilities.expand(puzzle_state, Utilities.hashed_state(puzzle_state)) first_child_direction, first_child_state = result[0] second_child_direction, second_child_state = result[1] third_child_direction, third_child_state = result[2] assert first_child_direction == "Up" assert second_child_direction == "Down" assert third_child_direction == "Left" assert first_child_state.config == (1, 2, 0, 3, 4, 5, 6, 7, 8) assert second_child_state.config == (1, 2, 5, 3, 4, 8, 6, 7, 0) assert third_child_state.config == (1, 2, 5, 3, 0, 4, 6, 7, 8)
def main(): sm = sys.argv[1].lower() begin_state = sys.argv[2].split(",") begin_state = tuple(map(int, begin_state)) size = int(math.sqrt(len(begin_state))) hard_state = PuzzleState(begin_state, size) args = { "client_defined_expand": Utilities.expand, "client_defined_goal_state_check": Utilities.goal_state_check, "client_defined_hashed_state": Utilities.hashed_state, "client_defined_compute_state_cost": Utilities.compute_state_cost, "start_state_hash": sm, "start_state": hard_state, } if sm == "bfs": result = Algorithms.search_wrapper( **args, search_type = "bfs" ) elif sm == "dfs": result = Algorithms.search_wrapper( **args, search_type = "dfs" ) elif sm == "ast": result = Algorithms.search_wrapper( **args, search_type = "astar" ) else: print("Enter valid command arguments !") Reporter.write_output(file_name = "output.txt", **result)
def test_bfs_wrapper_1(): config = [1, 2, 5, 3, 4, 0, 6, 7, 8] size = int(math.sqrt(len(config))) puzzle_state = PuzzleState(config, size) start_state_hash = Utilities.hashed_state(puzzle_state) start_state = puzzle_state result = Algorithms.search_wrapper( client_defined_expand = Utilities.expand, client_defined_goal_state_check = Utilities.goal_state_check, client_defined_hashed_state = Utilities.hashed_state, start_state_hash = start_state_hash, start_state = start_state, search_type = "bfs" ) assert result["path_to_goal"] == ["Up", "Left", "Left"] assert result["cost_of_path"] == 3 assert result["search_depth"] == 3
def test_bfs_wrapper_2(): config = [6, 1, 8, 4, 0, 2, 7, 3, 5] size = int(math.sqrt(len(config))) puzzle_state = PuzzleState(config, size) start_state_hash = Utilities.hashed_state(puzzle_state) start_state = puzzle_state result = Algorithms.search_wrapper( client_defined_expand = Utilities.expand, client_defined_goal_state_check = Utilities.goal_state_check, client_defined_hashed_state = Utilities.hashed_state, start_state_hash = start_state_hash, start_state = start_state, search_type = "bfs" ) assert result["path_to_goal"] == [ 'Down', 'Right', 'Up', 'Up', 'Left', 'Down', 'Right', 'Down', 'Left', 'Up', 'Left', 'Up', 'Right', 'Right', 'Down', 'Down', 'Left', 'Left', 'Up', 'Up' ] assert result["cost_of_path"] == 20 assert result["nodes_expanded"] == 54094 assert result["search_depth"] == 20 assert result["max_search_depth"] == 21
def test_astar_wrapper_2(): config = [8, 6, 4, 2, 1, 3, 5, 7, 0] size = int(math.sqrt(len(config))) puzzle_state = PuzzleState(config, size) start_state_hash = Utilities.hashed_state(puzzle_state) start_state = puzzle_state result = Algorithms.search_wrapper( client_defined_expand = Utilities.expand, client_defined_goal_state_check = Utilities.goal_state_check, client_defined_hashed_state = Utilities.hashed_state, client_defined_compute_state_cost = Utilities.compute_state_cost, start_state_hash = start_state_hash, start_state = start_state, search_type = "astar" ) assert result["path_to_goal"] == ['Left', 'Up', 'Up', 'Left', 'Down', 'Right', 'Down', 'Left', 'Up', 'Right', 'Right', 'Up', 'Left', 'Left', 'Down', 'Right', 'Right', 'Up', 'Left', 'Down', 'Down', 'Right', 'Up', 'Left', 'Up', 'Left'] assert result["cost_of_path"] == 26 assert result["nodes_expanded"] == 1585 assert result["search_depth"] == 26 assert result["max_search_depth"] == 26
def test_dfs_wrapper_3(): config = [8, 6, 4, 2, 1, 3, 5, 7, 0] size = int(math.sqrt(len(config))) puzzle_state = PuzzleState(config, size) start_state_hash = Utilities.hashed_state(puzzle_state) start_state = puzzle_state result = Algorithms.search_wrapper( client_defined_expand = Utilities.expand, client_defined_goal_state_check = Utilities.goal_state_check, client_defined_hashed_state = Utilities.hashed_state, start_state_hash = start_state_hash, start_state = start_state, search_type = "dfs" ) assert result["path_to_goal"][0] == "Up" assert result["path_to_goal"][1] == "Up" assert result["path_to_goal"][2] == "Left" assert result["cost_of_path"] == 9612 assert result["nodes_expanded"] == 9869 assert result["search_depth"] == 9612 assert result["max_search_depth"] == 9612
import numpy from puzzle_state import PuzzleState row = 1 col = 0 # lit = curr_state[:row]+[curr_state[row][:col]+curr_state[row][col+1:col+2]+curr_state[row][col:col+1]+curr_state[row][col+2:]]+curr_state[row+1:] # print(curr_state) # print(lit) curr_state = PuzzleState() curr_state.state = numpy.ones(shape=(4, 4)) s1 = PuzzleState() s1.state = numpy.zeros(shape=(4, 4)) s1.state = curr_state.state[:row - 1] + [ curr_state.state[row - 1][:col] + curr_state.state[row][col:col + 1] + curr_state.state[row - 1][col + 1:] ] + [ curr_state.state[row][:col] + curr_state.state[row - 1][col:col + 1] + curr_state.state[row][col + 1:] ] + curr_state.state[row + 1:] print(s1.state)
path_to_input = Path.cwd().parent / "input" / "samplePuzzles.txt" if path_to_input.exists(): with open(path_to_input) as f: puzzles = f.readlines() puzzles = [x.strip() for x in puzzles] puzzles = [[int(s) for s in puzzle.split(" ")] for puzzle in puzzles] puzzles = [[puzzle[:len(puzzle) // 2], puzzle[len(puzzle) // 2:]] for puzzle in puzzles] for count, puzzle in enumerate(puzzles): # To run the algorithm with the second heuristic, do the following: # (1) Change h1 to h2 on line 21 # (2) Change h1 to h2 on line 50 # (3) Change h1 to h2 on line 52 initial_state = PuzzleState(puzzle, None, 0, "h1") open_list = [] heapq.heappush(open_list, (initial_state.estimate, initial_state)) closed_list = [] start_time = time.clock() done = False no_solution_found = False while not done: if time.clock() - start_time > 120: done = True no_solution_found = True if not open_list: print("No solution found.") done = True else: first = heapq.heappop(open_list)
def test_goal_state_check_success(): config = [0, 1, 2, 3, 4, 5, 6, 7, 8] size = int(math.sqrt(len(config))) result = Utilities.goal_state_check(PuzzleState(config, size)) assert result == True
def main(): # Create a initial state randomly square_size = 4 init_state = PuzzleState(square_size=square_size) # dst = [1, 2, 3, # 8,-1, 6, # 7, 4, 5] dst = [1, 4, 5, 14, 2, 6, 13, 15, 11, 7, -1, 10, 8, 9, 12, 3] init_state.state = np.asarray(dst).reshape(square_size, square_size) move_list = generate_moves(100) # 起始状态是通过在目标状态上随机执行一定步数的移动指令生成,当前设置为100步 init_state.state = runs(init_state, move_list).state # Set a determined destination state dst_state = PuzzleState(square_size=square_size) dst_state.state = np.asarray(dst).reshape(square_size, square_size) # Find the path from 'init_state' to 'dst_state' move_list = astar_search_for_puzzle_problem(init_state, dst_state) move_list = convert_moves(move_list) # Perform your path if run_moves(init_state, dst_state, move_list): print_moves(init_state, move_list) print("Our dst state: ") dst_state.display() print("Get to dst state. Success !!!") else: print_moves(init_state, move_list) print("Our dst state: ") dst_state.display() print("Can not get to dst state. Failed !!!")
def test_hashed_state(): config = [0, 1, 2, 4, 3, 5, 6, 7, 8] size = int(math.sqrt(len(config))) result = Utilities.hashed_state(PuzzleState(config, size)) assert result == '0,1,2,4,3,5,6,7,8'