def random_restart(self): configuration = [['#' for _ in range(n)] for _ in range(n)] positions = [] i = 0 while i < n: x, y = randint(0, n - 1), randint(0, n - 1) if (x, y) not in positions: positions.append((x, y)) i += 1 for i, j in positions: configuration[i][j] = 'Q' board = ChessboardState(configuration) while any(board.__eq__(e) for e in self.prev_expanded_states): configuration = [['#' for _ in range(n)] for _ in range(n)] positions.clear() i = 0 while i < n: x, y = randint(0, n - 1), randint(0, n - 1) if (x, y) not in positions: positions.append((x, y)) i += 1 for i, j in positions: configuration[i][j] = 'Q' board = ChessboardState(configuration) return ChessboardStateNode(board)
def solve(self): algorithm = self.ui.algorithmComboBox.currentText() solver = None initial_state = ChessboardState(chessboard=self.chessboard) final_state = None if algorithm == "Hill Climbing": i = self.ui.paramComboBox.currentIndex() restarts_limit = int(self.ui.paramLineEdit_1.text()) solver = HillClimbingSolver(['rr', 'sa'][i], restarts_limit) final_state = solver.solve(ChessboardStateNode(initial_state)) elif algorithm == "Beam Search": k = int(self.ui.paramLineEdit_1.text()) solver = BeamSearchSolver(k) final_state = solver.solve() elif algorithm == "Genetic Algorithm": pop = int(self.ui.paramLineEdit_1.text()) gen = int(self.ui.paramLineEdit_2.text()) solver = GASolver(n_population=pop, n_generations=gen) final_state = solver.solve() elif algorithm == "CSP": solver = CSPSolver() final_state = solver.solve(initial_state) self.chessboard = [['#' for _ in range(MainWindow.n)] for _ in range(MainWindow.n)] for i, j in final_state.queen_positions: self.chessboard[i][j] = 'Q' self.refresh_chessboard() self.ui.runningTimeLineEdit.setText(str(solver.get_running_time())) self.ui.costLineEdit.setText(str(solver.get_cost())) self.ui.expandedNodesLineEdit.setText(str(solver.get_expanded_count()))
def reset_chessboard(self): s = ChessboardState(self.chessboard) self.chessboard = [['#' for _ in range(MainWindow.n)] for _ in range(MainWindow.n)] for i in range(self.ui.gridLayout.count()): pass btn = self.ui.gridLayout.itemAt(i).widget() btn.setIcon(QIcon())
def __init__(self, state=None, sequence=None): if state is not None: self.state = state self.sequence = [] for i, j in state.queen_positions: self.sequence.append(i) elif sequence is not None: self.sequence = sequence queen_positions = [] for i in range(ChessboardState.n): queen_positions.append((sequence[i], i)) self.state = ChessboardState(queen_positions=queen_positions) else: self.state = ChessboardState.random_state_one_per_col() self.sequence = [] for i, j in self.state.queen_positions: self.sequence.append(i)
def solve(self, initial_chessboard_state): # Structure: each column should contain only one queen prev_expanded = [] start_time = time.time() current_state, positions = self.get_chessboard_and_positions( initial_chessboard_state) while True: print("Current state #attacks =", current_state.get_attacking_count()) current_state.print_chessboard() last_cost = current_state.get_attacking_count() if last_cost == 0: self.final_sol = current_state break positions = self.heuristic_move(positions) current_state = ChessboardState(queen_positions=positions) # while any(current_state.__eq__(x) for x in prev_expanded): # positions = self.heuristic_move(positions) # current_state = ChessboardState(queen_positions=positions) self.expanded_count += 1 prev_expanded.append(current_state) if last_cost == current_state.get_attacking_count( ): # local optima print("--- Local Optima ---") positions = self.random_move(positions) current_state = ChessboardState(queen_positions=positions) while any(current_state.__eq__(x) for x in prev_expanded): positions = self.random_move(positions) current_state = ChessboardState(queen_positions=positions) self.expanded_count += 1 prev_expanded.append(current_state) last_cost = current_state.get_attacking_count() else: last_cost = current_state.get_attacking_count() self.steps_count += 1 end_time = time.time() self.execution_time = end_time - start_time return self.final_sol
class ChessboardChromosome: state: ChessboardState sequence: list def __init__(self, state=None, sequence=None): if state is not None: self.state = state self.sequence = [] for i, j in state.queen_positions: self.sequence.append(i) elif sequence is not None: self.sequence = sequence queen_positions = [] for i in range(ChessboardState.n): queen_positions.append((sequence[i], i)) self.state = ChessboardState(queen_positions=queen_positions) else: self.state = ChessboardState.random_state_one_per_col() self.sequence = [] for i, j in self.state.queen_positions: self.sequence.append(i) def fitness(self): return 1.0 / (1 + self.state.get_attacking_count()) def __lt__(self, other): assert isinstance(other, ChessboardChromosome) return self.state.get_attacking_count( ) < other.state.get_attacking_count() def __eq__(self, other): assert isinstance(other, ChessboardChromosome) return self.sequence == other.sequence
def solve(self): self.start_time = time.time() # Initial random fringe with k states fringe = [ChessboardStateNode(ChessboardState.random_state_one_per_col()) for _ in range(self.k)] explored = set() while fringe[0].cost() > 0: self.depth += 1 new_fringe = [] for node in fringe: if node in explored: continue self.expanded_count += 1 explored.add(node) for child in node.neighbors(): if child not in explored: new_fringe.append(child) fringe = nsmallest(self.k, new_fringe) self.end_time = time.time() return fringe[0].chessboard_state
def get_chessboard_and_positions(self, chessboard): positions = [x for x in chessboard.queen_positions] invalid = False cols = [False for i in range(n)] for i in range(n): if cols[positions[i][1]]: invalid = True for j in range(n): if not cols[j]: positions[i] = (positions[i][0], j) cols[j] = True break else: cols[positions[i][1]] = True if invalid: configuration = [['#' for _ in range(n)] for _ in range(n)] for i, j in positions: configuration[i][j] = 'Q' board = ChessboardState(configuration, positions) return board, positions else: return chessboard, positions
from algorithms.beam_search_solver import BeamSearchSolver from algorithms.ga_solver import GASolver from algorithms.csp_solver import CSPSolver from algorithms.hill_climbing_solver import HillClimbingSolver from chessboard.chessboard_state_node import ChessboardStateNode from ui.main_window import MainWindow import sys from file_io import read_config, write_config from chessboard.chessboard_state import ChessboardState if __name__ == '__main__': # pass initial_config = read_config('input2.txt') state = ChessboardState(initial_config) # state.print_chessboard() ga_solver = GASolver(n_population=8) final_state = ga_solver.solve() final_state.print_chessboard() print(final_state.get_attacking_count()) print(ga_solver.get_running_time(), ga_solver.get_expanded_count(), ga_solver.get_cost()) csp = CSPSolver() csp.solve(state) print("Number steps to the final solution =", csp.get_cost()) csp.final_sol.print_chessboard() print("Expanded node count =", csp.get_expanded_count()) print("Execution time in milliseconds =", csp.get_running_time())