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

时间:2016-06-28 21:08:00

标签: 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之间。对于这样一组数组,我想找到A_i的所有可能状态。

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

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

[1 2]会产生[1 1]和[1 2]等

我在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, 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

由于我这样做是为了思考问题,我很好奇如何:

  • python itertools可能使这成为可能
  • 任何谈论这一系列问题的链接
  • 如何更有效地思考我的方法

任何想法都赞赏。

2 个答案:

答案 0 :(得分:4)

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

itertools.product(* iterables [,repeat])

这可能也很有用:link

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

答案 1 :(得分:0)

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

递归地说,你需要让问题更小。你可以在这里递归数组长度:

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))