You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

优化单人数学解谜游戏求解性能的技术咨询

10×10方格跳跃解谜算法优化问题

游戏背景与规则

这是一款单人解谜游戏,规则如下:

  • 绘制10×10的方格区域
  • 任选一个方格放置数字1(通常选(0,0)位置)
  • 按特定跳跃规则从1数到100,在跳跃到达的方格填入对应数字
  • 跳跃规则:水平/垂直方向跳过2个方格(一次移动3格);对角线方向跳过1个方格(一次移动2格,坐标变化为±2,±2)

游戏示例:
游戏示例

问题描述

我用Python写了暴力搜索代码,但运行速度极慢——要探索的可能性达100!量级,完全不现实。我用的是11代i7处理器,但代码仅单核心运行,想请教如何提升速度或改进算法。

现有代码

class Gametable:

    def __init__( self ):
        #This value contains the maximum number reched by the algorithm
        self.max_reached = 1

    def start_at( self, coordX,  coordY ):
        tmpTable = [
            [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
            [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
            [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
            [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
            [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
            [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
            [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
            [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
            [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
            [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
        ]
        #We do not need to check the first jump, since the table should be empty.
        if self.is_valid_move( coordX, coordY, 1, tmpTable ):
            print("Found a solution!")
        else:
            print("Found no solution :(")

    def print_table( self, table ):
        print(52*"-")
        for X in range(10):
            for Y in range(10):
                if table[ X ][ Y ] == 0:
                    print("|    ", end="")
                else:
                    print("| {:02d} ".format( table[ X ][ Y ]), end='')
            print(" |")
            print(52*"-")
        print()


    def is_valid_move( self,  X,  Y,  counter,  table):

        # Check bounds
        if  X < 0:
            return False
        elif  X > 9:
            return False
        elif  Y < 0:
            return False
        elif  Y > 9:
            return False

        # Now check next steps
        if  table[ X ][ Y ]==0:
                table[ X ][ Y ] = counter
                if self.is_valid_move( X + 3, Y, counter+1, table ) or self.is_valid_move( X - 3, Y, counter+1, table ) or self.is_valid_move( X , Y + 3, counter+1, table ) or self.is_valid_move( X,  Y - 3, counter+1, table ) or self.is_valid_move( X + 2, Y + 2, counter+1, table ) or self.is_valid_move( X + 2, Y - 2, counter+1, table ) or self.is_valid_move( X - 2, Y + 2, counter+1, table ) or self.is_valid_move( X - 2, Y - 2, counter+1, table ):
                    return True
                else:
                    if counter > self.max_reached:
                        print("Max reached "+str(self.max_reached))
                        self.print_table(table)
                        self.max_reached = counter
                    table[X][Y] = 0 # We'll have to delete the last step if there is no further possibility
                    return False

mytable = Gametable()
mytable.start_at( 0, 0 )

优化方案

1. 用Warnsdorff启发式搜索替代暴力遍历

这是解决这类路径覆盖问题的核心优化——每次优先选择后续可移动选项最少的位置,而非盲目尝试所有方向。这种策略能快速剪掉大量死胡同路径,搜索效率提升几个数量级。

实现时,不要按固定顺序尝试8个方向,先计算每个合法下一跳位置的可移动次数,按次数升序排序后再递归尝试。

2. 奇偶性剪枝,提前排除无解路径

分析跳跃规则的奇偶性变化:

  • 水平/垂直跳3格:坐标x或y的奇偶性翻转(比如x从偶变奇)
  • 对角线跳2格:x和y的奇偶性都不变
    初始位置(0,0)是偶偶格,10×10方格中偶偶、奇偶、偶奇、奇奇格各25个。如果后续路径的奇偶性变化无法覆盖所有类型的格子,直接终止当前分支,无需继续搜索。

3. 多进程并行搜索

利用11代i7的多核心优势,把初始的几个分支拆分到不同进程同时运行。比如先找出数字1之后的所有合法位置,每个位置启动一个独立的搜索任务,用Python的multiprocessing模块实现。注意每个进程要维护独立的棋盘状态,避免共享数据冲突。

4. 数据结构提速

  • 把二维棋盘换成一维数组(比如table[x*10 + y]),访问速度更快;
  • 用位掩码记录已访问格子:100位刚好可以用Python大整数存储,判断格子是否被占用只需位运算(mask & (1 << pos)) == 0,比列表索引高效得多。

5. 预计算合法移动方向

提前遍历所有格子,预生成每个位置的合法下一跳坐标列表并存入字典。这样每次递归时不用重复判断边界,直接从字典取可用方向。

实操建议

先优先实现Warnsdorff法则,这是见效最快的优化。如果用启发式搜索后仍找不到解,再结合奇偶性分析判断是否存在解的可能——比如如果路径的奇偶性无法覆盖所有25个奇奇格,可直接判定无解。


内容的提问来源于stack exchange,提问作者LinuxCNC Nerd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 04:50:17