Я переписал свой Java Sudoku solver в python. Все работает, однако решение занимает до 2 минут, в то время как идентичная головоломка занимает всего несколько секунд на Java. Также итерации должны быть равны одному и тому же номеру. Я что-то упускаю?Почему переводчик Sudoku медленнее, чем оригинал?
import numpy as np
def solve_recursive(puzzle, pos):
if(pos == 81):
print puzzle
return True
if(puzzle[pos] != 0):
if (not solve_recursive(puzzle, pos+1)):
return False
else:
return True
row = np.copy(puzzle[pos//9*9:pos//9*9+9])
col = np.copy(puzzle[pos%9::9])
short = (pos%9)//3*3 + pos//27*27
square = np.concatenate((puzzle[short:short+3],puzzle[short+9:short+12],puzzle[short+18:short+21]))
for i in range(1,10):
puzzle[pos] = i
if(i not in row and i not in col and i not in square and solve_recursive(puzzle, pos+1)):
return True
puzzle[pos] = 0
return False
puzzle = np.array([[0,0,0,0,0,0,0,8,3],
[0,2,0,1,0,0,0,0,0],
[0,0,0,0,0,0,0,4,0],
[0,0,0,6,1,0,2,0,0],
[8,0,0,0,0,0,9,0,0],
[0,0,4,0,0,0,0,0,0],
[0,6,0,3,0,0,5,0,0],
[1,0,0,0,0,0,0,7,0],
[0,0,0,0,0,8,0,0,0]])
solve_recursive(puzzle.ravel(), 0)
EDIT:
Как было предложено @hpaulj я переработан код для работы с numpy's 2D массивов:
import numpy as np
def solve_recursive(puzzle, pos):
if pos == (0,9):
print puzzle
raise Exception("Solution")
if(puzzle[pos] != 0):
if(pos[0] == 8):
solve_recursive(puzzle, (0,pos[1]+1))
return
elif pos[0] < 8:
solve_recursive(puzzle, (pos[0]+1, pos[1]))
return
for i in range(1,10):
if(i not in puzzle[pos[0]] and i not in puzzle[:,pos[1]] and i not in puzzle[pos[0]//3*3:pos[0]//3*3+3,pos[1]//3*3:pos[1]//3*3+3]):
puzzle[pos] = i
if(pos[0] == 8):
solve_recursive(puzzle, (0,pos[1]+1))
elif pos[0] < 8:
solve_recursive(puzzle, (pos[0]+1, pos[1]))
puzzle[pos] = 0
puzzle = np.array([[0,0,0,0,0,0,0,8,3],
[0,2,0,1,0,0,0,0,0],
[0,0,0,0,0,0,0,4,0],
[0,0,0,6,1,0,2,0,0],
[8,0,0,0,0,0,9,0,0],
[0,0,4,0,0,0,0,0,0],
[0,6,0,3,0,0,5,0,0],
[1,0,0,0,0,0,0,7,0],
[0,0,0,0,0,8,0,0,0]])
solve_recursive(puzzle, (0,0))
Игнорируя тот факт, что метание исключение в нижней части рекурсивные вызовы довольно неэлегантные, это просто значительно быстрее, чем мое первоначальное решение. Будет ли использование словарей, таких как связанный с ним алгоритм Норвига, разумной альтернативой?
В вопросе отсутствует синтаксически корректный код python и весь код Java. –
BTW: 'if not condition: return False; else return True' - это то же самое, что и 'return condition'. (Борьба с однострочным синтаксисом py, надеюсь, вы получите эту идею). –
Просьба указать [Минимальный, полный и проверенный пример] (http://stackoverflow.com/help/mcve) – BPL