Arrays 递归优化

Arrays 递归优化,arrays,python-3.x,recursion,Arrays,Python 3.x,Recursion,我试图通过我的2d数组找到一条特定的路径 我的阵列可能如下所示: temp = [ ["placeholder", 2, 0], ["placeholder", 1, 7, 3], ["placeholder", 4, 5, 8], ["placeholder", 6, 3, 5, 2], ["placeholder", 7], ["pla

我试图通过我的2d数组找到一条特定的路径

我的阵列可能如下所示:

temp = [
    ["placeholder", 2, 0],
    ["placeholder", 1, 7, 3],
    ["placeholder", 4, 5, 8],
    ["placeholder", 6, 3, 5, 2],
    ["placeholder", 7],
    ["placeholder", 3, 0],
]
内部数组包含一个占位符,后跟可变数量的整数。这些整数的值范围在0-19之间(包括0和19)

我想找到一条从上到下穿过这些内部数组的路径,在这些数组中,数字不能被多次使用

temp[0]
时,我可以选择我的第一个值
2
0

temp[1]
时,我可以选择第二个值
1
7
3

temp[2]
时,我可以选择第三个值
4
5
8

temp[3]
时,我可以选择第四个值
6
3
5
2

请注意,如果我在第一步中已经选择了
2
,则在此步骤中我无法选择
2
如果我已经在第二步中选择了
3
,我将无法选择
3

如果我已经在第三步中选择了
5
,我将无法选择
5

等等

以下是一些法律途径:

  • 2-1-4-6-7-3
  • 0-1-4-5-7-3
以下是一些非法路径:

  • 2-1-4-2-7-3(2被触摸两次)
  • 0-1-4-5-7-0(0被触摸两次)
我希望我的函数输出一个完全合法的路径。
如果找不到路径,我只希望函数返回false。

我曾尝试编写自己的递归解决方案来解决这个问题,我认为这是可行的,但效率低下,因此需要花费大量时间来完成。
我想要的数组的大小更像是20 x 1..20

到目前为止,我的代码如下所示(用Python 3编写)(并带有临时数组):

temp=[
[“占位符”,7,3],
[“占位符”,3,3],
[“占位符”,4,3],
[“占位符”,3,8],
[“占位符”,1,3],
]
def findpath(数组,路径=[]):
如果path和path.count(path[-1])>1:
返回错误
如果len(路径)==len(数组):
打印(路径)
返回真值
路由=数组[len(路径)][1:]
对于路线中的路线:
路径追加(路由)
如果findpath(数组、路径):
返回真值
path.pop(-1)
findpath(临时)
此代码打印:
[7,3,4,8,1]

这种方法是在达成解决方案之前对每一种可能性进行残酷的强迫。在最坏的情况下,我的
temp
数组将包含20个数组,每个数组都包含20个值,这就是20!可能的解决方案,或者换句话说,2.432.902.008.176.640.000可能的路径。让我们夸张地说,我的电脑需要1毫秒来处理这个函数的单个迭代。我的数学可能是错误的,但这意味着这一过程可能需要77146816.6年才能完成(不包括闰年),老实说,伊玛,我没有这样的时间

必须有更聪明的方法来解决这个问题。
我注意到的一件事是,如果函数在步骤15遇到一个内部数组,它只包含一个int,例如
2
,那么函数将尝试一次调整一个最新拾取(第一步14,然后是步骤13),而没有意识到它已经在步骤2拾取了
2
。在这种情况下,返回步骤2并将值从
2
更改为其他值将节省大量迭代。唯一的问题是我不知道如何实现这一点,也不知道如何进一步优化这一点

下面是一个真实的示例数组(不确定它是否包含解决方案)

temp=[
[‘占位符’、2、6、11、14、15、16、18],
[2,6,7,10,11,14,15,16,17,18,19],
[‘占位符’、2、6、10、11、14、15、16、18、19],
[‘占位符’、2、6、11、14、15、16、18、19],
[‘占位符’、2、6、11、14、15、16],
[2,6,7,10,11,14,15,16,18,19],
[‘占位符’、2、6、7、8、9、10、11、14、15、16、17、18、19],
[‘占位符’、11、15、16],
['placeholder',11,14,15,16],
[‘占位符’、0、1、2、4、6、7、8、9、10、11、12、13、14、15、16、17、18、19],
[‘占位符’,11,15],
[‘占位符’、2、6、7、8、9、10、11、12、13、14、15、16、17、18、19],
[‘占位符’、1、2、4、6、7、8、9、10、11、12、13、14、15、16、17、18、19],
[‘占位符’、0、1、2、3、4、5、6、7、8、9、10、11、12、13、14、15、16、17、18、19],
[‘占位符’、2、6、7、8、9、10、11、13、14、15、16、17、18、19],
[‘占位符’、2、4、6、7、8、9、10、11、12、13、14、15、16、17、18、19],
[placeholder',15],
[‘占位符’、0、1、2、4、5、6、7、8、9、10、11、12、13、14、15、16、17、18、19],
['placeholder',2,11,14,15,16],
[‘占位符’、2、6、7、8、10、11、14、15、16、17、18、19]
]

希望您能帮助我学习功能性遗产

递归是一种函数遗产,因此将其与函数风格结合使用会产生最好的结果。这意味着避免像
.append
.pop
这样的突变和其他副作用

下面我们使用
集合
有效地跳过无效组合,并使用
元组
存储路径。为每个递归构造一个新的集合和元组-

def遍历(t,s=set(),p=()):
如果不是t:
产量p
其他:
[[[ux,*值],*更多]=t
对于v值:
如果v不在s中:
遍历产生的收益(更多,{*s,v},(*p,v))
使用示例程序中的数据-

temp=\
[“占位符”,7,3]
,[“占位符”,3,3]
,[“占位符”,4,3]
,[“占位符”,3,8]
,[“占位符”,1,3]
]
对于导线中的p(温度):
印刷品(p)
(7,3,4,8,1)
(7, 3, 4, 8, 1)
使用原始问题中的数据-

temp=\
[[“占位符”,2,0]
,[“占位符”,1,7,3]
,[“占位符”,4,5,8]
,[“占位符”,6,3,5,2]
,[“占位符”,7]
,[“占位符”,3,0]
]
对于导线中的p(温度):
印刷品(p)
<