【发布时间】:2016-01-15 01:16:12
【问题描述】:
我有三个列表,每个列表都有几个可能的值。
probs = ([0.1,0.1,0.2], \
[0.7,0.9], \
[0.5,0.4,0.1])
我想测试从每个列表中选择一个元素的所有可能组合。所以,在这个例子中,3*2*3=18 种可能的组合。最后,我想根据一些标准选择最有利的组合。这是:
[<index in row 0> , <index in row 1> , <index in row 2> , <criteria value>]
我可以通过使用三个嵌套的 for 循环来完成我的任务(我这样做了)。但是,在此代码的实际应用中,我将拥有可变数量的列表。因此,似乎解决方案是使用内部带有 for 循环的递归函数(我也这样做了)。代码:
# three rows. Test all combinations of one element from each row
# This is [value form row0, value from row1, value from row2]
# So: 3*2*3 = 18 possible combinations
probs = ([0.1,0.1,0.2], \
[0.7,0.9], \
[0.5,0.4,0.1])
meu = [] # The list that will store the best combinations in the recursion
#######################################################
def main():
choice = [] #the list that will store the best comb in the nested for
# accomplish by nested for loops
for n0 in range(len(probs[0])):
for n1 in range(len(probs[1])):
for n2 in range(len(probs[2])):
w = probs[0][n0] * probs[1][n1] * probs[2][n2]
cmb = [n0,n1,n2,w]
if len(choice) == 0:
choice.append(cmb)
elif len(choice) < 5:
for i in range(len(choice)+1):
if i == len(choice):
choice.append(cmb)
break
if w < choice[i][3]:
choice.insert(i,cmb)
break
else:
for i in range(len(choice)):
if w < choice[i][3]:
choice.insert(i,cmb)
del choice[-1]
break
# using recursive function
combinations(0,[])
#both results
print('By loops:')
print(choice)
print('By recursion:')
print(meu)
#######################################################
def combinations(step,cmb):
# Why does 'meu' needs to be global
if step < len(probs):
for i in range(len(probs[step])):
cmb = cmb[0:step] # I guess this is the same problem I dont understand recursion
# But, unlike 'meu', here I could use this workaround
cmb.append(i)
combinations(step+1,cmb)
else:
w = 1
for n in range(len(cmb)):
w *= probs[n][cmb[n]]
cmb.append(w)
if len(meu) == 0:
meu.append(cmb)
elif len(meu) < 5:
for i in range(len(meu)+1):
if i == len(meu):
meu.append(cmb)
break
if w < meu[i][-1]:
meu.insert(i,cmb)
break
else:
for i in range(len(meu)):
if w < meu[i][-1]:
meu.insert(i,cmb)
del meu[-1]
break
return
######################################################
main()
它按照我的意愿输出:
By loops:
[[0, 0, 2, 0.006999999999999999], [1, 0, 2, 0.006999999999999999], [0, 1, 2, 0.009000000000000001], [1, 1, 2, 0.009000000000000001], [2, 0, 2, 0.013999999999999999]]
By recursion:
[[0, 0, 2, 0.006999999999999999], [1, 0, 2, 0.006999999999999999], [0, 1, 2, 0.009000000000000001], [1, 1, 2, 0.009000000000000001], [2, 0, 2, 0.013999999999999999]]
最初,我想将“meu”列表用作函数的内部,因为我认为最好避免使用全局变量(也许不是……我是新手)。问题是我无法想出在深度之间传递“meu”和“cmb”的代码,以提供与嵌套循环相同的效果。
如何使用内部“meu”而不是全局列表来实现递归函数?我从递归概念中遗漏了什么?谢谢。
++++++++++++++++++++++++++++++++++++++
失败函数示例:
def combinations(choice,step,cmb):
if step < len(probs):
for i in range(len(probs[step])):
cmb = cmb[0:step] #workaroud for cmb
cmb.append(i)
choice = combinations(choice,step+1,cmb)
else:
w = 1
for n in range(len(cmb)):
w *= probs[n][cmb[n]]
cmb.append(w)
if len(choice) == 0:
choice.append(cmb)
elif len(choice) < 5:
for i in range(len(choice)+1):
if i == len(choice):
choice.append(cmb)
break
if w < choice[i][-1]:
choice.insert(i,cmb)
break
else:
for i in range(len(choice)):
if w < choice[i][-1]:
choice.insert(i,cmb)
del choice[-1]
break
return choice
调用者:
choice = combinations([],0,[])
【问题讨论】:
-
对不起,你在很多地方都说'meu',但我似乎在代码中找不到它。另外,您能否检查一下 [stackoverflow.com/questions/533905/…,因为它可能会为您提供一些来自 python 的额外工具。
-
感谢您的回复。亲切的回应以及您的链接建议回答了我的问题。但回答你的问题,“meu”在我提出的最长代码部分的“组合”函数中。
-
@ direito 完全忽略了它:-) 对不起。很高兴您得到了解决方案!
标签: python recursion nested-loops