簡體   English   中英

對於循環陷入Python

[英]For cycle gets stuck in Python

我下面的代碼被卡在一個隨機點上:

import functions
from itertools import product
from random import randrange

values = {}
tables = {}
letters = "abcdefghi"
nums = "123456789"
for x in product(letters, nums): #unnecessary
    values[x[0] + x[1]] = 0
for x in product(nums, letters): #unnecessary
    tables[x[0] + x[1]] = 0

for line_cnt in range(1,10):
    for column_cnt in range(1,10):
        num = randrange(1,10)
        table_cnt = functions.which_table(line_cnt, column_cnt) #Returns a number identifying the table considered
        #gets the values already in the line and column and table considered
        line = [y for x,y in values.items() if x.startswith(letters[line_cnt-1])]
        column = [y for x,y in values.items() if x.endswith(nums[column_cnt-1])]
        table = [x for x,y in tables.items() if x.startswith(str(table_cnt))]
        #if num is not contained in any of these then it's acceptable, otherwise find another number 
        while num in line or num in column or num in table:
            num = randrange(1,10)
        values[letters[line_cnt-1] + nums[column_cnt-1]] = num #Assign the number to the values dictionary
        print(line_cnt) #debug
print(sorted(values)) #debug

如您所見,它是一個使用2個詞典生成隨機數獨方案的程序:包含完整方案的值和包含每個表的值的表。

范例:

5th square on the first line = 3
    |
    v
values["a5"] = 3
tables["2b"] = 3

那是什么問題呢? 我想念什么嗎?

import functions
...
        table_cnt = functions.which_table(line_cnt, column_cnt) #Returns a number identifying the table considered

當我們可以在自己的計算機上直接執行代碼進行測試時,這是很好的選擇。 換句話說,將示例中的“ table_cnt”替換為固定值會很好(在這里,一個簡單的字符串就足夠了)。

for x in product(letters, nums):
    values[x[0] + x[1]] = 0

沒那么重要,但這更加優雅:

values = {x+y: 0 for x, y in product(letters, nums)}

現在,問題的核心是:

while num in line or num in column or num in table:
    num = randrange(1,10)

這是您永遠循環的地方。 因此,您正在嘗試生成隨機數獨。 從您的代碼中,這是生成隨機列表的方式:

nums = []
for _ in range(9):
    num = randrange(1, 10)
    while num in nums:
        num = randrange(1, 10)
    nums.append(num)

這種方法的問題在於您不知道程序需要多長時間才能完成。 可能需要一秒鍾或一年(盡管這不太可能 )。 這是因為不能保證程序不會一遍又一遍地選擇已經接受的號碼。

不過,實際上,它仍然需要相對較短的時間來完成(這種方法效率不高,但清單很短)。 但是,在數獨的情況下,您可能會陷入不可能的情況。 例如:

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

這些是第一行(或實際上的任何行)和最后一列。 當算法嘗試為line [8]查找值時,由於7被column阻塞,它將總是失敗。

如果要保持這種方式(又名蠻力),則應檢測到這種情況並重新開始。 再次,這是非常無效的,您應該查看如何正確生成數獨(我的幼稚方法是從一個已解決的數獨開始,然后隨機交換行和列,但是我知道這不是一個好方法)。

暫無
暫無

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

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