又快又脏,但有效:
将 numpy 导入为 np
导入数学
N = 3
# 重写 https://www.tutorialspoint.com/valid-sudoku-in-python
def isValidSudoku(M):
'''
检查数独矩阵:
一个 9x9 数独矩阵是有效的,当且仅当:
行包含 1 - 9 和
col 包含 1 - 9 和
3x3 包含 1 - 9
0 用于空白条目
'''
对于范围内的 i (9):
行 = {}
col = {}
块 = {}
row_cube = N * (i//N)
col_cube = N * (i%N)
对于范围内的 j (N*N):
如果 M[i][j] != 0 并且 M[i][j] 在行中:
返回假
行[M[i][j]] = 1
如果 M[j][i] != 0 和 M[j][i] 在 col:
返回假
科尔[M[j][i]] = 1
rc = row_cube + j//N
cc = col_cube + j%N
如果 M[rc][cc] 在块中并且 M[rc][cc] != 0:
返回假
块[M[rc][cc]]=1
返回真
def generate_sudoku_puzzles(run_size, 种子):
order = int(math.sqrt(run_size))
计数 = 0
有效 = 0
空= []
np.random.seed(seed) # 获得可重复的结果
对于范围内的 k(顺序):
对于 l 在范围内(顺序):
A = np.fromfunction(lambda i, j: ((k*i + l+j) % (N*N)) + 1, (N*N, N*N), dtype=int)
B = np.random.randint(2, size=(N*N, N*N))
empty.append(np.count_nonzero(B))
C = A*B
计数 += 1
如果是有效数独(C):
有效 += 1
最后 = C
# print('C(',k,l,') 是有效的数独:')
# print(C) # 取消对拼图的注释
print('Tried', count, 'valid', valid, 'yield', round(valid/count, 3)*100, '%', '平均线索', round(sum(empty)/len(empty)) )
返回(最后)
posTest = np.array([(0, 7, 0, 0, 4, 0, 0, 6, 0), \
(3, 0, 0, 5, 0, 7, 0, 0, 2), \
(0, 0, 5, 0, 0, 0, 3, 0, 0), \
(0, 4, 0, 3, 0, 6, 0, 5, 0), \
(6, 0, 0, 0, 0, 0, 0, 0, 8), \
(0, 1, 0, 2, 0, 8, 0, 3, 0), \
(0, 0, 7, 0, 0, 0, 4, 0, 0), \
(1, 0, 0, 8, 0, 2, 0, 0, 9), \
(0, 6, 0, 0, 9, 0, 0, 1, 0), \
])
negTest = np.array([(0, 7, 0, 0, 4, 0, 0, 6, 2), \
(3, 0, 0, 5, 0, 7, 0, 0, 2), \
(0, 0, 5, 0, 0, 0, 3, 0, 0), \
(0, 4, 0, 3, 0, 6, 0, 5, 0), \
(6, 0, 0, 0, 0, 0, 0, 0, 8), \
(0, 1, 0, 2, 0, 8, 0, 3, 0), \
(0, 0, 7, 0, 0, 0, 4, 0, 0), \
(1, 0, 0, 8, 0, 2, 0, 0, 9), \
(0, 6, 0, 0, 9, 0, 0, 1, 0), \
])
print('阳性质量控制测试:', isValidSudoku(posTest))
print('阴性质量控制测试:', isValidSudoku(negTest))
打印(generate_sudoku_puzzles(10000, 0))
输出:
阳性质量控制测试:正确
阴性质量控制测试:错误
尝试 10000 有效 31 收益率 0.3 % 平均线索 40
[[0 0 2 3 0 0 0 7 8]
[7 8 9 1 2 0 0 0 0]
[5 0 0 0 9 0 0 3 0]
[0 0 0 6 7 8 0 0 2]
[0 2 0 0 0 0 7 8 9]
[8 0 0 2 3 0 0 0 0]
[0 0 0 0 0 2 3 0 5]
[0 5 6 0 8 9 1 2 0]
[0 3 0 5 0 0 0 9 0]]
取消对拼图来源的两行注释。