python-3.x - 计算网格中从左上到右下的路径数
问题描述
我需要计算从左上角到右下角的路径数,其中有效路径是穿过网格中所有正方形的路径(每个正方形恰好一次)
我正在使用回溯技术。不幸的是,count
是0
在计算结束。打印t
,我看到它永远不会到达n-1
。
我的算法有什么问题?
n = 4
count = 0
m = [[False for x in range(n)] for y in range(n)]
def num_of_paths(m, x, y, t):
print(t)
global count
# check if we reached target
if x == (n - 1) and y == (n - 1):
if t < (n * n):
# not on time, prune the tree here
return
elif t == n * n:
# completed a full path in the grid and on time
count += 1
if t > n * n:
return
# Right
if x + 1 < n and m[x + 1][y] == False:
m[x + 1][y] = True
num_of_paths(m, x + 1, y, t + 1)
m[x + 1][y] = False
# Left
if x - 1 > 0 and m[x - 1][y] == False:
m[x - 1][y] = True
num_of_paths(m, x - 1, y, t + 1)
m[x - 1][y] = False
# Down
if y + 1 < n and m[x][y + 1] == False:
m[x][y + 1] = True
num_of_paths(m, x, y + 1, t + 1)
m[x][y + 1] = False
# Up
if y - 1 > 0 and m[x][y - 1] == False:
m[x][y - 1] = True
num_of_paths(m, x, y - 1, t + 1)
m[x][y - 1] = False
num_of_paths(m, 0, 0, 0)
print(count)
解决方案
有以下问题:
- 起始单元格没有标记
m[0][0] = True
,因此向右走后,算法将再次向左走,实际上访问了两次该单元格。要解决此问题,您可以将用于管理m
值的代码从您现在拥有的位置移开(4 次)并将其应用到当前单元格(一次)。这包括检查以及和if m[..][..]
的分配。True
False
if
与左和上方向相关的条件应将坐标与 进行比较>= 0
,而不是与> 0
:坐标的零值仍在范围内。t
应该从 1 开始,因为您将其值与n * n
. 否则你应该与n * n - 1
. 在下面的更正中,我将从t = 1
.- 不是一个真正的问题,但是在这样做之后
count += 1
立即有意义return
,因为不再有可能进一步扩展路径。
其他一些评论:
- 当n为偶数时,没有有效路径,因此即使更正,该函数在这种情况下也必然返回 0
- 这个算法访问的路径数量是指数的,O(2 n² )。对于n > 6,不要等待它......
这是您的代码的更正版本。评论应阐明更改的内容和原因:
n = 5
count = 0
m = [[False for x in range(n)] for y in range(n)]
def num_of_paths(m, x, y, t):
global count
# Moved the "visited" check to here. No need to add `== True`.
if m[x][y]:
return
if x == (n - 1) and y == (n - 1):
if t < (n * n):
return
else: # Removed the unnecessary condition here
count += 1
# Added a return here
return
# Removed an if-block of which the condition could never be true
# Moved the "visited" marking to here:
m[x][y] = True
if x + 1 < n:
num_of_paths(m, x + 1, y, t + 1)
# Corrected "> 0" to ">= 0"
if x - 1 >= 0:
num_of_paths(m, x - 1, y, t + 1)
if y + 1 < n:
num_of_paths(m, x, y + 1, t + 1)
# Corrected "> 0" to ">= 0"
if y - 1 >= 0:
num_of_paths(m, x, y - 1, t + 1)
# Moved the "visited" unmarking to here:
m[x][y] = False
# Corrected the last argument
num_of_paths(m, 0, 0, 1)
print(count)
推荐阅读
- algorithm - 如何在块算法中显示“if operator in for operator”?
- core-audio - PCM中的音频帧样本类型?
- c# - Kubectl 以交互方式应用 .NET Core 控制台应用程序,并在 Kubernetes 上退出 Console.ReadLine
- javascript - 我无法捕获 Select2 事件 - 我怀疑我使用了错误的 jquery 选择器
- google-chrome - MediaRecorder Chrome 编解码器/容器无法在移动设备或 Safari 上播放
- powershell - Powershell脚本将文件从一个位置移动到另一个位置,然后将消息框显示到我们网络上的另一台计算机
- symfony - 如何修复“key too long”错误并生成 Doctrine 迁移表?
- python - “numpy.ndarray”对象没有属性“fbind”
- css - 使用 Viusal Studio 2019 构建项目时,CSS 文件恢复为未修改版本
- java - 使用 GeoHash 进行地理空间查询