簡體   English   中英

在python中更改列表中的變量(回溯)

[英]Changing variables inside a list in python (backtracking)

我正在嘗試使用 python 解決數獨謎題,因為我使用的是 3D 列表,數獨板的 2 維和 3 維來存儲板上的更改,並且能夠在給定的單元格不能時回溯填充。 我已經編寫了一些代碼,但遇到了一個我無法弄清楚的問題,每當程序為 3D 列表中的單元格分配一個數字時,它也會更改其他單元格中的數字。 我的代碼如下:

import math


def square_id(grid, ni, nj):
    if ni >= 9:
        return ("the matrix doesn't have the right size or component doesn't exist")
    elif nj >= 9:
        return ("the matrix doesn't have the right size or component doesn't exist")
    elif ni < 3:
        if nj < 3:
            return 1
        elif nj < 6:
            return 2
        elif nj < 9:
            return 3
    elif ni < 6:
        if nj < 3:
            return 4
        elif nj < 6:
            return 5
        elif nj < 9:
            return 6
    elif ni < 9:
        if nj < 3:
            return 7
        elif nj < 6:
            return 8
        elif nj < 9:
            return 9


def sudo_rules(grid, ni, nj):
    if grid[ni][nj] == 0:
        return False
    for i in range(0, 9):
        if grid[i][nj] == grid[ni][nj] and i != ni:
            return False
    for j in range(0, 9):
        if grid[ni][j] == grid[ni][nj] and j != nj:
            return False
    for i in range(0, 3):
        for j in range(0, 3):
            k = square_id(grid, ni, nj)
            l = int(math.ceil(k / 3)) - 1
            c = k % 3 - 1
            if c == -1:
                c = 2
            if grid[3 * l + i][3 * c + j] == grid[ni][nj] and 3 * c + j != nj and 3 * l + i != ni:
                return False


grid0 = [[0, 0, 0, 6, 0, 0, 0, 8, 0],
        [0, 4, 0, 0, 0, 0, 0, 2, 0],
        [5, 0, 0, 0, 9, 0, 4, 0, 6],
        [0, 5, 0, 2, 0, 0, 7, 0, 1],
        [9, 0, 0, 0, 0, 3, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 4, 0],
        [0, 0, 1, 0, 2, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 8],
        [0, 7, 0, 1, 0, 0, 6, 0, 5]]

grid= []
pos = []
for i in range(0, 30):
    grid.append([[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, 0],
                 [0, 0, 0, 0, 0, 0, 0, 0, 0]])
    pos.append([1, 0, 0])

grid[0]=grid0

k = 0
i = 0
j = 0
n = 1

while i < 9:
    if j == 9:
        j = 0
    while j < 9:
        if sudo_rules(grid[k], i, j) == False:
            while n < 11:
                if n == 10:
                    break
                print(k, i, j)
                print("grid[0]:", grid[0])
                grid[k][i][j] = n
                print("grid[0]:", grid[0])
                print("grid[1]:", grid[1])
                if sudo_rules(grid[k], i, j) != False:
                    pos[k] = [n, i, j]
                    n = 1
                    grid[k + 1] = grid[k]
                    k = k + 1
                    break
                n = n + 1
                if k==1:
                    exit()
        if n == 10:
            break
        j = j + 1
    i = i + 1
    if n == 10:
        print(grid[0])
        k = k - 1
        n = pos[k][0] + 1
        i = pos[k][1]
        j = pos[k][2]

for i in range(0, 9):
    for j in range(0, 9):
        if sudo_rules(grid[k], i, j) == False:
            print("Wrong")
            break

我的問題在這一行:

                print(k, i, j)
                print("grid[0]:", grid[0])
                grid[k][i][j] = n
                print("grid[0]:", grid[0])
                print("grid[1]:", grid[1])

我不明白為什么改變 grid[1][0][1] 也會改變 grid[0][0][1]。 任何幫助將不勝感激,謝謝

這一行:

grid[k + 1] = grid[k]

看起來您希望它創建網格的副本,但它只是將分配給grid[k]的相同網格也分配給grid[k + 1]

如果您需要某個對象的副本,您可以使用copy()deepcopy() ,具體取決於數據結構。

你的問題是這個聲明:

grid[k + 1] = grid[k]

這不會復制網格。 這僅存儲對 SAME 網格的另一個引用。 通過任一元素更改都會更改一個網格。 注意grid[k+1] = grid[k][:]是不夠的; 這將創建一個新行列表,但該列表中的行仍將包含對舊行的引用。 您將不得不使用deepcopy

但是,將您在每一步所做的動作疊加起來會更有效。 這使得回溯變得容易,並且您可以通過掃描一組移動輕松地在回溯后重新創建網格。

然而,另一種方法是,用蠻力解決數獨並不是真正“解決”它們。 我相信你必須制作 9!x9! 嘗試次數,約為 1310 億次。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM