【问题标题】:Enumerate all possibilities in array with descending values用递减值枚举数组中的所有可能性
【发布时间】:2016-06-28 21:08:00
【问题描述】:

我正在尝试编写一种递归方法来枚举任意长度数组的所有可能值,其元素都可以下降到一个。更正式地说,给定一个包含元素 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 可能使这成为可能
  • 任何讨论这一系列问题的链接
  • 如何更有效地思考我的方法

任何想法表示赞赏。

【问题讨论】:

    标签: python recursion array-algorithms


    【解决方案1】:

    你要找的函数/工具叫做“笛卡尔积”,已经在很多地方实现了,包括itertools。

    itertools.product(*iterables[, 重复])

    这也可能有用:link

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

    【讨论】:

    • 我不确定降序元素如何是笛卡尔积。你能再解释一下吗?
    • 好吧,我认为首先你会使用笛卡尔积来快速生成所有可能性。然后,您将根据自己的喜好开始对列进行排序。根据您如何调用笛卡尔积,列表可能已经排序。
    • so itertools.product 例如生成 [3 2 3] 的所有可能性,例如,没有看到会生成 [1 1 1]
    【解决方案2】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-31
      • 2012-06-26
      • 1970-01-01
      • 2017-06-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多