Python 用降序值枚举数组中的所有可能性

Python 用降序值枚举数组中的所有可能性,python,recursion,array-algorithms,Python,Recursion,Array Algorithms,我正在尝试编写一种递归方法来枚举任意长度数组的所有可能值,这些数组的元素都可以降为一个。更正式地说,给定一个包含元素A_1,A_2,…,A_N的数组A和包含元素B_1,B_2…B_N的数组B。A_i和B_i之间存在一种关系,其中i介于1和N之间,任何元素A_i都位于1和B_i之间。对于这样一组数组,我想找到一个I的所有可能状态 例如,数组[1 2 3]具有以下六种可能的状态: [1 1 1] [1 2 1] [1 1 2] [1 1 3] [1 2 2] [1 2 3] [12]会产生[11

我正在尝试编写一种递归方法来枚举任意长度数组的所有可能值,这些数组的元素都可以降为一个。更正式地说,给定一个包含元素A_1,A_2,…,A_N的数组A和包含元素B_1,B_2…B_N的数组B。A_i和B_i之间存在一种关系,其中i介于1和N之间,任何元素A_i都位于1和B_i之间。对于这样一组数组,我想找到一个I的所有可能状态

例如,数组[1 2 3]具有以下六种可能的状态:


[1 1 1]
[1 2 1]
[1 1 2]
[1 1 3]
[1 2 2]
[1 2 3]

[12]会产生[11]和[12],等等

我用python尝试了一种解决方案,例如:

b = [1, 3, 3]
n = len(b)

a = []
k = 0
r = 0

print b
print '------'

def f(i, k, a, r):
  k += 1
  if i == n-1:
    return False
  for j in range(1, b[i+1]+1):
    r += 1
    print "i: %d b[i]: %d k: %d new: %d r: %d" % (i, b[i], k, j, r)
    f(i+1, k, a, r)

f(0, k, a, r)
但我似乎无法获得正确的值,也无法获得要填充的数据结构。例如[3]只生成一个具有三个节点的树或结果:

[3, 3]
------
i: 0 b[i]: 3 k: 1 new: 1 r: 1
i: 0 b[i]: 3 k: 1 new: 2 r: 2
i: 0 b[i]: 3 k: 1 new: 3 r: 3
由于我这样做是为了思考问题,我很好奇如何:

  • pythonitertools可能使这成为可能
  • 有没有关于这一系列问题的链接
  • 如何更有效地思考我的方法

任何想法都值得欣赏。

您正在寻找的功能/工具称为“笛卡尔产品”,它已在许多地方实现,包括itertools

(*iterables[重复])

这也可能有用:


要实现最终目标,您需要的是所谓的“词典”排序。我不确定是否有一个易于使用的工具可用,因为我不确定它是否是一个已解决的问题(取决于许多任意排序规则)。但是,您可以查看Python文档以开始,因为它们有一些关于词典输出的信息。

您正在寻找的函数/工具称为“笛卡尔产品”,它已在许多地方实现,包括itertools

(*iterables[重复])

这也可能有用:


要实现最终目标,您需要的是所谓的“词典”排序。我不确定是否有一个易于使用的工具可用,因为我不确定它是否是一个已解决的问题(取决于许多任意排序规则)。但是,您可以查看Python文档以开始,因为它们有一些关于词典输出的信息。

基本上,对于每一列,您都有一组“允许”的值。通过从每个集合中选取一个值并将其放入相关列中,可以生成一个有效的“相关”数组。你只需要尝试所有的可能性

递归地,您需要使问题更小。您可以在此处递归数组长度:

def enumerate(v):                                                               
    if len(v) == 0:                                                             
        yield v                                                                 
    else:                                                                       
        for i in range(1, v[0] + 1):                                            
            for rest in enumerate(v[1:]):                                       
                yield [i] + rest                                                
您可以使用itertools获得相同的效果,无需显式重复:

def enumerate2(v):                                                              
    from itertools import product                                               
    return product(*(range(1, e+1) for e in v))   

基本上,每个列都有一组“允许”值。通过从每个集合中选取一个值并将其放入相关列中,可以生成一个有效的“相关”数组。你只需要尝试所有的可能性

递归地,您需要使问题更小。您可以在此处递归数组长度:

def enumerate(v):                                                               
    if len(v) == 0:                                                             
        yield v                                                                 
    else:                                                                       
        for i in range(1, v[0] + 1):                                            
            for rest in enumerate(v[1:]):                                       
                yield [i] + rest                                                
您可以使用itertools获得相同的效果,无需显式重复:

def enumerate2(v):                                                              
    from itertools import product                                               
    return product(*(range(1, e+1) for e in v))   

我不确定下降元素是如何笛卡尔积的。你能再解释一下吗?首先,我想你应该使用笛卡尔积来快速生成所有的可能性。然后,根据您的偏好开始对列进行排序。根据您如何调用笛卡尔产品,列表可能已经排序。因此,itertools.product可以生成[3 2 3]的所有可能性,例如,如果没有看到这将生成[1 1 1],例如,我不确定降序元素是如何为笛卡尔产品的。你能再解释一下吗?首先,我想你应该使用笛卡尔积来快速生成所有的可能性。然后,根据您的偏好开始对列进行排序。根据您对笛卡尔积的调用方式,可能已经对列表进行了排序。例如,itertools.product可以生成[3 2 3]的所有可能性,例如,没有看到会生成[1 1]