Python 数独生成器无限循环

问题描述 投票:0回答:1

我试图创建一个生成填充的数独网格的程序,但由于某种原因,我在生成几行后得到了一个无限循环,并且它从未输出完成的网格。每次它生成不同数量的正确行,然后一遍又一遍地重复,而不创建任何新行。

这是我的代码:

import random


def generate_sudoku():
    sudoku_grid_generated = [[0 for _ in range(9)] for _ in range(9)]
    is_valid_grid = False
    for row in range(9):
        for col in range(9):
            while True:
                i_counter = 0
                j_counter = 0
                valid_grid = 0
                generated_number = random.randint(1, 9)
                if 0 <= row <= 2 and 0 <= col <= 2:
                    if generated_number not in [sudoku_grid_generated[0][0], sudoku_grid_generated[0][1], sudoku_grid_generated[0][2],
                                                sudoku_grid_generated[1][0], sudoku_grid_generated[1][1], sudoku_grid_generated[1][2],
                                                sudoku_grid_generated[2][0], sudoku_grid_generated[2][1], sudoku_grid_generated[2][2]]:
                        if generated_number not in sudoku_grid_generated[row]:
                            i_counter += 1
                        for r in range(9):
                            if sudoku_grid_generated[r][col] != generated_number:
                                j_counter += 1

                        if i_counter == 1 and j_counter == 9:
                            sudoku_grid_generated[row][col] = generated_number
                            break
                    else:
                        continue
                elif 3 <= row <= 5 and 0 <= col <= 2:
                    if generated_number not in [sudoku_grid_generated[3][0], sudoku_grid_generated[3][1], sudoku_grid_generated[3][2],
                                                sudoku_grid_generated[4][0], sudoku_grid_generated[4][1], sudoku_grid_generated[4][2],
                                                sudoku_grid_generated[5][0], sudoku_grid_generated[5][1], sudoku_grid_generated[5][2]]:
                        if generated_number not in sudoku_grid_generated[row]:
                            i_counter += 1
                        for r in range(9):
                            if sudoku_grid_generated[r][col] != generated_number:
                                j_counter += 1
                        if i_counter == 1 and j_counter == 9:
                            sudoku_grid_generated[row][col] = generated_number
                            break
                    else:
                        continue
                elif 6 <= row <= 8 and 0 <= col <= 2:
                    if generated_number not in [sudoku_grid_generated[6][0], sudoku_grid_generated[6][1], sudoku_grid_generated[6][2],
                                                sudoku_grid_generated[7][0], sudoku_grid_generated[7][1], sudoku_grid_generated[7][2],
                                                sudoku_grid_generated[8][0], sudoku_grid_generated[8][1], sudoku_grid_generated[8][2]]:
                        if generated_number not in sudoku_grid_generated[row]:
                            i_counter += 1
                        for r in range(9):
                            if sudoku_grid_generated[r][col] != generated_number:
                                j_counter += 1
                        if i_counter == 1 and j_counter == 9:
                            sudoku_grid_generated[row][col] = generated_number
                            break

                    else:
                        continue
                elif 0 <= row <= 2 and 3 <= col <= 5:
                    if generated_number not in [sudoku_grid_generated[0][3], sudoku_grid_generated[0][4], sudoku_grid_generated[0][5],
                                                sudoku_grid_generated[1][3], sudoku_grid_generated[1][4], sudoku_grid_generated[1][5],
                                                sudoku_grid_generated[2][3], sudoku_grid_generated[2][4], sudoku_grid_generated[2][5]]:
                        if generated_number not in sudoku_grid_generated[row]:
                            i_counter += 1
                        for r in range(9):
                            if sudoku_grid_generated[r][col] != generated_number:
                                j_counter += 1
                        if i_counter == 1 and j_counter == 9:
                            sudoku_grid_generated[row][col] = generated_number
                            break

                    else:
                        continue
                elif 3 <= row <= 5 and 3 <= col <= 5:
                    if generated_number not in [sudoku_grid_generated[3][3], sudoku_grid_generated[3][4], sudoku_grid_generated[3][5],
                                                sudoku_grid_generated[4][3], sudoku_grid_generated[4][4], sudoku_grid_generated[4][5],
                                                sudoku_grid_generated[5][3], sudoku_grid_generated[5][4], sudoku_grid_generated[5][5]]:
                        if generated_number not in sudoku_grid_generated[row]:
                            i_counter += 1
                        for r in range(9):
                            if sudoku_grid_generated[r][col] != generated_number:
                                j_counter += 1
                        if i_counter == 1 and j_counter == 9:
                            sudoku_grid_generated[row][col] = generated_number
                            break

                    else:
                        continue
                elif 3 <= row <= 5 and 6 <= col <= 8:
                    if generated_number not in [sudoku_grid_generated[3][6], sudoku_grid_generated[3][7], sudoku_grid_generated[3][8],
                                                sudoku_grid_generated[4][6], sudoku_grid_generated[4][7], sudoku_grid_generated[4][8],
                                                sudoku_grid_generated[5][6], sudoku_grid_generated[5][7], sudoku_grid_generated[5][8]]:
                        if generated_number not in sudoku_grid_generated[row]:
                            i_counter += 1
                        for r in range(9):
                            if sudoku_grid_generated[r][col] != generated_number:
                                j_counter += 1
                        if i_counter == 1 and j_counter == 9:
                            sudoku_grid_generated[row][col] = generated_number
                            break

                    else:
                        continue
                elif 0 <= row <= 2 and 6 <= col <= 8:
                    if generated_number not in [sudoku_grid_generated[0][6], sudoku_grid_generated[0][7], sudoku_grid_generated[0][8],
                                                sudoku_grid_generated[1][6], sudoku_grid_generated[1][7], sudoku_grid_generated[1][8],
                                                sudoku_grid_generated[2][6], sudoku_grid_generated[2][7], sudoku_grid_generated[2][8]]:
                        if generated_number not in sudoku_grid_generated[row]:
                            i_counter += 1
                        for r in range(9):
                            if sudoku_grid_generated[r][col] != generated_number:
                                j_counter += 1
                        if i_counter == 1 and j_counter == 9:
                            sudoku_grid_generated[row][col] = generated_number
                            break

                    else:
                        continue
                elif 3 <= row <= 5 and 6 <= col <= 8:
                    if generated_number not in [sudoku_grid_generated[3][6], sudoku_grid_generated[3][7], sudoku_grid_generated[3][8],
                                                sudoku_grid_generated[4][6], sudoku_grid_generated[4][7], sudoku_grid_generated[4][8],
                                                sudoku_grid_generated[5][6], sudoku_grid_generated[5][7], sudoku_grid_generated[5][8]]:
                        if generated_number not in sudoku_grid_generated[row]:
                            i_counter += 1
                        for r in range(9):
                            if sudoku_grid_generated[r][col] != generated_number:
                                j_counter += 1
                        if i_counter == 1 and j_counter == 9:
                            sudoku_grid_generated[row][col] = generated_number
                            break

                    else:
                        continue
                elif 6 <= row <= 8 and 6 <= col <= 8:
                    if generated_number not in [sudoku_grid_generated[6][6], sudoku_grid_generated[6][7], sudoku_grid_generated[6][8],
                                                sudoku_grid_generated[7][6], sudoku_grid_generated[7][7], sudoku_grid_generated[7][8],
                                                sudoku_grid_generated[8][6], sudoku_grid_generated[8][7], sudoku_grid_generated[8][8]]:
                        if generated_number not in sudoku_grid_generated[row]:
                            i_counter += 1
                            print(i_counter)
                        for r in range(9):
                            if sudoku_grid_generated[r][col] != generated_number:
                                j_counter += 1
                        if i_counter == 1 and j_counter == 9:
                            sudoku_grid_generated[row][col] = generated_number
                            break

                    else:
                        continue
                for rows in range(9):
                    for cols in range(9):
                        if sudoku_grid_generated[rows][cols] != 0:
                            valid_grid += 1
                if valid_grid == 81:
                    is_valid_grid = True
                if is_valid_grid:
                    break
                for p in sudoku_grid_generated:
                    print(p)
    for p in sudoku_grid_generated:
        print(p)

generate_sudoku()

我该如何解决?

python infinite-loop sudoku
1个回答
0
投票

您的代码的主要问题是它陷入无法找到单元格有效数字的情况。这会导致无限循环。为了修复它,我们需要实现一个回溯算法来生成一个有效的数独网格。

这是实现回溯的代码的修改版本:

import random

def is_valid(grid, row, col, num):
    for i in range(9):
        if grid[row][i] == num or grid[i][col] == num:
            return False
    box_row = (row // 3) * 3
    box_col = (col // 3) * 3
    for i in range(box_row, box_row + 3):
        for j in range(box_col, box_col + 3):
            if grid[i][j] == num:
                return False
    return True

def generate_sudoku_helper(grid, row, col):
    if row == 9:
        return True
    if col == 9:
        return generate_sudoku_helper(grid, row + 1, 0)
    if grid[row][col] != 0:
        return generate_sudoku_helper(grid, row, col + 1)

    nums = list(range(1, 10))
    random.shuffle(nums)

    for num in nums:
        if is_valid(grid, row, col, num):
            grid[row][col] = num
            if generate_sudoku_helper(grid, row, col + 1):
                return True
    grid[row][col] = 0
    return False

def generate_sudoku():
    sudoku_grid_generated = [[0 for _ in range(9)] for _ in range(9)]
    generate_sudoku_helper(sudoku_grid_generated, 0, 0)
    return sudoku_grid_generated

def print_sudoku(grid):
    for row in grid:
        print(row)

sudoku = generate_sudoku()
print_sudoku(sudoku)

generate_sudoku
函数初始化一个空的 9x9 网格,并调用
generate_sudoku_helper
函数使用回溯法用有效的数独数字填充它。
print_sudoku
函数用于以可读格式打印生成的数独网格。

当你运行代码时,它会生成一个有效的数独网格并打印出来。回溯算法确保代码不会陷入无限循环,因为如果它到达无效状态,它将回溯并尝试不同的数字。

© www.soinside.com 2019 - 2024. All rights reserved.