不完全な数独グリッドを解析して補完する方法


  1. バックトラッキング: バックトラッキングは、深さ優先探索を用いて解を探索する手法です。数独グリッドの各セルを順番に試し、ルールに従って数字を配置していきます。不正な配置が行われた場合にはバックトラックし、別の数字を試します。このプロセスを繰り返すことで、可能な解を見つけることができます。

以下は、バックトラッキングを使用して不完全な数独グリッドを補完するためのPythonコード例です。

def solve_sudoku(grid):
    if is_complete(grid):
        return grid

    row, col = find_empty_cell(grid)

    for num in range(1, 10):
        if is_valid_move(grid, row, col, num):
            grid[row][col] = num

            if solve_sudoku(grid):
                return grid

            grid[row][col] = 0

    return None
def is_complete(grid):
    for row in grid:
        if 0 in row:
            return False
    return True
def find_empty_cell(grid):
    for row in range(9):
        for col in range(9):
            if grid[row][col] == 0:
                return row, col
    return None
def is_valid_move(grid, row, col, num):
    # 行に重複しないかチェック
    if num in grid[row]:
        return False

    # 列に重複しないかチェック
    for i in range(9):
        if grid[i][col] == num:
            return False

    # 3x3のボックスに重複しないかチェック
    box_row = (row // 3) * 3
    box_col = (col // 3) * 3
    for i in range(3):
        for j in range(3):
            if grid[box_row + i][box_col + j] == num:
                return False

    return True

以下は、Z3を使用して不完全な数独グリッドを補完するためのPythonコード例です。

from z3 import *
def solve_sudoku(grid):
    solver = Solver()

    # 数独グリッドの各セルに制約条件を設定
    cells = [[Int(f"cell_{i}_{j}") for j in range(9)] for i in range(9)]

    for i in range(9):
        for j in range(9):
            if grid[i][j] == 0:
                solver.add(And(cells[i][j] >= 1, cells[i][j] <= 9))
            else:
                solver.add(cells[i][j] == grid[i][j])

    # 各行に同じ数字が現れない制約を追加
    for i in range(9):
        solver.add(Distinct(cells[i]))

    # 各列に同じ数字が現れない制約を追加
    for j in range(9):
        solver.add(Distinct([cells[i][j] for i in range(9)]))

    # 各3x3のボックスに同じ数字が現れない制約を追加
    for i in range(0, 9, 3):
        for j in range(0, 9, 3):
            solver.add(Distinct([cells[row][col] for row in range(i, i+3) for col in range(j, j+3)]))

    if solver.check() == sat:
        model = solver.model()
        solution = [[model.evaluate(cells[i][j]).as_long() for j in range(9)] for i in range(9)]
        return solution

    return None