利用DeepSeek改写ITPUB newkid的数独求解SQL为python程序

想要评估每次取不同的位置效果,让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程序而言还可以。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值