查找所有可能的列表子集的所有可能组合

时间:2013-10-03 21:37:34

标签: python math combinations subset

我试图从列表中找到子集的所有组合,其中每个元素只使用一次。

为了澄清我的意思,给出了一个示例列表:

[1,2,3,4]

我可以生成以下组合:

[(1),(2),(3),(1,2),(1,3),(2,3),(1,2,3)](这应该是详尽的!)< / p>

然后我可以生成这些组合的组合:

<[>([1],(2),(3)],[(1,2),(3)],[(1,3),(2)],[(1),(2, 3)],[(1,2,3)],......(对许多人来说)]

重点是我只允许在给定的组合中使用每个元素一次。所以我不能:

[(1),(1,2,3)]因为元素1被使用了两次。

我一直在尝试使用python对小n(n <10)进行暴力破解,并且一直在失败。在这一点上它甚至不是运行时问题(小n!),但我甚至没有找到所有的可能性!

我不确定我是否正在制定我的问题,所以请澄清问题。另外,如果有一些关键词可以帮助我澄清问题,请告诉我!我对Python方法很感兴趣 - 但我对任何MATH方法都持开放态度,以帮助我做到这一点。运行时是一个我希望稍后解决的问题!

谢谢!

编辑1:查看此问题的另一种方法是使用子集求和问题,但需要注意的是:不只是找到所有可能的子集,而是查找所有子集组合,这样,原始列表中的元素数量最多使用,其中每个单独的子集总和为0(或k)。

我的目标是循环遍历所有答案,并根据最终未使用的元素数量对其进行评分,并选择“最佳”子集集。'

编辑2:已接受答案,但已修改为接受用户创建的列表     myList = ['a','b','c','d']

def partitions(myList):
   if not myList:
       yield []
   else:
       for partial_partition in partitions(myList[:-1]):
           for i in range(len(partial_partition)):
               copy_partition = partial_partition[:]
               copy_partition[i] += (myList[-1],)
               yield copy_partition
           yield partial_partition + [(myList[-1],)]

1 个答案:

答案 0 :(得分:2)

递归!生成1..n的所有可能分区,然后使用它们生成1..n + 1的所有可能分区:

def partitions(n):
    if n == 0:
        yield []
    else:
        for partial_partition in partitions(n-1):
            for i in range(len(partial_partition)):
                copy_partition = partial_partition[:]
                copy_partition[i] += (n,)
                yield copy_partition
            yield partial_partition + [(n,)]