保存时间:2026/3/29 16:24:20
numpy用于矩阵计算,scipy用于泰勒展开,无需深度学习框架)import numpy as np
# 原始问题X(固定不变)
X = np.array([
[1, 0, 0, 2],
[0, 3, 1, 0],
[0, 1, 3, 0],
[2, 0, 0, 1]
])
def is_valid(S, num, row, col):
# 检查行、列、2×2宫格是否重复
return (num not in S[row]) and (num not in S[:, col]) and (num not in S[row//2*2:row//2*2+2, col//2*2:col//2*2+2])
def recursive_solve(S):
# 找到第一个空白格(0的位置)
empty = np.where(S == 0)
if len(empty[0]) == 0:
return S # 终止条件:无空白格,返回解
row, col = empty[0][0], empty[1][0]
# 筛选候选数字(满足约束R)
candidates = [num for num in [1,2,3,4] if is_valid(S, num, row, col)]
if not candidates:
return None # 无解(简化实验,暂不考虑)
# 填充第一个候选数字(简化逻辑,优先验证可行性)
S[row][col] = candidates[0]
return recursive_solve(S) # 递归调用,上一轮输出作为下一轮输入
# 测试递归函数:获取终止状态S_final(正确解)
S_final = recursive_solve(X.copy())
print("正确解S_final:")
print(S_final)
scipy现成工具计算导数:from scipy.misc import derivative
# 先将4×4矩阵扁平化为16维向量(方便计算)
def flatten(S):
return S.flatten()
def unflatten(vec):
return vec.reshape(4,4)
# 定义“误差函数”E(Sₙ):空白格数量(E=0时为S_final)
def error(S_vec):
S = unflatten(S_vec)
return np.sum(S == 0)
# 递归函数F(Sₙ)转化为向量输入(适配泰勒展开)
def F_vec(S_vec):
S = unflatten(S_vec)
S_next = recursive_solve(S.copy()) # 调用第二步的递归函数
return flatten(S_next) if S_next is not None else S_vec
# 在S_final(扁平化为向量)附近做泰勒展开,取前3项
S_final_vec = flatten(S_final)
# 计算0阶系数a₀=F(S_final)
a0 = F_vec(S_final_vec)
# 计算1阶导数(误差下降速率),得到系数a₁
a1 = derivative(F_vec, S_final_vec, dx=1e-6) # dx为微小增量
# 计算2阶导数(速率变化率),得到系数a2
a2 = derivative(F_vec, S_final_vec, dx=1e-6, n=2) / 2 # 除以2!
# 泰勒展开逼近公式:F(Sₙ) ≈ a0 + a1·(Sₙ - S_final_vec) + a2·(Sₙ - S_final_vec)²
def taylor_approx(S_vec):
delta = S_vec - S_final_vec
return a0 + a1 * delta + a2 * delta **2
# 用初始状态S₀的向量做逼近
S0_vec = flatten(X)
taylor_result_vec = taylor_approx(S0_vec)
# 四舍五入为整数(数独只能是1-4),得到逼近解
taylor_result = np.round(taylor_result_vec).astype(int)
taylor_result = unflatten(taylor_result)
# 对比准确率(简化为“与正确解的差异数”)
diff = np.sum(np.abs(taylor_result - S_final))
accuracy = (16 - diff) / 16 # 16为总格子数
print("泰勒展开逼近解:")
print(taylor_result)
print(f"\n与正确解的差异数:{diff}")
print(f"准确率:{accuracy:.2%}")