Skip to content
Snippets Groups Projects
Commit 8caf06a5 authored by Michael Mutote's avatar Michael Mutote
Browse files

22202956

optimised successors function for sudoku to use the most complete row, column or sub-square
Added helper functions for selecting next position to solve for sudoku
Heuristics for Sudoku updated and tested for A*, works but slow, 30 seconds
parent e28116c3
No related branches found
No related tags found
No related merge requests found
import is_goal
import Sucessors
......@@ -16,21 +17,9 @@ def puzzle_opt(path):
def sudoku_opt(path):
# state = path[-1]
# box_value, row_value, col_value = 0, 0, 0
# # check each box to see the least empty
# for down in range(0, 9, 3):
# for across in range(0, 9, 3):
# box_value += 9 - ()
# box_value = 0
#
# # check each row for the one with the least zeros
# row_value = 0
#
# # check each column for the one with the least zeros
# col_value = 0
pass
starting_point = [Sucessors.choose_best_subsquare(path[-1]), Sucessors.choose_best_rows(path[-1]),
Sucessors.choose_best_column(path[-1])]
return max(starting_point, key=lambda w: w[2])[-1]
def queens_opt(path):
......
......@@ -34,7 +34,6 @@ def DepthFirstSearch(state, successor, isgoal):
if next_state not in explored:
explored.add(next_state)
path2 = path + [next_state]
print(path2)
toDo.append(path2)
return "Error Path not found"
......
......@@ -9,11 +9,8 @@ def maze_successor(state):
def sudoku_successor(state):
new_state = list(map(list, state)) # Convert state to a list of lists
y, x = -1, -1
for i, s in enumerate(state):
if 0 in s:
(y, x) = (i, s.index(0))
break
starting_point = [choose_best_subsquare(new_state), choose_best_rows(new_state), choose_best_column(new_state)]
x, y, dummy = max(starting_point, key=lambda w: w[2])
next_states = []
for j in range(1, len(new_state) + 1):
new_state[y][x] = j
......@@ -22,45 +19,6 @@ def sudoku_successor(state):
return next_states
def maze_allowed(state):
maze = [[' ', 'W', ' ', ' ', 'G'],
[' ', 'W', ' ', 'W', ' '],
[' ', 'W', ' ', ' ', ' '],
[' ', ' ', 'W', 'W', ' '],
[' ', ' ', ' ', ' ', ' ']]
if state[0] >= len(maze[0]) or state[0] < 0:
return False
if state[1] >= len(maze) or state[1] < 0:
return False
return maze[state[0]][state[1]] == ' ' or maze[state[0]][state[1]] == 'G'
def sudoku_allowed(state):
(y, x, grid) = state
"""I'm making the state a triple on this one"""
# (y, x, z): x,y is the coordinate and z is the value in the square
# check if still inside the box
if y < 0 or y >= len(grid[0]):
return False
if x < 0 or x >= len(grid):
return False
# inspect columns and rows
if ([row[x] for row in grid].count(grid[y][x]) > 1) or (grid[y].count(grid[y][x]) > 1):
return False
# inspect minor square in teh sudoku
inner_x = ((x - (x % 3)), (x - (x % 3) + 3))
inner_y = (y - (y % 3))
inner_square = grid[inner_y][inner_x[0]:inner_x[1]] + grid[inner_y + 1][inner_x[0]:inner_x[1]] + \
grid[inner_y + 2][inner_x[0]:inner_x[1]]
if inner_square.count(grid[y][x]) > 1:
return False
return True
def puzzle_successor(state):
y, x = -1, -1
for i in range(len(state)):
......@@ -103,10 +61,52 @@ def queens_successor(state):
return next_states
# Allowed moves Functions
def puzzle_allowed(state):
return True
def maze_allowed(state):
maze = [[' ', 'W', ' ', ' ', 'G'],
[' ', 'W', ' ', 'W', ' '],
[' ', 'W', ' ', ' ', ' '],
[' ', ' ', 'W', 'W', ' '],
[' ', ' ', ' ', ' ', ' ']]
if state[0] >= len(maze[0]) or state[0] < 0:
return False
if state[1] >= len(maze) or state[1] < 0:
return False
return maze[state[0]][state[1]] == ' ' or maze[state[0]][state[1]] == 'G'
def sudoku_allowed(state):
(y, x, grid) = state
"""I'm making the state a triple on this one"""
# (y, x, z): x,y is the coordinate and z is the value in the square
# check if still inside the box
if y < 0 or y >= len(grid[0]):
return False
if x < 0 or x >= len(grid):
return False
# inspect columns and rows
if ([row[x] for row in grid].count(grid[y][x]) > 1) or (grid[y].count(grid[y][x]) > 1):
return False
# inspect minor square in teh sudoku
inner_x = ((x - (x % 3)), (x - (x % 3) + 3))
inner_y = (y - (y % 3))
inner_square = grid[inner_y][inner_x[0]:inner_x[1]] + grid[inner_y + 1][inner_x[0]:inner_x[1]] + \
grid[inner_y + 2][inner_x[0]:inner_x[1]]
if inner_square.count(grid[y][x]) > 1:
return False
return True
def queens_allowed(state):
"""in this case the state is also y, x, grid"""
y, x, grid = state
......@@ -137,3 +137,49 @@ def queens_allowed(state):
return False
return True
# Helper Functions
def choose_best_rows(grid):
best_row = -1
x = -1
min_empty = len(grid)
for i in range(len(grid)):
empty_cells = grid[i].count(0)
if 0 < empty_cells < min_empty:
best_row = i
min_empty = empty_cells
x = grid[i].index(0)
return x, best_row, min_empty
def choose_best_column(grid):
best_col = -1
y = -1
min_empty = len(grid)
for i in range(len(grid)):
col = [row[i] for row in grid]
empty_cells = col.count(0)
if 0 < empty_cells < min_empty:
best_col = i
min_empty = empty_cells
y = col.index(0)
return best_col, y, min_empty
def choose_best_subsquare(grid):
x = -1
y = -1
best_val = len(grid)
for down in range(0, 9, 3):
for across in range(0, 9, 3):
subsquare = [grid[i][across: across + 3] for i in range(down, down + 3)]
zeros = sum([subsquare[i].count(0) for i in range(len(subsquare))])
if 0 < zeros < best_val:
best_val = zeros
for j in range(len(subsquare)):
if 0 in subsquare[j]:
x = across + subsquare[j].index(0)
y = down + j
break
return (x, y, best_val)
......@@ -5,26 +5,29 @@ import Heuristics
# Maze Problem, note, the maze is fixed in the allowed state.
# print(Search_Algorithms.BreadthFirstSearch((4, 0), Sucessors.maze_successor, is_goal.is_goal_maze))
print(Search_Algorithms.BreadthFirstSearch((4, 0), Sucessors.maze_successor, is_goal.is_goal_maze))
# Sudoku
grid = ((1, 0, 0, 0, 0, 0, 0, 0, 0),
(0, 0, 0, 0, 0, 0, 0, 0, 0),
(0, 0, 0, 0, 0, 0, 0, 0, 0),
(0, 0, 0, 0, 0, 0, 0, 0, 0),
(0, 0, 0, 0, 0, 0, 0, 0, 0),
(0, 0, 0, 0, 0, 0, 0, 0, 0),
(0, 0, 0, 0, 0, 0, 0, 0, 0),
(0, 0, 0, 0, 0, 0, 0, 0, 0),
grid = ((5, 3, 0, 0, 7, 0, 0, 0, 0),
(6, 0, 0, 1, 9, 5, 0, 0, 0),
(0, 9, 8, 0, 0, 0, 0, 6, 0),
(8, 0, 0, 0, 6, 0, 0, 0, 3),
(4, 0, 0, 8, 0, 3, 0, 0, 1),
(7, 0, 0, 0, 2, 0, 0, 0, 6),
(0, 6, 0, 0, 0, 0, 2, 8, 0),
(0, 0, 0, 4, 1, 9, 0, 0, 5),
(0, 0, 0, 0, 8, 0, 0, 0, 0))
# sln = (Search_Algorithms.BreadthFirstSearch(grid, Sucessors.sudoku_successor, is_goal.is_goal_sudoku)[-1])
sln = (Search_Algorithms.BreadthFirstSearch(grid, Sucessors.sudoku_successor, is_goal.is_goal_sudoku)[-1])
# sln = (Search_Algorithms.DepthFirstSearch(
# grid, Sucessors.sudoku_successor, is_goal.is_goal_sudoku)[-1])
for rows in sln:
print(rows)
print("--------------------------------")
sln = (Search_Algorithms.DepthFirstSearch(
grid, Sucessors.sudoku_successor, is_goal.is_goal_sudoku)[-1])
#
# for rows in sln:
# print(rows)
for rows in sln:
print(rows)
# N Queens
board = ((False, False, False, False, False, False, False, False, False),
......@@ -38,15 +41,15 @@ board = ((False, False, False, False, False, False, False, False, False),
(False, False, False, False, False, False, False, False, False))
# sln = (Search_Algorithms.BreadthFirstSearch(board, Sucessors.queens_successor, is_goal.is_goal_queens)[-1])
#
sln = (Search_Algorithms.BreadthFirstSearch(board, Sucessors.queens_successor, is_goal.is_goal_queens)[-1])
# sln = (Search_Algorithms.DepthFirstSearch(
# board, Sucessors.queens_successor, is_goal.is_goal_queens)[-1])
#
# output_tuple = tuple(tuple("Q" if value else "." for value in sln)
# for sln in sln)
# for rows in output_tuple:
# print(rows)
output_tuple = tuple(tuple("Q" if value else "." for value in sln)
for sln in sln)
for rows in output_tuple:
print(rows)
# Sliding Puzzle
......@@ -55,14 +58,14 @@ initial_puzzle = (
(5, 0, 6),
(8, 3, 1)
)
#
# sln = (Search_Algorithms.BreadthFirstSearch(initial_puzzle, Sucessors.puzzle_successor, is_goal.is_goal_puzzle)[-1])
#
# if sln:
# for rows in sln:
# print(rows)
# else:
# print("No solution found")
sln = (Search_Algorithms.BreadthFirstSearch(initial_puzzle, Sucessors.puzzle_successor, is_goal.is_goal_puzzle)[-1])
if sln:
for rows in sln:
print(rows)
else:
print("No solution found")
#
# sln = (Search_Algorithms.DepthFirstSearch(initial_puzzle, Sucessors.puzzle_successor, is_goal.is_goal_puzzle)[-1])
......@@ -73,7 +76,13 @@ initial_puzzle = (
# else:
# print("No solution found")
print(Search_Algorithms.A_StarSearch((4, 0), Sucessors.maze_successor, is_goal.is_goal_maze, Heuristics.maze_opt))
# print(Search_Algorithms.A_StarSearch((4, 0), Sucessors.maze_successor, is_goal.is_goal_maze, Heuristics.maze_opt))
sln = (Search_Algorithms.A_StarSearch(grid, Sucessors.sudoku_successor,
is_goal.is_goal_sudoku, Heuristics.sudoku_opt))[-1]
for rows in sln:
print(rows)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment