Python 在n*m网格中查找所有可能的无重复行走
我想找到所有可能通过尺寸为Python 在n*m网格中查找所有可能的无重复行走,python,algorithm,Python,Algorithm,我想找到所有可能通过尺寸为n*m的网格的行走,其中行走不得多次使用节点,并允许移动到相邻节点(包括对角线) 例如,1*1网格是微不足道的;只有一种可能的行走,即[(0,0)]。1*2网格有4种可能的行走,即[(0,0)],[(0,1)],[(0,0),(0,1)]和[(0,1),(0,0)]。2*2网格有4个长度为1的普通走行,分别是[(0,0)],[(0,1)],[(1,0)]和[(1,1)]和[(1,1)],[(0,0)、(0,1)],[(0,0)],[(1,0)],[(0,0)],,[(0
n*m
的网格的行走,其中行走不得多次使用节点,并允许移动到相邻节点(包括对角线)
例如,1*1
网格是微不足道的;只有一种可能的行走,即[(0,0)]
。1*2
网格有4种可能的行走,即[(0,0)]
,[(0,1)]
,[(0,0),(0,1)]
和[(0,1),(0,0)]
。2*2
网格有4个长度为1的普通走行,分别是[(0,0)]
,[(0,1)]
,[(1,0)]和[(1,1)]和[(1,1)],[(0,0)、(0,1)],[(0,0)],[(1,0)],[(0,0)],,[(0,0,0)],<1]等等,16个长度为3的走行行行和16次行走,长度为4([(0,0)、(0,1)、(1,1)、(1,0)]
等)
这是我在python中实现递归算法的尝试,以列出n*m网格中所有可能的行走,但它不会返回正确的解决方案。我通过迭代所有的起点来实现它,然后形成一个包含可能的后续步骤的递归树
dim=(2,2)
walks=[]
def main():
for row in range(dim[0]):
for col in range(dim[1]):
walked=[[0 for i in range(dim[0])] for j in range(dim[1])]
walkTree(row, col, walked, [])
print(walks)
def walkTree(row, col, walked, leading):
walks.append( leading+[(row,col)] )
walked[row][col]=1
leading.append((row,col))
if row-1 >= 0:
if col-1 >= 0:
if not walked[row-1][col-1]:
walkTree(row-1, col-1, walked, leading)
if not walked[row-1][col]:
walkTree(row-1, col, walked, leading)
if col+1 < dim[1]:
if not walked[row-1][col+1]:
walkTree(row-1, col+1, walked, leading)
if col-1 >= 0:
if not walked[row][col-1]:
walkTree(row, col-1, walked, leading)
if col+1 < dim[1]:
if not walked[row][col+1]:
walkTree(row, col+1, walked, leading)
if row+1 < dim[0]:
if col-1 >= 0:
if not walked[row+1][col-1]:
walkTree(row+1, col-1, walked, leading)
if not walked[row+1][col]:
walkTree(row+1, col, walked, leading)
if col+1 < dim[1]:
if not walked[row+1][col+1]:
walkTree(row+1, col+1, walked, leading)
if __name__=='__main__':
main()
dim=(2,2)
步行=[]
def main():
对于范围内的行(尺寸[0]):
对于范围内的列(尺寸[1]):
步行=[[0表示范围内的i(尺寸[0])]表示范围内的j(尺寸[1])]
walkTree(行、列、行、[]))
印刷(步行)
def walkTree(行、列、行、前导):
walks.append(前导+[(行,列)])
步行[行][列]=1
前导.追加((行,列))
如果第1行>=0:
如果col-1>=0:
如果不是步行[第1排][第1列]:
walkTree(第1行、第1列、步行、领先)
如果不是步行[第1排][col]:
walkTree(第1行,col,walked,leading)
如果列+1=0:
如果没有步行[世界其他地区][col-1]:
walkTree(行、列1、行、前导)
如果列+1=0:
如果没有步行[行+1][列-1]:
walkTree(行+1,列-1,走行,前导)
如果不是步行[行+1][列]:
walkTree(行+1,列,行,前导)
如果列+1
非常感谢您对我的代码不起作用的原因提供任何帮助,或者提供更好的方法来解决这个问题。谢谢 我添加了一些跟踪工具。从(0,0)开始的输出低于该值。print语句是根据级别缩进的,我只是在几个有用的点上打印出当前位置
代码:
。。。或者制作一份本地副本,而不是处理本质上是全局主列表的内容
既然您已经得到了提示,我将把引导的处理留给您
输出:
ENTER pos 0 0 walked= [[False, False], [False, False]] lead= []
ROW- 0 0 [[True, False], [False, False]]
COL- 0 0 [[True, False], [False, False]]
COL+ 0 0 [[True, False], [False, False]]
ENTER pos 0 1 walked= [[True, False], [False, False]] lead= [(0, 0)]
ROW- 0 1 [[True, True], [False, False]]
COL- 0 1 [[True, True], [False, False]]
COL+ 0 1 [[True, True], [False, False]]
ROW+ 0 1 [[True, True], [False, False]]
ENTER pos 1 0 walked= [[True, True], [False, False]] lead= [(0, 0), (0, 1)]
ROW- 1 0 [[True, True], [True, False]]
COL- 1 0 [[True, True], [True, False]]
COL+ 1 0 [[True, True], [True, False]]
ENTER pos 1 1 walked= [[True, True], [True, False]] lead= [(0, 0), (0, 1), (1, 0)]
ROW- 1 1 [[True, True], [True, True]]
COL- 1 1 [[True, True], [True, True]]
COL+ 1 1 [[True, True], [True, True]]
ROW+ 1 1 [[True, True], [True, True]]
ROW+ 1 0 [[True, True], [True, True]]
ROW+ 0 0 [[True, True], [True, True]]
ENTER pos 0 1 walked= [[False, False], [False, False]] lead= []
ROW- 0 1 [[False, True], [False, False]]
COL- 0 1 [[False, True], [False, False]]
...
还有另一种方法。您可以将问题简化为图形上的已知问题,然后使用图形库来解决它
将单元定义为节点,用边连接所有相邻单元(包括对角线)
添加两个附加节点s和d。将s连接到所有初始节点,对d执行相同操作
然后你的问题就变成了:找到s和d之间的所有简单路径。python的networkx库可以做到这一点(请参阅),R的igraph也可以做到这一点(而且它会做得更快)。出于某种奇怪的原因,igraph For python中似乎没有类似的函数
当你说你也对“更好的方法”感兴趣时,那包括外部包吗?当然,只要它能够迭代所有可能的行走。你没有向我们展示错误的输出,也没有提供任何执行跟踪。你对此做了什么,你从中学到了什么?我在(2,1)和(1,2)网格上尝试了你的代码。在这两种情况下,它都会出现索引超出范围的故障。如果这是我的问题,我会使用并搜索一个索引。我会帮你做这件事,但至少需要序列的前四个数字。谢谢,我知道问题出在哪里,但我不知道是什么原因造成的。我试着按照你的建议创建一个本地的walked副本,但似乎没有什么不同。此外,我不明白为什么函数的其他迭代会通过上一次迭代的遍历-我的意思是让每个迭代都使用调用时通过的自己的遍历列表来运行。我不明白为什么创建本地副本不能解决此问题。您发布的代码没有创建walk
的本地副本:您在主程序中创建了一个副本,并将其传递给每个迭代。你有没有用一些打印的语句来检查你的功能?作为一名即将毕业的数学本科生,我修了一门图论课程,我有点惭愧自己没有看到这种图论方法;特别是考虑到我已经看到类似的技术被用于稳定的婚姻问题等。这是比我更优雅的方法,imo-非常感谢你的帮助!作为一个更新:我已经成功地实现了这个解决方案,并且它按照预期工作;虽然我发现使用4x4网格(如果您好奇,可以使用“Boggle解算器”)的应用程序效率太低,因为4x4 Kings图有1200万条简单路径(因此算法会“卡住”不包含单词的无望路径)。然而,这种方法使我对如何更有效地解决问题产生了更好的想法(有些是启发性的,而不是穷尽性的)。即首先搜索哈密顿路径(因为单词越长越好),并移除各种顶点。再次感谢@用户406579,不客气;很高兴听到你玩得很开心:)
walked[row,col] = False
ENTER pos 0 0 walked= [[False, False], [False, False]] lead= []
ROW- 0 0 [[True, False], [False, False]]
COL- 0 0 [[True, False], [False, False]]
COL+ 0 0 [[True, False], [False, False]]
ENTER pos 0 1 walked= [[True, False], [False, False]] lead= [(0, 0)]
ROW- 0 1 [[True, True], [False, False]]
COL- 0 1 [[True, True], [False, False]]
COL+ 0 1 [[True, True], [False, False]]
ROW+ 0 1 [[True, True], [False, False]]
ENTER pos 1 0 walked= [[True, True], [False, False]] lead= [(0, 0), (0, 1)]
ROW- 1 0 [[True, True], [True, False]]
COL- 1 0 [[True, True], [True, False]]
COL+ 1 0 [[True, True], [True, False]]
ENTER pos 1 1 walked= [[True, True], [True, False]] lead= [(0, 0), (0, 1), (1, 0)]
ROW- 1 1 [[True, True], [True, True]]
COL- 1 1 [[True, True], [True, True]]
COL+ 1 1 [[True, True], [True, True]]
ROW+ 1 1 [[True, True], [True, True]]
ROW+ 1 0 [[True, True], [True, True]]
ROW+ 0 0 [[True, True], [True, True]]
ENTER pos 0 1 walked= [[False, False], [False, False]] lead= []
ROW- 0 1 [[False, True], [False, False]]
COL- 0 1 [[False, True], [False, False]]
...