def testQueens ( self, n = 8 ): initial = () cost = lambda x, y : 1 def goal ( board ): return len(board) == n def successor ( board ): def attacks ( q1, q2 ): return q1[0]==q2[0] or q1[1]==q2[1] or abs(q1[0]-q2[0]) == abs(q1[1]-q2[1]) result = [] for col in range(len(board), n): for row in range(n): new_queen = (row, col) hostiles = [q for q in board if attacks(new_queen, q)] if len(hostiles) == 0: nxt_board = board + (new_queen,) result.append(nxt_board) return tuple(result) problem = Problem(initial, goal, successor, cost) solver = ProblemSolver() solver.solve(problem, ProblemSolver.depthFirstGenerator(successor), True) self.assertTrue(solver.solved(problem)) print("N queens, solution found using depth-first search: " + str(solver.solution[-1])) print("Algorithm performance: ", solver.performance, ", memory used: ", solver.resources)
def testMissionariesAndCannibals(self): initial = ((3,3), (0,0)) goal = ((0,0), (3,3)) cost = lambda x, y : 1 def successor ( s ): mis = lambda b: b[0] can = lambda b: b[1] ouch = lambda a: mis(a) > 0 and can(a) > 0 and mis(a) != can(a) def trip(a, b, a_to_b): if mis(a_to_b) > mis(a) or can(a_to_b) > can(a): # check physical limits raise Exception("Not enough people!") nxt_a = (mis(a) - mis(a_to_b), can(a) - can(a_to_b)) if ouch(nxt_a): # discard fail a->b trips raise Exception("Holocaust!") nxt_b = (mis(b) + mis(a_to_b), can(b) + can(a_to_b)) return nxt_a, nxt_b result = [] a, b = s[0], s[1] boat_floats = ((0,0), (1,0), (2,0), (1,1), (0,1), (0,2)) for a_to_b in boat_floats: try: tmp_a, tmp_b = trip(a, b, a_to_b) except: continue for b_to_a in filter(lambda b_to_a: b_to_a != a_to_b, boat_floats): try: nxt_b, nxt_a = trip(tmp_b, tmp_a, b_to_a) except: continue if not ouch(nxt_a): # discard wrong b->a trips result.append((nxt_a, nxt_b)) return result problem = Problem(initial, goal, successor, cost) solver = ProblemSolver() solver.solve(problem, ProblemSolver.depthFirstGenerator(successor), True) self.assertTrue(solver.solved(problem)) print("M&C, solution found using depth-first search: " + str(solver.solution)) print("Algorithm performance: ", solver.performance, ", memory used: ", solver.resources)
def testProblem(self): initial = 1 successor = lambda x : (2*x, 2*x + 1) cost = lambda x, y : 1 goal = 8 # goal must be on the leftmost branch of the tree!! problem = Problem(initial, goal, successor, cost) solver = ProblemSolver() solver.solve(problem, ProblemSolver.depthFirstGenerator(successor)) self.assertTrue(solver.solved(problem)) self.assertEqual( solver.solution, [1, 2, 4, 8], "Solution found using depth-first search is " + str(solver.solution)) goal = 10 problem = Problem(initial, goal, successor, cost) solver = ProblemSolver() solver.solve(problem, ProblemSolver.breadthFirstGenerator(successor)) self.assertTrue(solver.solved(problem)) self.assertEqual( solver.solution, [1, 2, 5, 10], "Solution found using breadth-first search is " + str(solver.solution)) goal = 10 problem = Problem(initial, goal, successor, cost) solver = ProblemSolver() solver.solve(problem, ProblemSolver.depthLimitedGenerator(successor, 4)) self.assertTrue(solver.solved(problem)) self.assertEqual( solver.solution, [1, 2, 5, 10], "Solution found using depth-limited search is " + str(solver.solution)) goal = 10 problem = Problem(initial, goal, successor, cost) solver = ProblemSolver() solver.solve(problem, ProblemSolver.iterativeDeepeningGenerator(successor)) self.assertTrue(solver.solved(problem)) self.assertEqual( solver.solution, [1, 2, 5, 10], "Solution found using IDDF search is " + str(solver.solution)) goal = 10 successor = \ lambda x: (random() < 0.5 and (2*x, 2*x + 1)) \ or (max(1, int(x/2)), 2*x, 2*x + 1) problem = Problem(initial, goal, successor, cost) solver = ProblemSolver() solver.solve(problem, ProblemSolver.breadthFirstGenerator(successor), True) self.assertTrue(solver.solved(problem)) self.assertEqual( solver.solution, [1, 2, 5, 10], "Solution found using breadth-first *graph* search is " + str(solver.solution)) goal = 32 successor = \ lambda x: (random() < 0.5 and (2*x, 2*x + 1)) \ or (max(1, int(x/2)), 2*x, 2*x + 1) problem = Problem(initial, goal, successor, cost) solver = ProblemSolver() solver.solve(problem, ProblemSolver.iterativeDeepeningGenerator(successor), True) self.assertTrue(solver.solved(problem)) self.assertEqual( solver.solution, [1, 2, 4, 8, 16, 32], "Solution found using IDDF *graph* search is " + str(solver.solution))