下面的代码卡在随机点上:
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
那么问题是什么?我错过了什么吗?
答案 0 :(得分:2)
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]
这些是第一行(或实际的任何行)和最后一列。当算法试图找到第[8]行的值时,它将始终失败,因为7被column
阻止。
如果你想保持这种方式(也就是蛮力),你应该发现这种情况并重新开始。再次,这是非常低效的,你应该看看如何正确生成sudokus(我天真的方法是从一个解决的方法开始,随机交换行和列,但我知道这不是一个好方法)。