繁体   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