python实现的nonogram自动解答器

希望得到优化的方法

项目分为两个文件:

        1. sudoku.py用于接受题目输入以及输出一个表示答案的二维数组

        2. plt_show会接受这个二维数组并将其可视化

可以接受任意矩形的题目输入,且不需要输入其它参数

只能解决存在每一步迭代都存在确定解的情况

对于小规模的题目,例如30x30,完成计算通常只需要小于一秒的时间

        对于大规模的题目,例如50x50,可能会需要超过20分钟的计算时间,且参与计算的列表

all_sequences体积可能达到几十G,所以对于大型题目(max_size > Storage_mode_threshold)

通过硬盘存储中间变量而不直接使用内存:

            if max_size <= Storage_mode_threshold:
                all_sequences.append(result)
            else:
                np.save(f'save/{file_counter}_{segment}.npy', result)
                file_counter += 1
                del result
                gc.collect()

运行逻辑是:

1. 计算每一行和列所有可能的答案排列

2. 将每一行和列从answer中取出作为master,将该行或列所有排列作为作为slaves

    清洗slaves中与不与master重叠的组合(比如answer为真,而slaves为假则剔除)

    将清洗过后的所有slaves逻辑与,结果为真的项则答案(answer)在此项为真

                          所有slaves逻辑或,结果为假的项则答案在此项为假

    将清洗过的slaves覆盖原slaves,剪枝

3.将确定的目标写入答案中,缩小解空间。判断答案中是否还有未知项,若有,则继续迭代

4.将答案(answer)可视化

 sudoku.py

import numpy as np
import plt_show
import time
import gc

rows = [
    [3, 3, 2, 2], [1, 3, 1, 2], [6, 1], [2, 3, 1, 1, 3], [3, 4, 1, 7],
    [3, 4, 3, 5], [4, 5, 3, 6], [3, 4, 6, 3], [4, 11, 3, 1], [5, 2, 7],
    [9, 7], [3, 9, 10], [2, 4, 3, 7], [2, 1, 3, 6, 2], [1, 5, 1, 3, 2],
    [2, 3, 1, 1, 2], [6, 6, 2], [4, 1, 8, 1, 2], [8, 7, 1, 1], [5, 6, 3, 1, 2],
    [3, 12, 3, 1, 1], [17, 1, 7], [2, 4, 8, 10], [6, 3, 7, 2], [3, 2, 3, 4, 1, 2],
    [5, 2, 4], [4, 3, 1, 2], [4, 3, 2, 5], [3, 3, 1, 5], [7, 3, 7]
]
columns = [
    [1, 1, 4, 3], [3, 1, 1, 4, 3], [4, 1, 3, 5, 1], [3, 1, 1, 1, 1, 5, 1], [7, 2, 5, 1],
    [9, 1, 4, 1], [1, 6, 6, 1], [4, 12], [3, 3, 1, 4, 6], [1, 6, 3, 1, 7, 3],
    [8, 3, 1, 1, 5], [1, 15, 5], [1, 7, 3, 3, 2], [3, 1, 1, 10, 3], [4, 2, 2, 6, 3],
    [2, 3, 13], [5, 2, 3, 5], [5, 1, 4, 2], [6, 1, 3, 1], [7, 3],
    [6, 2, 3], [6, 5], [2, 1, 1, 4, 1, 4], [1, 3, 1, 5, 6, 2], [4, 1, 7, 1, 3, 1, 1],
    [5, 1, 1, 1, 1, 9], [5, 1, 3, 3], [5, 3, 3], [5, 3, 1, 1, 4, 4], [2, 1, 3, 8, 4]
]

all_segments = rows + columns
size_r = len(columns)
size_c = len(rows)
max_size = max(size_c, size_r)
Storage_mode_threshold = 40

answer = np.zeros((size_c, size_r), dtype=np.uint8)
all_sequences = []


def find_sequences(segments, size):
    result = []

    def backtrack(arr, index, segment):
        if not segment:
            result.append(arr.copy())
            return
        length = segment[0]

        # 遍历可能的起始位置
        for i in range(index, size - length + 1):
            if arr[i - 1]:
                continue

            # 标记当前片段为 1
            arr[i:i + length] = True
            backtrack(arr, i + length 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值