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

优化带规则网格的寻路算法:大网格性能提升需求

问题描述

给定带数值的网格,需找到从最高点到最低点的最长路径(最缓路径)。参考的递归搜索代码在小网格上运行正常,但在140x140这类大网格中,因遍历所有可能路径导致计算耗时极长,需要实现剪枝策略停止对非最优路径的搜索。

原递归代码如下:

def find_paths_recursive(grid, current_path=[(136,136)], solutions=[]):
    n = len(grid)
    dirs = [(-1,0), (1,0), (0,1), (0,-1)]
    
    last_cell = current_path[-1]
    
    for x,y in dirs:
        new_i = last_cell[0] + x
        new_j = last_cell[1] + y
        
        # 检查新单元格是否在网格内
        if new_i<0 or new_i>=n or new_j<0 or new_j>=n:
            continue
            
        # 检查新单元格数值是否大于当前单元格
        if grid[new_i][new_j] > grid[last_cell[0]][last_cell[1]]:
            continue
        
        # 检查新单元格是否已在路径中
        if (new_i, new_j) in current_path:
            continue

        # 复制当前路径并添加新单元格
        current_path_copy = current_path.copy()
        current_path_copy.append((new_i, new_j))

        # 到达终点则保存路径
        if new_i==0 and new_j ==0:
            solutions.append(current_path_copy)
        print(current_path_copy)
        # 递归搜索新路径
        find_paths_recursive(grid, current_path_copy, solutions)
        
    return solutions

def compute_cell_values(grid1, solutions):
    path_values = []

    for solution in solutions:
        solution_values = []
        for cell in solution:
            solution_values.append(grid1[cell[0]][cell[1]])
        path_values.append(solution_values)
    return path_values

grid1 = [...]


solutions = find_paths_recursive(grid1)
path_values = compute_cell_values(grid1, solutions)

print('所有路径:')
print(solutions)
print('路径数值:')
print(path_values)
剪枝与优化方案

1. 记忆化搜索(核心剪枝)

记录每个单元格(i,j)能到达终点的最长路径长度。当遍历到(i,j)时,如果当前路径长度已经小于等于该单元格已记录的最长路径,直接终止该分支搜索——因为继续走下去也不可能得到更长的路径。

2. 仅跟踪最长路径,丢弃非最优解

原代码保存所有路径会占用大量内存且无必要,只需维护当前找到的最长路径及其长度,一旦发现当前路径长度不可能超过已知最长路径,立即剪枝。

3. 启发式剪枝:提前预判路径上限

计算当前路径长度加上从当前单元格到终点的曼哈顿距离(即|i-0| + |j-0|,每步最多走一格,这是理论上能走的最大步数),如果这个值小于当前已知的最长路径长度,直接终止该分支——即使走满所有可能步数也追不上当前最优解。

4. 优先搜索更有潜力的方向

优先搜索与当前单元格数值差更小的邻居(符合"最缓"路径需求),或者更靠近终点的邻居。这样能更快找到较长路径,进而更早触发剪枝,减少无效搜索。

优化后的代码
def find_longest_path(grid, start, end):
    n = len(grid)
    dirs = [(-1,0), (1,0), (0,1), (0,-1)]
    # 记忆化数组:memo[i][j] 记录从(i,j)到终点的最长路径长度
    memo = [[-1 for _ in range(n)] for _ in range(n)]
    longest_path = []
    
    def dfs(current_i, current_j, current_path):
        nonlocal longest_path
        
        # 到达终点,更新最长路径
        if (current_i, current_j) == end:
            if len(current_path) > len(longest_path):
                longest_path = current_path.copy()
            return len(current_path)
        
        # 已有更优路径记录,直接返回并剪枝
        if memo[current_i][current_j] != -1:
            if len(current_path) + memo[current_i][current_j] - 1 <= len(longest_path):
                return memo[current_i][current_j]
        
        max_length = len(current_path)
        # 按数值差从小到大排序邻居,优先走更缓的路径
        neighbors = []
        for dx, dy in dirs:
            ni, nj = current_i + dx, current_j + dy
            if 0 <= ni < n and 0 <= nj < n:
                if grid[ni][nj] <= grid[current_i][current_j] and (ni, nj) not in current_path:
                    diff = grid[current_i][current_j] - grid[ni][nj]
                    neighbors.append((diff, ni, nj))
        
        # 优先搜索数值差更小的方向
        neighbors.sort()
        for _, ni, nj in neighbors:
            current_path.append((ni, nj))
            # 启发式剪枝:当前路径+剩余最大可能步数仍小于已知最长,直接跳过
            remaining_steps = abs(ni - end[0]) + abs(nj - end[1])
            if len(current_path) + remaining_steps <= len(longest_path):
                current_path.pop()
                continue
            
            length = dfs(ni, nj, current_path)
            if length > max_length:
                max_length = length
            current_path.pop()
        
        # 更新记忆化数组
        memo[current_i][current_j] = max_length
        return max_length
    
    dfs(start[0], start[1], [start])
    return longest_path

def compute_cell_values(grid, path):
    return [grid[i][j] for (i,j) in path]

# 示例使用
grid1 = [...]  # 你的网格数据
start_point = (136, 136)  # 最高点坐标
end_point = (0, 0)  # 最低点坐标

longest_path = find_longest_path(grid1, start_point, end_point)
path_values = compute_cell_values(grid1, longest_path)

print('最长路径:', longest_path)
print('路径数值:', path_values)
优化效果说明
  • 记忆化搜索避免了重复计算同一单元格的路径分支,大幅减少递归次数。
  • 启发式剪枝提前终止了不可能成为最优解的路径分支。
  • 优先搜索更缓方向能更快找到较长路径,更早触发剪枝逻辑。
  • 仅跟踪最长路径节省了大量内存,避免大网格下的内存溢出问题。

内容的提问来源于stack exchange,提问作者D a r k k

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 15:45:37