想要评估每次取不同的位置效果,让DeepSeek改写数独求解SQL为python程序
把附件的穷举法改写成python,递归查询的每步结果只保留最新的一份,编写成循环接收已知点数状态字符串的版本,输出结果同时输出迭代次数和生成中间结果总行数,不做别的
他第一次给出的程序有错误,而且十分低效,对于每行中间结果都计算下一个位置。我给他指出:
按照sql的逻辑,计算下一个位置只有在while states:中计算一次即可,另外你计算的 new_next_pos 是0开始的索引,需要+1,修改如下:
new_next_pos=-1
# 查找下一个空位置
remaining_str = states[0]['s'][states[0]['next_pos']:]
next_dot_pos = remaining_str.find('.')
if next_dot_pos == -1:
new_next_pos = 0
else:
new_next_pos = states[0]['next_pos'] + next_dot_pos+1,
另外每次在循环for ap in all_pos:中搜索
if ap['pos'] == state['next_pos']:非常低效,改成字典,请实现这个思路,不做别的
他给出了如下程序
def solve_sudoku_bfs():
# 初始化数独字符串
b = '9......4..5..2........1......69..1........5.24..7......1....3.....6...9....4.....'
# 生成数字序列
digits = [str(i) for i in range(1, 10)]
# 生成网格位置信息
grid = []
for lp in range(1, 82):
pos = lp
r = (lp - 1) // 9
c = (lp - 1) % 9
g = (lp - 1) // 9 // 3 * 3 + (lp - 1) % 9 // 3
grid.append({'pos': pos, 'r': r, 'c': c, 'g': g})
# 生成所有可能的位置和数字组合,并按位置分组
all_pos_dict = {}
for grid_item in grid:
pos = grid_item['pos']
all_pos_dict[pos] = []
for n in range(1, 10):
r_bit = 1 << (grid_item['r'] * 9 + n - 1)
c_bit = 1 << (grid_item['c'] * 9 + n - 1)
g_bit = 1 << (grid_item['g'] * 9 + n - 1)
all_pos_dict[pos].append({
'n': n,
'r': r_bit,
'c': c_bit,
'g': g_bit
})
# 初始化状态队列
initial_rs = 0
initial_cs = 0
initial_gs = 0
# 计算初始状态的二进制位
for pos in range(1, 82):
if b[pos - 1] != '.':
n = int(b[pos - 1])
for ap in all_pos_dict[pos]:
if ap['n'] == n:
initial_rs |= ap['r']
initial_cs |= ap['c']
initial_gs |= ap['g']
break
# 查找第一个空位置
next_pos = b.find('.') + 1
if next_pos == 0: # 没有找到点号
next_pos = 0
# 初始状态
states = [{
's': b,
'rs': initial_rs,
'cs': initial_cs,
'gs': initial_gs,
'next_pos': next_pos
}]
total_iterations = 0
total_states_generated = 1 # 初始状态
# BFS循环
while states:
total_iterations += 1
# 计算下一个位置(只在循环开始时计算一次)
new_next_pos = -1
if states[0]['next_pos'] > 0:
remaining_str = states[0]['s'][states[0]['next_pos']:]
next_dot_pos = remaining_str.find('.')
if next_dot_pos == -1:
new_next_pos = 0
else:
new_next_pos = states[0]['next_pos'] + next_dot_pos + 1
new_states = []
for state in states:
if state['next_pos'] == 0:
# 找到解
print(f"迭代次数: {total_iterations}")
print(f"生成中间结果总行数: {total_states_generated}")
return state['s']
# 使用字典直接获取当前位置的所有可能数字
current_pos_options = all_pos_dict[state['next_pos']]
for ap in current_pos_options:
# 检查约束条件
if (state['rs'] & ap['r']) == 0 and \
(state['cs'] & ap['c']) == 0 and \
(state['gs'] & ap['g']) == 0:
# 生成新状态
new_s = state['s'][:state['next_pos'] - 1] + str(ap['n']) + state['s'][state['next_pos']:]
# 更新二进制位
new_rs = state['rs'] | ap['r']
new_cs = state['cs'] | ap['c']
new_gs = state['gs'] | ap['g']
new_states.append({
's': new_s,
'rs': new_rs,
'cs': new_cs,
'gs': new_gs,
'next_pos': new_next_pos
})
total_states_generated += 1
# 只保留最新的一批状态(BFS的下一层)
states = new_states
print("未找到解")
return None
# 运行求解器
if __name__ == "__main__":
result = solve_sudoku_bfs()
if result:
print(f"数独解: {result}")
# 格式化输出
print("\n格式化输出:")
for i in range(0, 81, 9):
row = result[i:i+9]
formatted_row = ' '.join(row)
print(formatted_row)
执行结果
time python3 dspy2.txt
迭代次数: 65
生成中间结果总行数: 2394439
数独解: 932567841157824963648319725576982134893146572421753689714298356285631497369475218
格式化输出:
9 3 2 5 6 7 8 4 1
1 5 7 8 2 4 9 6 3
6 4 8 3 1 9 7 2 5
5 7 6 9 8 2 1 3 4
8 9 3 1 4 6 5 7 2
4 2 1 7 5 3 6 8 9
7 1 4 2 9 8 3 5 6
2 8 5 6 3 1 4 9 7
3 6 9 4 7 5 2 1 8
real 0m7.247s
user 0m6.880s
sys 0m0.344s
虽然不太快,对于穷举的python程序而言还可以。


被折叠的 条评论
为什么被折叠?



