def test_agent(self): state, _, _ = cube.scramble(50) self._mcts_test(state, False) state, _, _ = cube.scramble(3) agent, sol_found = self._mcts_test(state, False) _action_queue_test(state, agent, sol_found) agent, sol_found = self._mcts_test(state, True) _action_queue_test(state, agent, sol_found)
def test_scramble(self): np.random.seed(42) state = cube.get_solved() state, faces, dirs = cube.scramble(1) assert not cube.is_solved(state) state = cube.get_solved() state, faces, dirs = cube.scramble(20) assert not cube.is_solved(state) for f, d in zip(reversed(faces), reversed([int(not item) for item in dirs])): state = cube.rotate(state, *(f, d)) assert cube.is_solved(state)
def _can_win_all_easy_games(self, agent): state, i, j = cube.scramble(2, force_not_solved=True) is_solved = agent.search(state, time_limit=1) if is_solved: for action in agent.action_queue: state = cube.rotate(state, *cube.action_space[action]) assert cube.is_solved(state)
def _eval_game(self, agent: agents.Agent, depth: int, profile: str): turns_to_complete = -1 # -1 for unfinished state, _, _ = cube.scramble(depth, True) self.tt.profile(profile) solution_found = agent.search(state, self.max_time, self.max_states) dt = self.tt.end_profile(profile) if solution_found: turns_to_complete = len(agent.action_queue) return turns_to_complete, dt
def test_expansion(self): net = Model.create(ModelConfig()).eval() init_state, _, _ = cube.scramble(3) agent = AStar(net, lambda_=0.1, expansions=5) agent.search(init_state, time_limit=1) init_idx = agent.indices[init_state.tostring()] assert init_idx == 1 assert agent.G[init_idx] == 0 for action in cube.action_space: substate = cube.rotate(init_state, *action) idx = agent.indices[substate.tostring()] assert agent.G[idx] == 1 assert agent.parents[idx] == init_idx
def generate_actions(agent: Agent, games: int, max_time: float): sequences = list() for i in range(games): actions_taken = [] state, _, _ = cube.scramble(np.random.randint(100, 1000), True) won = agent.search(state, max_time, None) if not won: log(f"Game {i+1} was not won") else: for action_num in agent.action_queue: action_tup = cube.action_space[action_num] actions_taken.append(cube.action_names[action_tup[0]].lower( ) if action_tup[1] else cube.action_names[action_tup[0]]) log(f'Actions taken: {actions_taken}') sequences.append(actions_taken) return sequences
def analyse_time_distribution(depth: int, c: float): time_limits = np.linspace(.1, 2, 10) expand = np.zeros_like(time_limits) explore = np.zeros_like(time_limits) searcher = MCTS(net, c=c, search_graph=False) log.section( f"Analyzing time distribution at depth {depth}\nExpected max time <~ {TickTock.stringify_time(sum(time_limits*n), TimeUnit.minute)}" ) for i, tl in enumerate(time_limits): log(f"Analyzing with time limit of {tl:.2f} s") sols = np.zeros(n) for j in range(n): state, f, d = cube.scramble(depth, True) sols[j] = searcher.search(state, time_limit=tl) expand[i] += sum( searcher.tt.profiles["Expanding leaves"].get_hits()) try: explore[i] += sum( searcher.tt.profiles["Exploring next node"].get_hits()) except KeyError: pass log(f"Solved {np.mean(sols)*100:.2f} % of configurations") expand /= n explore /= n expand, explore = expand / (expand + explore), explore / (expand + explore) plt.figure(figsize=(15, 10)) plt.plot(time_limits, expand * 100, "o-", label="Time spent expanding") plt.plot(time_limits, explore * 100, "o-", label="Time spent exploring") plt.legend(loc=2) plt.xlabel("Time limit [s]") plt.ylabel(f"Mean time spent over {n} runs [%]") plt.ylim([-0.05, 1.05]) # plt.semilogx() plt.grid(True) plt.savefig(f"data/local_analyses/mcts_time.png") # plt.show() plt.clf()
def _test_agents(self, agent: Agent): state, _, _ = cube.scramble(4) solution_found = agent.search(state, .05) for action in agent.action_queue: state = cube.rotate(state, *cube.action_space[action]) assert solution_found == cube.is_solved(state)
def solve(depth: int, c: float, time_limit: float): state, f, d = cube.scramble(depth, True) searcher = MCTS(net, c=c, search_graph=False) is_solved = searcher.search(state, time_limit) assert is_solved == (cube.get_solved().tostring() in searcher.indices) return is_solved, len(searcher.indices)